Skip to main content
 首页 » 编程设计

python之如何在 Django 中使用通用外键引用来引用对象

2025年05月04日32yjmyzz

我有一个包含三个模型的 Django 应用程序,它们使用 ContentTypes 和 Generic 来尝试并允许任务模型使用 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() 将所有任务连接到任何给定的维护,但是对于这个动态外键系统,该功能不起作用。有谁知道实现这种效果的替代函数调用?

请您参考如下方法:

赞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 的字段,对吗?那为什么叫维护呢?我绝对推荐阅读 this section of the docs也是。