【问题标题】:how to reference objects with Generic ForeignKey reference in Django如何在 Django 中使用通用外键引用来引用对象
【发布时间】:2013-07-17 10:17:27
【问题描述】:

我有一个 Django 应用程序,其中包含三个模型,它们使用 ContentTypes 和 Generic 来尝试并允许 Task 模型使用 How to use dynamic foreignkey in Django? 作为指南来使用其他两个模型中的任何一个的 ForeignKey(尽管我承认我有不知道这种方法发生了什么)。

class Task(models.Model):
    date = models.DateTimeField(null = True)
    day = models.IntegerField(null = True)
    task = models.CharField(max_length = 100, null = False)
    owner = models.CharField(max_length = 25, null = True)
    notes = models.CharField(max_length = 250, null = True)
    isDone = models.BooleanField(default = False, null = False)

    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    maintenance = generic.GenericForeignKey('content_type', 'object_id')

class Maintenance(models.Model):
    startMonth = models.CharField(max_length = 15, null = False)
    startYear = models.IntegerField(null = False)
    location = models.CharField(max_length = 20, null = False)
    mode = models.CharField(max_length = 20, null = False)

    taskRef = generic.GenericRelation(Task)

class Template(models.Model):
    name = models.CharField(max_length = 25, null = False)
    location = models.CharField(max_length = 20, null = False)
    mode = models.CharField(max_length = 20, null = False)

    taskRef = generic.GenericRelation(Task)

通常,如果任务只有一个正常的外键来维护,我可以使用 Maintenance.task_set.all() 将所有任务连接到任何给定的维护,但是使用这个动态外键系统,该功能不起作用。有谁知道实现这种效果的替代函数调用?

【问题讨论】:

  • Maintenance.taskRef.all() 工作?
  • 哦,这行得通,就像我说的,我真的不明白这是怎么回事。
  • 这是有效的,因为您为模型添加了“反向”通用关系
  • 我不知道你为什么对它的工作感到惊讶
  • 这并不是说我对它的工作感到惊讶,我只是不完全理解我放入的所有部分都在做什么,这使得我很难理解我想要做什么。

标签: python django model generic-foreign-key


【解决方案1】:

就像user710907 says,Maintenance.taskRef.all() 应该可以解决问题。当您指定 ForeignKey 关系时,您可以设置用于反向关系的“related_name”参数。如果您不指定,则默认为“model_name_set”。

class Foo(models.Model):
    ...

class Bar(models.Model):
    ...
    foo = models.ForeignKey(Foo, related_name="related_bars")

现在您可以从一侧通过bar.foo 或从另一侧通过foo.related_bars 访问该关系。如果不指定,后一个参数将默认为foo.bar_set

在您的示例中,您从双方定义关系; FK 在 Task 上定义,reference 在 Maintenance 和 Template 上定义。由于您在处理关系的两个模型上都提供了字段,因此无需提供 maintenance_set 默认值。

编辑:经过进一步检查,我认为部分混淆可能与您的 Task.maintenance 字段有关。如果我没记错的话,这就是您要指向Maintenance Template 的字段,对吗?那么为什么叫maintenance呢?我也绝对推荐阅读this section of the docs

【讨论】:

  • 当时它被设置为维护,因为我正在将模板模型集成到我的应用程序中,并且我程序中的所有引用都已经使用了 task.maintenance,我不想改变他们都在当时。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
  • 2013-02-23
  • 1970-01-01
  • 2016-11-06
相关资源
最近更新 更多