django - 字符串中的 Django 外键和不带字符串的 Django 外键有什么区别?

标签 django django-models

我不明白为什么人们以两种方式编写外键,这样做的目的是什么?它们是相同还是不同?

我注意到有些人这样写:

author = models.ForeignKey(Author, on_delete=models.CASCADE)

有些人这样写:

author = models.ForeignKey('Author', on_delete=models.CASCADE)

它们之间有什么不同?这样写有什么特殊目的还是两者都是一样的?

最佳答案

What is different between these? is there any special purpose of writing like this or they both are same?

它们都会产生相同的链接,是的。该字符串稍后将被“解析”,最终 ForeignKey 将指向 Author 模型。

但是,如果您的目标模型还需要定义,那么有时使用字符串是进行引用的唯一方法。例如,在循环引用的情况下。

想象一下,您定义的关系如下:

class Author(models.Model):
    name = models.CharField(max_length=128)
    favorite_book = models.ForeignKey(<s>Book</s>, null=True, on_delete=models.SET_NULL)

class Book(models.Model):
    title = models.CharField(max_length=128)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

这里,Book 指的是 AuthorAuthor 指的是 Book。但由于在构造 ForeignKey 时未构造 Book 类,因此这将给出 NameError

在定义了Book之后,我们就不能再定义Author了,因为我们在构造Author之前就引用了Author(并且这个因此将再次产生 NameError)。

但是我们可以在这里使用字符串,以避免循环引用,例如:

class Author(models.Model):
    name = models.CharField(max_length=128)
    favorite_book = models.ForeignKey(<b>'Book'</b>, null=True, on_delete=models.SET_NULL)

class Book(models.Model):
    title = models.CharField(max_length=128)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

通过使用字符串,对于 Python 解释器来说没有问题,因为您不使用尚未定义的标识符,并且 Django 将在加载模型时将字符串替换为对相应模型的引用.

documentation on a ForeignKey [Django-doc] :

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 (...)

如果模型是在另一个应用中定义的,那么您可以使用 app_name.ModelName 引用它。

关于django - 字符串中的 Django 外键和不带字符串的 Django 外键有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56922668/

相关文章:

python - Django 循环模型依赖

python - django 上下文处理器 - 如何从一个函数返回所有内容?

mysql - 使用 Django queryset 查询日期对象存在性能问题

Django drf simple-jwt身份验证“详细信息”: "No active account found with the given credentials"

python - 如何使用 Django 将图像流式传输到浏览器

django - 我如何从 django 中的查询集中获取字符串表示形式

python - Django TypeError __str__ 返回非字符串(类型元组)

具有多对多关系的Django表单不保存

python - 覆盖 django 管理事件日志

Django 性能调优技巧?