ForeignKey
多对一关系class ForeignKey(othermodel[, **options])
如果关联模型还没有创建,可以使用该模型的名字而不是模型本身来指定
options
limit_chices_to
对关联对象进行过滤,可以是一个字典, 一个 Q 对象, 或者一个可调用的返回字典或者Q对象的对象
related_name
在关联对象上返回这个对象的名称,替代默认的xxx_set
django字段选项related_name和related_query_name.md
related_query_name
在关联对象上进行查询时使用的名称
to_field
指定关联到关联对象的字段名称,默认使用关联对象主键
db_constraint
是否在数据库中为这个外键创建约束的控制。默认值为 True, 而且这几乎一定是你想要的效果。如果设置成 False 对数据集成来说是很糟糕的。即便如此,有一些场景你也许想要这么设置:
on_delete
当此外键引用的对象被删除时,这个字段的行为
swappable
allow_unsaved_instance_assignment
ManyToManyField
多对多关系class ManyToManyField(othermodel[, **options])
related_name
同ForeignKey.related_name
related_query_name
同ForeignKey.related_query_name
limit_choices_to
同ForeignKey.limit_choices_to
symmetrical
只有在关联自身情况下使用,默认是对称的,即如果a是b的好友,默认b也是a的好友,要取消对称设置symmetrical为False
from django.db import models
class Person(models.Model):
friends = models.ManyToManyField("self")
through
djagno默认会自动创建一个表来管理多对多的关系,但是你可以自己建立中介表,然后来手动指定。详细
注意:手动指定中间表后,关联表的add
create
remove
将不可用,但clear
还是可以用的
(http://python.usyiyi.cn/django/ref/models/fields.html#django.db.models.ManyToManyField.through)
through_fields
在中间表中对应的字段名,只能在自定义中间表时使用[详细]
db_table
指定中间表名称
db_constraint
是否为外键创建约束,默认为True
swappable
allow_unsaved_instance_assignment
OneToOneField
一对一关系这个是一个对一关联关系。总体上,这个字段类很像是ForeignKey设置了unique=True, 不同的是它会直接返回关系的另一边的对象。
from django.conf import settings
from django.db import models
class MySpecialUser(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
supervisor = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='supervisor_of')
>>> user = User.objects.get(pk=1)
>>> hasattr(user, 'myspecialuser')
True
>>> hasattr(user, 'supervisor_of')
True
import datetime
from django.db import models
class Blog(models.Model):
...
class Entry(models.Model):
blog = models.ForeignKey(Blog)
published = models.DateTimeField(default=datetime.datetime.now)
...
有以下方法
blog.entry_set
entry.blog
class Topping(models.Model):
# ...
pass
class Pizza(models.Model):
toppings = models.ManyToManyField(Topping)
有以下方法
topping.pizza_set
pizza.toppings
把指定的模型对象添加到关联对象集中。
>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.add(e) # Associates Entry e with Blog b.
不需要调用save()方法
创建一个新的对象,保存对象,并将它添加到关联对象集之中。返回新创建的对象:
>>> b = Blog.objects.get(id=1)
>>> e = b.entry_set.create(
... headline='Hello',
... body_text='Hi',
... pub_date=datetime.date(2005, 1, 1)
... )
# No need to call e.save() at this point -- it's already been saved.
这完全等价于(不过更加简洁于):
>>> b = Blog.objects.get(id=1)
>>> e = Entry(
... blog=b,
... headline='Hello',
... body_text='Hi',
... pub_date=datetime.date(2005, 1, 1)
... )
>>> e.save(force_insert=True)
要注意我们并不需要指定模型中用于定义关系的关键词参数。在上面的例子中,我们并没有传入blog参数给create()。Django会明白新的 Entry对象blog 应该添加到b中。
从关联对象集中移除执行的模型对象(不是删除)
>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.remove(e) # Disassociates Entry e from Blog b.
和add()相似,上面的例子中,e.save()可会执行更新操作。但是,多对多关系上的remove(),会使用QuerySet.delete()删除关系,意思是并不会有任何模型调用save()方法:如果你想在一个关系被删除时执行自定义的代码,请监听m2m_changed信号。
对于ForeignKey对象,这个方法仅在null=True时存在。如果关联的字段不能设置为None (NULL),则这个对象在添加到另一个关联之前不能移除关联。在上面的例子中,从b.entry_set()移除e等价于让e.blog = None,由于blog的ForeignKey没有设置null=True,这个操作是无效的。
对于ForeignKey对象,该方法接受一个bulk参数来控制它如果执行操作。如果为True(默认值),QuerySet.update()会被使用。而如果bulk=False,会在每个单独的模型实例上调用save()方法。这会触发pre_save和post_save,它们会消耗一定的性能。
从关联对象集中移除一切对象(不是删除)
>>> b = Blog.objects.get(id=1)
>>> b.entry_set.clear()
注意这样不会删除对象 —— 只会删除他们之间的关联。
就像 remove() 方法一样,clear()只能在 null=True的ForeignKey上被调用,也可以接受bulk关键词参数。
注意
注意对于所有类型的关联字段,add()、create()、remove()和clear()都会马上更新数据库。换句话说,在关联的任何
端,都不需要再调用save()方法。
同样,如果你再多对多关系中使用了中间模型,一些关联管理的方法会被禁用。
通过赋值一个新的可迭代的对象,关联对象集可以被整体替换掉。
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set = new_list
如果外键关系满足null=True,关联管理器会在添加new_list中的内容之前,首先调用clear()方法来解除关联集中一切已存在对象的关联。否则, new_list中的对象会在已存在的关联的基础上被添加。