save
关系字段
更新时放入所指向的model实例,如果是多对多要用add方法
可以直接传入id
Entry.objects.filter(blog=b) # Query using object instance
Entry.objects.filter(blog=b.id) # Query using id from instance
Entry.objects.filter(blog=5) # Query using id directly
对于普通的id也能查询,可使用
Entry.objects.filter(blog_id=4)
retrieve
默认使用的Manager是objects
XXModel.objects.all()
链式使用filter和exclude
因为使用了filter和exclude之后的结果也是QuerySet所以可以链式使用
>>> Entry.objects.filter(
... headline__startswith='What'
... ).exclude(
... pub_date__gte=datetime.date.today()
... ).filter(
... pub_date__gte=datetime.date(2005, 1, 30)
... )
使用get获取单一的对象
其他的方法
limit
lookuptype
默认是exact完全匹配
iexact会忽略大小写
contains包含
icontains忽略大小写的包含
startswith endswith istartswith iendswith
如果想过滤关联的内容,可直接使用,反向的也行
关系查询
Blog.objects.filter(entry__authors__name='Lennon')
如果查询时Blog中没有对应的entry,理论上这里的authors为None,应该报错,但是django处理后返回为空,视为未查询到,但是在使用isnull时会出问题
Blog.objects.filter(entry__authors__name__isnull=True)
这样会查询出name为空的和authors为空的,可用
Blog.objects.filter(entry__authors__isnull=False, entry__authors__name__isnull=True)
先确保authors存在,再查询name为空的
关于多值的关系
注意filter和exclude都是在本model上的操作,限制的结果也是本model
Blog.objects.filter(entry__headline__contains='Lennon', entry__pub_date__year=2008)
# 同时满足这两个筛选项
Blog.objects.filter(entry__headline__contains='Lennon').filter(entry__pub_date__year=2008)
# 这里对于本model的查询应该是一致的(例如上面的链式),但是这里使用了两步,那么
# 每次的entry都是该Blog所对应的全部entry而未加限制
行内比较使用F表达式
Entry.objects.filter(n_comments__gt=F('n_pingbacks'))
n_comments__gt=F('n_pingbacks') * 2
rating__lt=F('n_comments') + F('n_pingbacks')
>>> Entry.objects.filter(authors__name=F('blog__name'))
mod_date__gt=F('pub_date') + timedelta(days=3)
PK
pk=14
pk__in=[1, 2]
pk__gt=14
使用%的转置方式
cache
没有完整遍历过的queryset不会缓存
for in
bool转换 list转换
Q
把上述的过滤语句包装为整体,可用& | ~连接来形成 且 或 非 操作
comparing
使用主键
del
可在单独的object上调用delete,也可在queryset上调用delete
copy
设置主键为None再保存,但不会自动处理关系字段
如果涉及到了继承,那么需要将pk id都设置
复制后不会自动设置例如多对多关系的成员,另外一对一的字段应该预先复制好
多行更新
update可以批量修改本model的字段和外键
使用的直接是update语句,所以不会调用save,所以pre_save post_save的信号也不会触发,auto_now的选项也不会遵循,
Related Objects
多对一 ForeignKey
例如一个Entry可用用e.blog来获得Blog,Blog可用b.entry_set.all()来反向获得Entry的列表
在创建ForeignKey时指定了related_name来设置默认的entry_set名字,例如设置为entries,则可用entries.all()来反向获得Entry的列表
默认使用的Manger也是default manager的子类,如果在entry中设置了自定义的manager,可在获取时使用b.entry_set(manager='entries').all(),通过manger参数来指定,这样可调用自定义manger中的方法
对于反向的manager,可用add create remove clear set
多对多 ManyToManyField
定义了ManyToManyField字段的model中使用定义的字段名称,而反向的model中还是使用_set的方式,同样可用related_name来指定
一对一 OneToOneField
注意自动生成的反向名称是model名称,例如Blog使用entry,Entry中使用blog
如何实现的
利用了app registry,引入INSTALLED_APPS中的app和model,