Skip to main content
 首页 » 编程设计

python之Django 间接泛型关系

2024年08月30日26pander-it

我一直在尝试为我的应用程序实现一个标记系统,其中每种内容类型只允许使用特定的标记。

我已经尝试在 Tag 模型上设置内容类型,并在 TagAttribution 模型上使用这个值,并且得到了......有趣的结果。

代码:

from django.db import models 
from django.contrib.contenttypes.models import ContentType 
from django.contrib.contenttypes import generic 
from django.contrib.auth.models import User 
 
class Tag(models.Model): 
    value = models.CharField(max_length=32) 
    created_by = models.ForeignKey(User) 
    appliable_to = models.ForeignKey(ContentType) 
 
    def __unicode__(self): 
        return self.value 
 
class TagAttribution(models.Model): 
    tag = models.ForeignKey(Tag) 
    object_id = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey('tag__appliable_to', 'object_id') 
 
    def __unicode__(self): 
        return "%s for id %s of class %s" % (self.tag.value, self.object_id, self.content_object.model)  

外壳测试:

ct = ContentType.objects.get(model='company') 
tag = Tag() 
tag.value = 'value' 
tag.created_by = User.objects.get(id=1) 
tag.appliable_to = ct 
tag.save() 
ta = TagAttribution() 
ta.tag = tag 
ta.object_id = Company.objects.get(id=1).id 
ta.content_object = ta.tag.appliable_to 
ta.save() 
ta 

输出:

<TagAttribution: value for id 13 of class company> 

我不理解这种行为;如果我使用的公司 ID 为 1,为什么它的 ID 为 13?

请您参考如下方法:

错误在这里:

ta.content_object = ta.tag.appliable_to 

这里的ta.content_object不是Company对象而是ContentType。正确的代码应该是:

ta.content_object = Company.objects.get(id=1).id 

此外,您不必直接设置 ta.object_id,它由 GenericForeignKey 字段完成