如何在Django中使用Generic Foreign Key引用引用对象

时间:2013-07-18 12:47:37

标签: python django model generic-foreign-key

我有一个带有三个模型的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)

通常,如果Task只有一个正常的ForeignKey维护,我可以通过Maintenance.task_set.all()获得与任何给定维护连接的所有任务,但是这个动态的外键系统该功能不起作用。有没有人知道实现这种影响的替代函数调用?

1 个答案:

答案 0 :(得分: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上定义,引用在Maintenance和Template上定义。由于您在两个模型上都提供了处理关系的字段,因此无需提供maintenance_set默认值。

编辑:经过进一步检查,我认为部分混乱可能在您的Task.maintenance字段附近。如果我没弄错的话,那就是你要指向Maintenance Template的字段,对吧?那为什么叫maintenance?我绝对建议你阅读this section of the docs