首先我们来熟悉一下Django Model中外键的定义方式:
class ForeignKey(to, on_delete, **options)
A many-to-one relationship. Requires two positional arguments: the class to which the model is related and the on_delete option.
对于多对一的关系定义,我们需要传递两个位参,一个是要参照的模型,一个是on_delete选项
To create a recursive relationship – an object that has a many-to-one relationship with itself – use models.ForeignKey(‘self’, on_delete=models.CASCADE).
如果想要创建一个递归的关系参照,比如以自己来创建多对一关系,使用models.ForeignKey('self', on_delete=models.CASCADE)
If you need to create a relationship on a model that has not yet been defined, you can use the name of the model, rather than the model object itself:
from django.db import models
class Car(models.Model):
manufacturer = models.ForeignKey(
'Manufacturer',
on_delete=models.CASCADE,
)
# ...
class Manufacturer(models.Model):
# ...
pass
关于Model定义时的on_delete=models.CASCADE参数
When the referenced object is deleted, also delete the objects that have references to it (When you remove a blog post for instance, you might want to delete comments as well). SQL equivalent: CASCADE.
当被参照对象被删除的时候,对应的删除与他有参照关系的对象(例如当你删除一篇博客的时候,所有的评论也会被删除),这个定义与SQL中的CASCADE相等(ON DELETE CASCADE)
The other possible values for on_delete are found in django.db.models:
PROTECT
Prevent deletion of the referenced object by raising ProtectedError, a subclass of django.db.IntegrityError.
SET_NULL
Set the ForeignKey null; this is only possible if null is True.
SET_DEFAULT
Set the ForeignKey to its default value; a default for the ForeignKey must be set.
SET()
Set the ForeignKey to the value passed to SET(), or if a callable is passed in, the result of calling it. In most cases, passing a callable will be necessary to avoid executing queries at the time your models.py is imported:
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
def get_sentinel_user():
return get_user_model().objects.get_or_create(username='deleted')[0]
class MyModel(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET(get_sentinel_user),
)
DO_NOTHING
Take no action. If your database backend enforces referential integrity, this will cause an IntegrityError unless you manually add an SQL ON DELETE constraint to the database field.