Django's ORM (three) F Q queries and queries, transactions, and other

F and Q query


Django provides F () to do such a comparison. Examples F. () Can be referenced in the query field, the value to compare different fields of the same model instance two.


settings.py

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'ORM2',
        'PORT': 3306,
        'HOST': '127.0.0.1',
        'USER': 'root',
        'PASSWORD': 123

    }
}


init.py

import pymysql
pymysql.install_as_MySQLdb()


models.py

from django.db import models


# Create your models here.

class Product(models.Model):
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    maichu = models.IntegerField()
    kucun = models.IntegerField()

    def __str__(self):
        return '对象的名字:%s'%self.name


执行命令创建表

pycharm菜单-tools-run manage.py TASK
$ makemigrations
$ migrate


tests.py

from django.test import TestCase

# Create your tests here.

import os


if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ORM2.settings")
    import django
    django.setup()
    from app01 import models


初始数据


Query F


Queries sell inventory number is greater than the number of goods

from django.db.models import F,Q
    # F查询 给一个字段就能拿到字段的值
    res=models.Product.objects.filter(maichu__gt=F('kucun'))
    print(res)


The prices of all commodities increased 100

models.Product.objects.update(price=F('price')+100)


The name behind plus all commodities are a hot style

from django.db.models.functions import Concat
    from django.db.models import Value
    models.Product.objects.update(name=Concat(F('name'),Value('爆款')))


Q query


<1> for price is 288.88 and the name is the same paragraph clothes burst models of goods (query)

from django.db.models import Q
    from django.db.models import Q

    res = models.Product.objects.filter(Q(price='288.88'),Q(name='衣服爆款'))
    # 这里 第一个Q参数后面必须是传字符串,如果传数字(Q(price=288.88)),无法查询出对象
    print(res)


<2> query name or price 288.88 commodity hot style hat with money (or query)

from django.db.models import Q
res = models.Product.objects.filter(Q(price='288.88') | Q(name='裤子爆款'))  # or
    print(res)
  # <QuerySet [<Product: 对象的名字:衣服爆款>, <Product: 对象的名字:裤子爆款>]>


<3> Check rates than 288.88 and the name of the commodity pants explosion models

混合使用 需要注意的是Q对象必须放在普通的过滤条件前面

res=models.Product.objects.filter(~Q(price='288.88'),Q(name='裤子爆款'))
print(res)


<4> Check rates than 288.88 or the name of the commodity pants explosion models

res=models.Product.objects.filter(Q(name='裤子爆款')|~Q(price='288.88'))
print(res)


Q objects complement

Q的源码

class Q(tree.Node):
    """
    Encapsulates filters as objects that can then be combined logically (using
    `&` and `|`).
    """
    # Connection types
    AND = 'AND'
    OR = 'OR'
    default = AND

    def __init__(self, *args, **kwargs):
        super(Q, self).__init__(children=list(args) + list(kwargs.items()

Q itself is a class instance of an object, all of the children in this condition the incoming properties, and this property is a list of children, the condition written in a manner Xiao Yuan group as a whole, this list passed children, Xiao Yuan the first element is a set of field names, and the second element is the hope that the field name written in line with conditions


例如

Q=q()

q.children.append((‘字段名’,‘条件’))


<1> query name or price 288.88 commodity explosion models of the same paragraph hat

  from django.db.models import F, Q 
  q = Q()
  q.connector = 'or'
  q.children.append(('price', '288.88'))
  q.children.append(('name', '裤子爆款'))
  res = models.Product.objects.filter(q) # # Q对象查询默认也是and
    print(res)


<2> query name or price 288.88 commodity explosion models of clothes

  from django.db.models import F, Q 
  q = Q()
  q.children.append(('price', '288.88'))
  q.children.append(('name', '衣服爆款'))
  res = models.Product.objects.filter(q) # # Q对象查询默认也是and
    print(res)


Affairs

事务的ACID

Atomicity
Consistency
Isolation
Persistence

id=1的商品卖出去一件

    from django.db import transaction
    from django.db.models import F

    with transaction.atomic():
        # 在with代码块儿写你的事务操作
        models.Product.objects.filter(id=1).update(kucun=F('kucun') - 1)
        models.Product.objects.filter(id=1).update(maichu=F('maichu') + 1)


Custom fields ORM


models.py

from django.db import models


class MycharField(models.Field):
    def __init__(self,max_length,*args,**kwargs):
        self.max_length=max_length
        super().__init__(max_length=max_length,*args,**kwargs)

    def db_type(self,connection):
        return 'char(%s)'%self.max_length


class Product(models.Model):
    name = models.CharField(max_length=32) # 都是类实例化的对象
    price = models.DecimalField(max_digits=8, decimal_places=2)
    maichu = models.IntegerField()
    kucun = models.IntegerField()
    info=MycharField(max_length=32,null=True) # 该字段可以为空

    def __str__(self):
        return '对象的名字:%s'%self.name


执行manage.py命令

菜单-tools-Run manager.py Task
$ makemigrations
$ migrate


only与defer

res = models.Product.objects.filter(id=1).values('name').first()
print(res)

这个过程中执行了3条sql语句

(0.000) SELECT @@SQL_AUTO_IS_NULL; args=None
(0.000) SELECT VERSION(); args=None
(0.000) SELECT `app01_product`.`name` FROM `app01_product` WHERE `app01_product`.`id` = 1 LIMIT 21; args=(1,)

only

If you take only the specified field, not to database values, the values ​​directly in the cache of the application

Case 1

res=models.Product.objects.filter(pk=1).only('name').first()
print(res.name)

这个过程执行了3条SQL语句

(0.000) SELECT @@SQL_AUTO_IS_NULL; args=None
(0.000) SELECT VERSION(); args=None
(0.000) SELECT `app01_product`.`id`, `app01_product`.`name` FROM `app01_product` WHERE `app01_product`.`id` = 1 ORDER BY `app01_product`.`id` ASC LIMIT 1; args=(1,)


Case 2

res=models.Product.objects.filter(pk=1).only('name').first()
print(res.price)

这个过程中执行了4条SQL语句,因为price字段不在only里面配置,所以price字段的值是去数据库里面取

(0.000) SELECT @@SQL_AUTO_IS_NULL; args=None
(0.000) SELECT VERSION(); args=None
(0.000) SELECT `app01_product`.`id`, `app01_product`.`name` FROM `app01_product` WHERE `app01_product`.`id` = 1 ORDER BY `app01_product`.`id` ASC LIMIT 1; args=(1,)
(0.000) SELECT `app01_product`.`id`, `app01_product`.`price` FROM `app01_product` WHERE `app01_product`.`id` = 1; args=(1,)


defer

And only the contrary, if taken defer the specified field, it is the value to the database, other fields values ​​directly in the application's cache


Case 1

res=models.Product.objects.filter(pk=1).defer('name').first()
print(res.name)

执行了4条SQL语句

(0.000) SELECT @@SQL_AUTO_IS_NULL; args=None
(0.000) SELECT VERSION(); args=None
(0.000) SELECT `app01_product`.`id`, `app01_product`.`price`, `app01_product`.`maichu`, `app01_product`.`kucun`, `app01_product`.`info` FROM `app01_product` WHERE `app01_product`.`id` = 1 ORDER BY `app01_product`.`id` ASC LIMIT 1; args=(1,)
(0.000) SELECT `app01_product`.`id`, `app01_product`.`name` FROM `app01_product` WHERE `app01_product`.`id` = 1; args=(1,)


Case 2

res=models.Product.objects.filter(pk=1).defer('name').first()
print(res.price)

执行了3条SQL语句

(0.000) SELECT @@SQL_AUTO_IS_NULL; args=None
(0.000) SELECT VERSION(); args=None
(0.001) SELECT `app01_product`.`id`, `app01_product`.`price`, `app01_product`.`maichu`, `app01_product`.`kucun`, `app01_product`.`info` FROM `app01_product` WHERE `app01_product`.`id` = 1 ORDER BY `app01_product`.`id` ASC LIMIT 1; args=(1,)


Field

choices

models.py

from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=32) # 都是类实例化的对象
    price = models.DecimalField(max_digits=8, decimal_places=2)
    maichu = models.IntegerField()
    kucun = models.IntegerField()
    info=MycharField(max_length=32,null=True) # 该字段可以为空

    choices=((1,'男'),(2,'女'),(3,'其他'))
    gender=models.IntegerField(choices=choices,default=2)

    def __str__(self):
        return '对象的名字:%s'%self.name


更新字段操作

菜单-tools-Run manager.py Task
$ makemigrations
$ migrate


tests.py

import os

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ORM2.settings")
    import django

    django.setup()
    from app01 import models  
    res=models.Product.objects.filter(id=1).first()
    print(res.get_gender_display()) # 获取编号对应的中文注释

Guess you like

Origin www.cnblogs.com/cjwnb/p/11802810.html