ORM Query 2

table of Contents

2 + 13 strokes commonly

13-style

Test models

class City(models.Model):
    name= models.CharField(max_length=30)
    # def __str__(self):
    #     return

    class Meta:
        ordering = ("id",)
    # unique_together = ("name","phone")

(1) filter has a filtering function, there is no return None

models.Tb1.objects.filter(条件)

(2) get an error if there is no will, therefore will usually be queried with filter

models.Tb1.objects.all.get(条件,None)    # 字典查询,如果没有就赋值为None,防止报错

(3) exclude (condition), equivalent to not in condition

models.Tb1.objects.exclude(id__in=[11, 22, 33])       # not  in [ 11,33,22]

(4) values ​​(field name): returns [{key: v}, {k, v}], so the value after the first value list dictionaries


 ------------------------------
 <QuerySet [{'name': '上海'}, {'name': '北京'}, {'name': '广州'}, {'name': '深圳'}, {'name': '南宁'}]>
 上海 
 

在views中
        city_list = models.City.objects.filter().values("name")
        print(city_list)
        print([0]["name"])
             return render(request,"en.html",{"city_list":city_list})
 
 
 html 中取值是
        {{ city_list.0.name }}

(5) values_list (* field): returns a list of sets of element Zug formula

views中
        def a(request,):
            city_list = models.City.objects.filter().values_list("name")
            print(city_list)
            return render(request,"en.html",{"city_list":city_list})
------------------------------
结果是: 
        [('上海',), ('北京',), ('广州',), ('深圳',), ('南宁',)]>

html 中取值
        {{ city_list.0.0 }}

(6) order_by (* field): the results are arranged,


对对象进行排序
def a(request,):
    city_list = models.City.objects.filter().order_by("name")
    print(city_list)
    return render(request,"en.html",{"city_list":city_list})
-------------------
结果是:
        <QuerySet [><City: City object (1)>, <City: City object (5)>, <City: City object (3)>>
注意对对象的排序时根据__str__返回值进行排序的,要是在models中设置没有返回值则会报错


def a(request,):
    city_list = models.City.objects.filter().values_list("name")
    city_list1 = city_list.order_by("name")
    print(city_list,city_list1)
    return render(request,"en.html",{"city_list":city_list})
---------------------------------    
结果分别是:
    <QuerySet [('上海',), ('北京',), ('广州',), ('深圳',), ('南宁',)]>
    <QuerySet [('上海',), ('北京',), ('南宁',), ('广州',), ('深圳',)]>


在html中对对象取值方式是
    {{ city_list.name }}    

(7) reverse (): the arrangement has been set for the results of reverse sorting arrangement is provided with a (specified ordering or calling ORDER_BY () method in class Meta model).

在类中设置
        class Person(models.Model):
            class Meta:
                 ordering = ("id",)   #切记后面必须有逗号,即是元祖的形式
                     

类中没有设置,则在查询中设置,
        def a(request,):
            city_list = models.City.objects.filter().order_by("name").reverse()
            print(city_list[0])
            return render(request,"en.html",{"city_list":city_list})

在HTML中取值
        {% for city in city_list %}
             {{ city.name}}
        {% endfor %}

(8) distinct (): eliminate duplicate records (from the returned results if you query across multiple tables , you might get in the calculation of QuerySet reproducible results can now use distinct (), note that only supported by fields go in PostgreSQL. weight.)

pass

(9) count (): Returns the database that match the query (QuerySet) the number of objects.

pass

(10) first (): returns the first record

pass

(11) last () returns the last result

pass

(12) exists (): returns the data to determine whether it is empty, returns True, otherwise False

pass

(13) all (): Query all results

pass

2 type (for foreign key query optimization)

  For one field (OneToOneField) and the foreign key field (a ForeignKey) , you may be used to optimize the select_related QuerySet. From a forward query.

  Django> = 1.7, chained calls select_related equivalent to using a variable-length parameters. Django <1.7, chained calls will lead to failure select_related front, leaving only the last one.

article = models.Article.objects.select_related("category").select_related("articledetail").get(nid=1)

  The use of SQL JOIN statement optimization, be optimized by reducing the number of SQL queries and improve performance.

  For many to many fields (ManyToManyField) and many fields, you may be used prefetch_related () to optimize.

  But for many relationships, and the foreign key table to check the primary key table using SQL statements resolve on a bit unwise, because JOIN resulting table will be very long, it will lead to increased memory footprint and increase the running time of SQL statements. Respectively, each table query, and then deal with their relationship with Python.

b是city的多对多外键
        models.City.objects.prefetch_related("b").filter(id=7).values_list("b__name")


Province是City的外键表        
        models.Province.objects.prefetch_related("City").filter(id=5).values_list("City__name")

A table's primary key can not be repeated exist only in the third table will duplicate id, this will save space, but as the id of the foreign key is a digital presence can be repeated, therefore, foreignkey is many-to the relationship, which in turn is many relationship

The query returns a value type

== prefetch_related mainly query table is too long for even the foreign key table ==

The method has returned queryset

queryset definition:

  It is a collection of objects, and not to the database query, only when we go to the table specific data, he will go to database queries, thus reducing the number of database lookup and improve performance

1 post = Post.objects.all()#返回一个QuerySet对象并赋值给posts


2 available_posts = Posts.filter(status=1)#继续返回一个QuerySet对象并赋值给available_posts


4 print(available_posts)#此时会根据上边的两个条件执行数据查询操作,对应的SQL语句为:SELECT * FROM blog_post where status =1;

The method has returned queryset

  ( 1 )  all()

  ( 2 )  filter()

  ( 3 )  exclude()

  ( 4 )  order_by()

  ( 5 )  reverse()

  ( 6 )  distinct()

Special methods have returned queryset

method return value
alues() Back to list sleeve dictionary
values_list() Ganso set to return a list of

Specific target return

方法|
--|
get() |
first()|
first()|

image

condition

Inequality inquiry

symbol significance Logogram
id__gt more than the greater than
id__lt Less than less than
id__in
filter(id__in=[11, 22, 33]) in [ ]
exclude(id__in=[11, 22, 33]) not in [ ]
id__range=[1, 3] In [1,2,3], find the interval bettwen and
models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值
 
models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
 

 
models.Tb1.objects.filter(id__range=[1, 3])      # id范围是1到3的,等价于SQL的bettwen and
 

Keyword Search

symbol significance Logogram
name__contains="ven" contain
name__icontains="ven" Containing not case sensitive
name__startswith, What begins with
name__istartswith, not case sensitive
name__endswith, To what end i
name__iendswith not case sensitive
models.Tb1.objects.filter(name__contains="ven")  # 获取name字段包含"ven"的
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感

Time of the query

models.Class.objects.filter(first_day__year=2017)

The numbers do not begin with 0 query how years. The disadvantage is that the query is less than 30 days, it does not contain 30

a= "2019-06"
    a,b=a.split("-")
    a = int(a)
    b = int(b)
    start = datetime.date(a, b, 1)
    end = datetime.date(a, b, 30)
    print(type(a),b)
    article_list = models.Article.objects.filter(create_time__gte=start, create_time__lte=end)

1, gt: greater than some time
now = datetime.datetime.now ()
before one day #
Start = now - the datetime.timedelta (= 23 is hours, minutes = 59, = 59 seconds The)
A = yourobject.objects .filter (= youdatetimcolumn__gt start)

2, gte: greater than or equal to a time:
A = yourobject.objects .filter (youdatetimcolumn__gte = Start)

3、lt:小于
a=yourobject.objects .filter(youdatetimcolumn__lt=start)

4、lte:小于等于
a=yourobject.objects .filter(youdatetimcolumn__lte=start)

5、range:查询时间段
start_date = datetime.date(2005, 1, 1)
end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date))

6、year:查询某年
Entry.objects.filter(pub_date__year=2005)

7、month:查询某月
Entry.objects.filter(pub_date__month=12)

8、day:某天
Entry.objects.filter(pub_date__day=3)

9、week_day:星期几
Entry.objects.filter(pub_date__week_day=2)

10、获取今天的日期,日期格式为yyyy-MM-dd

from django.utils.timezone import now, timedelta
date = now().date() + timedelta(days=-1) #昨天
date = now().date() + timedelta(days=0) #今天
date = now().date() + timedelta(days=1) #明天

  注意查询某年某月用大于或者小于结合即可,但是有可能报错,因为月份不一样,一个月多少天也不一样,当设置日期大于本月数,就会抛出异常,查询就需要,多个条件判断,一般和datetime.timedelta(day=1)结合使用

格式是 字段名__条件

跨表查询

**直接通过 外键名__外建表字段名__外键---- 其可以进行多次跨表查询**

models.City.objects.filter(id=6).values_list("b__name")

------------------------
结果如下:
        <QuerySet [('秦时明月汉时关之君临天下',), ('小明hkhkkkhkhk',)]>

跨表计数

models.RegForm.objects.annotate(count=Count("City__id")).values_list("count","name")   #计算个数
models.City.objects.annotate(count=Count("b")).values("b").values("name")

组合和聚合()

主要目的是计算Avg, Sum, Max, Min, Count

聚合和组合用法区别

聚合
        .aggregate(Avg("price"), Max("price"), Min("price"))


组合
        .annotate(avg=Avg("salary").values(dept, "avg")

聚合查询(单表)

其作用是对某一字段进行组合求平均值,像group_by一样,对数字敏感

from django.db.models import Avg, Sum, Max, Min, Count

models.Book.objects.all().aggregate(Avg("price"), Max("price"), Min("price"))
-----------------------------------
结果是:
    {'price__avg': 13.233333, 'price__max': Decimal('19.90'), 'price__min': Decimal('9.90')}

组合查询(相当于group_by)

组合主要目的是计算Avg, Sum, Max, Min, Count

如计算一本书的作者数量

models.Book.objects.annotate(count=Count("author"))


以author字段组合,提取作者字段,再提取作者表中name字段


models.Book.objects.values(author).annotate(count=Count("price"))


annotate(count=Count("price"))前面是什么以以什么为组合依据,直接取值就可以,不用跨表



一本书的作者是,直接用跨表查询即可

print(models.Book.objects.filter(id=6).values_list("author__name"))

F查询(字段对比)

两字段大小筛选

查询评论数大于收藏数的书籍

from django.db.models import F
models.Book.objects.filter(commnet_num__gt=F('keep_num'))

Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。

models.Book.objects.filter(commnet_num__lt=F('keep_num')*2)

修改操作也可以使用F函数,比如将每一本书的价格提高30元

models.Book.objects.all().update(price=F("price")+30)

某字段值后面添加内容

如:把所有书名后面加上(第一版)

from django.db.models.functions import Concat
from django.db.models import Value
models.Book.objects.all().update(title=Concat(F("title"), Value("("), Value("第一版"), Value(")")))

追加)  ( 第一版 )           #value可以是多个,相当于拼接

与或查询

与查询

与条件查询非常简单,条件之间直接用逗号隔开即可

models.City.objects.filter(name__endswith="以",name__contains='钱')

Q中的与或非查询

或查询的格式 :把条件放在Q里面,或条件用| 隔开

models.Book.objects.filter(Q(authors__name="小仙女")|Q(authors__name="小魔女"))

非条件查询格式是: 把条件放在Q里面,或条件用~ 隔开,如查找name属性不包含有小仙女的对象,与条件查询直接用 &(在有Q情况下) 隔开即可,也可以逗号隔开,如查询作者名字是小仙女并且不是2018年出版的书的书名。

models.Book.objects.filter(Q(author__name="小仙女") & ~Q(publish_date__year=2018)).values_list("title")

查询出版年份是2017或2018,书名中带物语的所有书。

models.Book.objects.filter(Q(publish_date__year=2018) | Q(publish_date__year=2017), title__icontains="物语")

事务操作

主要是导入事务模块,把想要执行事务操作语句放在放在其中就可以了,最后用try包起来,防止报错

import os
from django.db import transaction

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

    import datetime
    from app01 import models

    try:
        
        with transaction.atomic():
            new_publisher = models.Publisher.objects.create(name="火星出版社")
            models.Book.objects.create(title="橘子物语", publish_date=datetime.date.today(), publisher_id=10)  # 指定一个不存在的出版社id
    except Exception as e:
        print(str(e))

不常用的查询

自写sql查询

image

image

image

终端打印sql语句

在setting配置一下文件即可

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

脚本导入项目环境

import os

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

    from app01 import models

    books = models.Book.objects.all()
    print(books)

切记要先导入环境,才能导入项目模块

 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
    import django
    django.setup()

select_related和prefetch_related

查询方法大全

def all(self)
    # 获取所有的数据对象

def filter(self, *args, **kwargs)
    # 条件查询
    # 条件可以是:参数,字典,Q

def exclude(self, *args, **kwargs)
    # 条件查询
    # 条件可以是:参数,字典,Q



def annotate(self, *args, **kwargs)
    # 用于实现聚合group by查询

    from django.db.models import Count, Avg, Max, Min, Sum

    v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id'))
    # SELECT u_id, COUNT(ui) AS `uid` FROM UserInfo GROUP BY u_id

    v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id')).filter(uid__gt=1)
    # SELECT u_id, COUNT(ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1

    v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id',distinct=True)).filter(uid__gt=1)
    # SELECT u_id, COUNT( DISTINCT ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1

def distinct(self, *field_names)
    # 用于distinct去重
    models.UserInfo.objects.values('nid').distinct()
    # select distinct nid from userinfo

    注:只有在PostgreSQL中才能使用distinct进行去重

def order_by(self, *field_names)
    # 用于排序
    models.UserInfo.objects.all().order_by('-id','age')

def extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
    # 构造额外的查询条件或者映射,如:子查询

    Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
    Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
    Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])

 def reverse(self):
    # 倒序
    models.UserInfo.objects.all().order_by('-nid').reverse()
    # 注:如果存在order_by,reverse则是倒序,如果多个排序则一一倒序


 def defer(self, *fields):
    models.UserInfo.objects.defer('username','id')
    或
    models.UserInfo.objects.filter(...).defer('username','id')
    #映射中排除某列数据

 def only(self, *fields):
    #仅取某个表中的数据
     models.UserInfo.objects.only('username','id')
     或
     models.UserInfo.objects.filter(...).only('username','id')

 def using(self, alias):
     指定使用的数据库,参数为别名(setting中的设置)


##################################################
# PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS #
##################################################

def raw(self, raw_query, params=None, translations=None, using=None):
    # 执行原生SQL
    models.UserInfo.objects.raw('select * from userinfo')

    # 如果SQL是其他表时,必须将名字设置为当前UserInfo对象的主键列名
    models.UserInfo.objects.raw('select id as nid from 其他表')

    # 为原生SQL设置参数
    models.UserInfo.objects.raw('select id as nid from userinfo where nid>%s', params=[12,])

    # 将获取的到列名转换为指定列名
    name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
    Person.objects.raw('SELECT * FROM some_other_table', translations=name_map)

    # 指定数据库
    models.UserInfo.objects.raw('select * from userinfo', using="default")

    ################### 原生SQL ###################
    from django.db import connection, connections
    cursor = connection.cursor()  # cursor = connections['default'].cursor()
    cursor.execute("""SELECT * from auth_user where id = %s""", [1])
    row = cursor.fetchone() # fetchall()/fetchmany(..)


def values(self, *fields):
    # 获取每行数据为字典格式

def values_list(self, *fields, **kwargs):
    # 获取每行数据为元祖

def dates(self, field_name, kind, order='ASC'):
    # 根据时间进行某一部分进行去重查找并截取指定内容
    # kind只能是:"year"(年), "month"(年-月), "day"(年-月-日)
    # order只能是:"ASC"  "DESC"
    # 并获取转换后的时间
        - year : 年-01-01
        - month: 年-月-01
        - day  : 年-月-日

    models.DatePlus.objects.dates('ctime','day','DESC')

def datetimes(self, field_name, kind, order='ASC', tzinfo=None):
    # 根据时间进行某一部分进行去重查找并截取指定内容,将时间转换为指定时区时间
    # kind只能是 "year", "month", "day", "hour", "minute", "second"
    # order只能是:"ASC"  "DESC"
    # tzinfo时区对象
    models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.UTC)
    models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.timezone('Asia/Shanghai'))

    """
    pip3 install pytz
    import pytz
    pytz.all_timezones
    pytz.timezone(‘Asia/Shanghai’)
    """

def none(self):
    # 空QuerySet对象


####################################
# METHODS THAT DO DATABASE QUERIES #
####################################

def aggregate(self, *args, **kwargs):
   # 聚合函数,获取字典类型聚合结果
   from django.db.models import Count, Avg, Max, Min, Sum
   result = models.UserInfo.objects.aggregate(k=Count('u_id', distinct=True), n=Count('nid'))
   ===> {'k': 3, 'n': 4}

def count(self):
   # 获取个数

def get(self, *args, **kwargs):
   # 获取单个对象

def create(self, **kwargs):
   # 创建对象

def bulk_create(self, objs, batch_size=None):
    # 批量插入
    # batch_size表示一次插入的个数
    objs = [
        models.DDD(name='r11'),
        models.DDD(name='r22')
    ]
    models.DDD.objects.bulk_create(objs, 10)

def get_or_create(self, defaults=None, **kwargs):
    # 如果存在,则获取,否则,创建
    # defaults 指定创建时,其他字段的值
    obj, created = models.UserInfo.objects.get_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 2})

def update_or_create(self, defaults=None, **kwargs):
    # 如果存在,则更新,否则,创建
    # defaults 指定创建时或更新时的其他字段
    obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 1})

def first(self):
   # 获取第一个

def last(self):
   # 获取最后一个

def in_bulk(self, id_list=None):
   # 根据主键ID进行查找
   id_list = [11,21,31]
   models.DDD.objects.in_bulk(id_list)

def delete(self):
   # 删除

def update(self, **kwargs):
    # 更新

def exists(self):
   # 是否有结果

1、gt:大于某个时间
now = datetime.datetime.now()
#前一天
start = now – datetime.timedelta(hours=23, minutes=59, seconds=59)
a=yourobject.objects .filter(youdatetimcolumn__gt=start)

2、gte:大于等于某个时间:
a=yourobject.objects .filter(youdatetimcolumn__gte=start)

3、lt:小于
a=yourobject.objects .filter(youdatetimcolumn__lt=start)

4、lte:小于等于
a=yourobject.objects .filter(youdatetimcolumn__lte=start)

5、range:查询时间段
start_date = datetime.date(2005, 1, 1)
end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date))

6、year:查询某年
Entry.objects.filter(pub_date__year=2005)

7、month:查询某月
Entry.objects.filter(pub_date__month=12)

8、day:某天
Entry.objects.filter(pub_date__day=3)

9、week_day:星期几
Entry.objects.filter(pub_date__week_day=2)

10、获取今天的日期,日期格式为yyyy-MM-dd

from django.utils.timezone import now, timedelta
date = now().date() + timedelta(days=-1) #昨天
date = now().date() + timedelta(days=0) #今天
date = now().date() + timedelta(days=1) #明天

  Note that the query a certain period can be combined with more or less than, but it is possible error, because the month is not the same, not the same number of days a month, when the set date is greater than the number of the month, will throw an exception, we need to query, a plurality of determination conditions, used in a generic and datetime.timedelta (day = 1) binding

The format is the field name __ conditions

Guess you like

Origin www.cnblogs.com/AbnerLc/p/11130159.html