from django.db.models import Q,F
from user.models import Users
数据基础操作包括增删查改,常用的过滤属性,Q,F库的使用,外键的反向查询 _set()
class Users(models.Model):
nickname = models.CharField('昵称', max_length=256, null=True)
head_portrait = models.CharField('头像', max_length=256, null=True)
appkey = models.CharField('appkey', max_length=256, null=True)
status = models.CharField('状态', max_length=1, choices=STATUS_CHOICES, default='e')
create_date = models.DateTimeField('创建时间', auto_now_add=True)
update_date = models.DateTimeField('更新时间', auto_now=True)
user = models.ForeignKey('auth.user', verbose_name='用户',
null=True,
on_delete=models.SET_NULL)</code></pre>
class Branch(models.Model):
name = models.CharField('公司名称', max_length=128, null=True)
code = models.CharField('公司编码', max_length=64, null=True)
logo = models.CharField('公司logo', max_length=256, null=True)
invitation_code = models.CharField('邀请码', max_length=128, null=True)
website = models.CharField('公司网站', max_length=128, null=True)
address = models.CharField('地址', max_length=128, null=True)
telephone = models.CharField('公司联系电话', max_length=32, null=True)
introduction = models.TextField('公司简介', null=True)
status = models.CharField('状态', max_length=1, choices=STATUS_CHOICES, default='e')
create_date = models.DateTimeField('创建时间', auto_now_add=True)
update_date = models.DateTimeField('更新时间', auto_now=True)
users = models.ManyToManyField('Users',
verbose_name='昵称',
null=True,
blank=True)</code></pre>
# 增加 save users = Users(
user_account=user_account,
org_id=org
)
users.save()
# 删除 delete
Users.objects.filter(id=user_id).delete()
修改 update
Users.objects.filter(id=user_id).update(
user_account=user_account,
org_id=org
)
# 查询
检索记录 getget获取单个符合条件的记录,没找到或者超过一个都会抛出异常
user = Users.objects.get(id=10)
检索所有的记录 all
user = Users.objects.all()取前5个
Users.objects.all()[:5]取第五个到第十个
Users.objects.all()[5:10]
检索第一条记录 first
user = Users.objects.first()
检索记录条数 count
user = Users.objects.count()
检索记录排序 order_by
user = Users.objects.order_by(‘id’)
user = Users.objects.order_by(‘id’)[0:1]如果需要逆序 在字段前加负号 例 (‘-id’)检索记录特定字段 values
user = Users.objects.values('id', 'nickname').all()返回 指定字段的数据列表这里也可以指定外键字段 使用双下划线指定,返回的键值与values中的参数一致检索记录特定字段 values
user = Users.objects.values_list('id', flat=True).all()返回 id 列表这里也可以指定外键字段 使用双下划线指定,返回的键值与values中的参数一致条件查询exclude和filter相反,查找不符合条件的那些记录条件查询 filter或条件查询
user = Users.objects.filter(Q(nickname='qxt_common') | Q(nickname=u'系统管理员')).all()
非条件查询
user = Users.objects.filter(~Q(nickname='administrator')).all()
user = Users.objects.exclude(nickname='administrator').all()
# 字段名加关键字 例: filter(id __gt='10') # id 大于10 常用的过滤属性
__exact 精确等于 like 'aaa'
__iexact 精确等于 忽略大小写 ilike 'aaa'
__contains 包含 like '%aaa%'
__icontains 包含 忽略大小写 ilike '%aaa%',但是对于sqlite来说,contains的作用效果等同于icontains。
__gt 大于
__gte 大于等于
__lt 小于
__lte 小于等于
__in 存在于一个list范围内
__startswith 以...开头
__istartswith 以...开头 忽略大小写
__endswith 以...结尾
__iendswith 以...结尾,忽略大小写
__range 在...范围内
__year 日期字段的年份
__month 日期字段的月份
__day 日期字段的日
__isnull=True/False
__isnull=True 与 __exact=None的区别# Q或 条件查询
user = Users.objects.filter(Q(nickname='qxt_common') | Q(nickname=u'系统管理员')).all()非条件查询
user = Users.objects.filter(~Q(nickname='administrator')).all()
F例如我们有个统计点击量的字段,每次更新的操作其实就是把字段的值加1.一般我们的做法是把这条记录取出来,把相应字段加+1,然后在save:
articles = Article.objects.filter(id=self.product_id).first()
articles.likes += 1
articles.save()使用 F 改写:
Article.objects.filter(id=self.product_id).update(likes=F('likes') + 1)
外键反向查询一对多外键,多对多外键反向查询方法一致
users = Users.objects.all()
users.branch_set.all() # 反查
branchs = Branch.objects.all()
branchs.users.all() # 正查
# 一对多外键绑定可使用 外键对象,也可以使用外键id直接绑定多对多外键绑定
branchs.users.add(users_obj)
branchs.users.add(users_id)多对多外键删除
branchs.users.remove(users_obj)
branchs.users.remove(users_id)多对多删除所有外键
branchs.users.clear()批量插入
users_list = []
users_list.append(Users(nickname='11'))
users_list.append(Users(nickname='22'))
users_list.append(Users(nickname='33'))
Users.objects.bulk_create(users_list)
distinct 去重
如果需要就一次性取出你所需要的数据
单一动作(如:同一个页面)需要多次连接数据库时,最好一次性取出所有需要的数据,减少连接数据库次数。此类需求推荐使用QuerySet.select_related() 和 prefetch_related()
相反,别取出你不需要的东西,模版templates里往往只需要实体的某几个字段而不是全部,这时QuerySet.values() 和 values_list(),对你有用,它们只取你需要的字段,返回字典dict和列表list类型的东西,在模版里够用即可,这可减少内存损耗,提高性能
同样QuerySet.defer()和only()对提高性能也有很大的帮助,一个实体里可能有不少的字段,有些字段包含很多元数据,比如博客的正文,很多字符组成,Django获取实体时(取出实体过程中会进行一些python类型转换工作),我们可以延迟大量元数据字段的处理,只处理需要的关键字段,这时QuerySet.defer()就派上用场了,在函数里传入需要延时处理的字段即可;而only()和defer()是相反功能
使用QuerySet.count()代替len(queryset),虽然这两个处理得出的结果是一样的,但前者性能优秀很多。同理判断记录存在时,QuerySet.exists()比if queryset实在强得太多了
推荐文章:
https://www.sitepoint.com/doing-more-with-your-django-models/