1.查看orm执行的sql
In [1]: from cost_app.models import AccountInfo
In [2]: print(str(AccountInfo.objects.all().query))
SELECT "account_info"."id", "account_info"."name", "account_info"."platform", "account_info"."company" FROM "account_info"
2.返回查询集的API
可以参考 https://www.cnblogs.com/rangger/p/9801165.html
https://www.jianshu.com/p/380aa2f6c88e
方法名 解释
filter() 过滤查询对象。
exclude() 排除满足条件的对象
annotate() 使用聚合函数
order_by() 对查询集进行排序
reverse() 反向排序
distinct() 对查询集去重
values() 返回包含对象具体值的字典的QuerySet
values_list() 与values()类似,只是返回的是元组而不是字典。
dates() 根据日期获取查询集
datetimes() 根据时间获取查询集
none() 创建空的查询集
all() 获取所有的对象
union() 并集
intersection() 交集
difference() 差集
select_related() 附带查询关联对象
prefetch_related() 预先查询
extra() 附加SQL查询
defer() 不加载指定字段
only() 只加载指定的字段
using() 选择数据库
select_for_update() 锁住选择的对象,直到事务结束。
raw() 接收一个原始的SQL查询
- exclude()
# 下面的示例排除所有pub_date晚于2005-1-3且headline为“Hello” 的记录:
Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')
#下面的示例排除所有pub_date晚于2005-1-3或者headline 为“Hello” 的记录:
Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello')
- values()
# values(fields, *expressions)
# 返回一个包含数据的字典的queryset,而不是模型实例。
# 每个字典表示一个对象,键对应于模型对象的属性名称。
# 下面的例子将values() 与普通的模型对象进行比较:
# 列表中包含的是Blog对象
>>> Blog.objects.filter(name__startswith='Beatles')
<QuerySet [<Blog: Beatles Blog>]>
# 列表中包含的是数据字典
>>> Blog.objects.filter(name__startswith='Beatles').values()
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
>>> Blog.objects.values()
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
>>> Blog.objects.values('id', 'name')
<QuerySet [{'id': 1, 'name': 'Beatles Blog'}]>
#values()方法还有关键字参数**expressions,这些参数将传递给annotate():
>>> from django.db.models.functions import Lower
>>> Blog.objects.values(lower_name=Lower('name'))
<QuerySet [{'lower_name': 'beatles blog'}]>
# 在values()子句中的聚合应用于相同values()子句中的其他参数之前。 如果需要按另一个值分组,请将其添加到较早的values()子句中。 像这样:
>>> from django.db.models import Count
>>> Blog.objects.values('author', entries=Count('entry'))
<QuerySet [{'author': 1, 'entries': 20}, {'author': 1, 'entries': 13}]>
>>> Blog.objects.values('author').annotate(entries=Count('entry'))
<QuerySet [{'author': 1, 'entries': 33}]>
- dates()
>>> Entry.objects.dates('pub_date', 'year')
[datetime.date(2005, 1, 1)]
>>> Entry.objects.dates('pub_date', 'month')
[datetime.date(2005, 2, 1), datetime.date(2005, 3, 1)]
>>> Entry.objects.dates('pub_date', 'day')
[datetime.date(2005, 2, 20), datetime.date(2005, 3, 20)]
>>> Entry.objects.dates('pub_date', 'day', order='DESC')
[datetime.date(2005, 3, 20), datetime.date(2005, 2, 20)]
>>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
[datetime.date(2005, 3, 20)]
- datetimes()
3.不返回查询集的API
增删改查对象
统计记录
聚合
- 自关联
- 一对一自关联
#评论表
class Comment(models.Model):
#评论的内容字段
content=models.CharField(max_length=255)
#评论的发布时间
push_time=models.DateTimeField(auto_now_add=True)
#关联父评论的id,可以为空
pcomment = models.ForeignKey(to='self',null=True)
def __str__(self):
return self.content
- 多对多自关联
class Person(models.Model):
name = models.CharField(max_length=12)
#人和人交朋友
friends = models.ManyToManyField(to='self',symmetrical=False,related_name='ship')
def __str__(self):
return self.name
5.常用的表元数据
class Books(models.Model):
"""图书类"""
name = models.CharField(max_length=20)
price = models.PositiveSmallIntegerField()
word_num = models.PositiveIntegerField()
class Meta:
abstract = True # 当该参数设置为True时表示该模型类是一个基类,提供给其他模型类继承,因此该基类不会在数据库中生成数据表。
app_label = "app_name" # 该参数是用于当我们没有在INSTALLED_APPS中注册app时,需要用该参数来说明该模型类属于哪个app。
db_table = "books" # 该参数表示该模型类在数据库中生成的数据表的表名。
get_latest_by = "price" # 该参数定义了当我们使用latest()和earliest()方法时是通过什么字段来进行排序的。
managed = True # 该参数默认值为True,表示Django将按照既定的规则,管理数据库表的生命周期。如果设置为False,将不会针对当前模型创建和删除数据库表.
ordering = ["price"] # 该参数表示按照什么字段排序,目前表示按照price升序排序,如需要降序,则在字段名前加一个负号["-price"],同时可以添加多个排序选项,如["price", "word_num"]表示先按照price升序排序,然后price相同的再按照word_num升序排序。
permissions = (("allow_update", "允许更新图书"),) # 该参数用于当创建对象时增加额外的权限。它接收一个所有元素都是二元元组的列表或元组,每个元素都是(权限代码, 直观的权限名称)的格式
indexes = [models.Index(fields=['name', 'price']), ] # 该参数表示要在模型上定义的索引列表,用于在数据库中创建索引。
unique_together = (("name", "price"),) # 该参数表示联合唯一约束,参数值可以是一维的,也可以是二维的,我这里是用二维的举例,当前表示该表中不能出现name和price都相同的书籍出现,该参数可以设置多组联合唯一约束,另外,如果约束只有一组的情况下可以用一维表示。
verbose_name = "图书" # 该参数可以设置模型直观的名称,一般我们设置为中文,如果不设置,那么Django会默认使用小写的模型名。
verbose_name_plural = verbose_name # 该参数是verbose_name的复数形式,由于中文没有复数的概念,所以一般verbose_name_plural = verbose_name。
F查询
# Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。 查询书id大于\小于价格的书籍 1 models.Book.objects.filter(id__gt=F("price")) 2 <QuerySet []> 3 4 models.Book.objects.filter(id__lt=F("price")) 5 <QuerySet [<Book: 书一>, <Book: 书二>, <Book: 书三>, <Book: 书四>, <Book: 书五>, <Book: 书六>]> Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。 1 models.Book.objects.filter(id__lt=F("price")/2) 2 <QuerySet [<Book: 书一>, <Book: 书二>, <Book: 书三>, <Book: 书四>, <Book: 书五>]> 修改操作也可以使用F函数,比如将每一本书的价格提高30元 models.Book.objects.all().update(price=F("price")+30) 字符串使用Concat连接 from django.db.models.functions import Concat from django.db.models import Value models.Book.objects.update(title=Concat(F("title"),Value("("),Value("第"),Value(")")))
Q查询
>>> from django.db.models import Q
# Q(...)
>>> Question.objects.filter(Q(question_text__contains='you'))
[<Question: what are you doing>, <Question: what is wrong with you>, <Question: who are you>]
# Q(...), Q(...)
>>> Question.objects.filter(Q(question_text__contains='you'), Q(question_text__contains='what'))
[<Question: what are you doing>, <Question: what is wrong with you>]
# Q(...) & Q(...)
>>> Question.objects.filter(Q(question_text__contains='you') & Q(question_text__contains='what'))
[<Question: what are you doing>, <Question: what is wrong with you>]