ForeignKey

多对一关系字段,需要填写两个必要参数:与模型关联的类和on_delete选项。
如果要创建与自身相关的多对一关系对象,可以使用以下方式。
models.ForeignKey("self", on_delete=model.CASCADE)
如果同一个模型类中有两个或以上的多对一关系同时指向另一个相同的模型类,那么需要为其中一个或多个字段添加related_name属性。

from django.db import models


class UserProfile(models.Model):
    name = models.CharField(max_length=10)


class Common(models.Model):
    content = models.CharField(max_length=128)
    user = models.ForeignKey("UserProfile", on_delete=models.CASCADE, related_name="comment_user")
    reply_user = models.ForeignKey("UserProfile", on_delete=models.CASCADE, related_name="reply_to", null=True)

参数说明:

on_delete

  • CASCADE:模拟SQL语言中的ON DELETE CASCADE约束,将定义有外键的模型对象同时删除!
  • PROTECT:阻止上面的删除操作,但是抛出ProtectedError异常。
  • SET_NULL:将外键字段设为null,只有当字段设置了null=True时,方可使用该值。
  • SET_DEFAULT:将外键字段设为默认值。只有当字段设置了default参数时,方可使用。
  • DO_NOTHING:什么也不做。
  • SET():设置为一个传递给SET()的值或者一个回调函数的返回值。注意大小写。
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),
    )

用于关联对象反向引用模型的名称。通常情况下,这个参数我们可以不设置,Django会默认以模型的小写加上_set作为反向关联名。

反向关联查询名。用于从目标模型反向过滤模型对象的名称。

class Tag(models.Model):
    article = models.ForeignKey(
        Article,
        on_delete=models.CASCADE,
        related_name="tags",
        related_query_name="tag",
    )
    name = models.CharField(max_length=255)


Article.objects.filter(tag__name="important")

to_field

默认情况下,外键都是关联到被关联对象的主键上(一般情况为id)。如果指定这个参数,可以关联到关联对象的指定字段上,但该字段必须有unique = True属性,也就是唯一属性。

db_constraint

默认情况下,此参数被设置为True,表示遵循数据库约束,也是大多数情况下的选择。如果设置为False,那么将无法保证数据的完整性和唯一性。在以下场景下,可能需要将其设置为False:

  • 有历史遗留的不合法数据。
  • 正在分割数据表。
    当db_constraint = False,并且正视图访问要一个不存在的关系对象时,将会抛出DoesNotExist异常。

ManyToManyField

多对多关系字段,需要一个位置参数:与模型相关的类,它的用法和ForeignKey基本类似。
在数据库后台,Django实际上是会额外创建一张用于提现多对多关系的中间表。默认表名师使用:多对多关系字段名 + 关联模型名 + 哈希码,也可以使用db_table定义表明。

参考ForeignKey的相同参数。

参考ForeignKey的相同参数。

through 与 through_fields

  • through:默认情况下,Django是用自动生成一个表来管理多对多关系。但是,如果需要手动指定中间表,可以使用through选项来表示要使用中间表的Django模型。
  • through_fields:只有在指定自定义中间模型时使用。
from django.db import models


class Person(models.Model):
    name = models.CharField(max_length=50)


class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through="Membership", through_fields=("group", "person"))


class Membership(models.Model):
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    inviter = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="membership_invites")
    invite_reason = models.CharField(max_length=64)

Membership模型中包含两个关联Person的外键,Django无法确定到底是使用哪个作为和Group关联的对象。所以,在上面的示例中,必须显式的指定through_fields参数,用于定义关系。
through_fields参数接收一个二元元祖(“field1”, “field2”),field1是指向定义有多对多的模型的外键字段的名称,这里是Membership中的group字段,另一个指向目标模型的外键字段的名称,这里是Merbership中的person。
如果中间模型上有多个外键到参与多对多关系的任何模型,则必须指定through_fields。
与普通的多对多不一样,使用自定义中间表的多对多不能使用add(),create(),remove()和set()方法来创建、删除关系。但是clear()方法是有效的,它能清空所有的多对多关系。

OneToOneField

一对一关系字段。从概念上来说,它类似于一个有unique = True属性的外键字段,但是反向关系查询时将直接返回单个对象。如果改字段没有设置related_name的话,Django会默认使用当前模型的小写名称作为其默认值。
如果使用反向查询的对象不存在时,将会抛出DoesNotExists异常。

0条评论

相关推荐

django教程

r

Django 2019-05-20 10:53:53

Celery

celery学习资料

Django 2019-05-25 18:41:55

Django-rest-framework教程

django-rest-framework教程。

Django 2019-07-18 16:33:26

django实用资料

django项目从0到1自己总结的实用的资料,大部分常用的功能这里都有

Django 2019-05-08 18:21:34