当ForeignKey现在是GenericForeignKey时,如何替换models.ManyToManyField

时间:2012-11-04 20:29:54

标签: django django-orm

不确定构建这种情况的正确方法 - 会喜欢一些反馈。

我有两个模型,Story和User,我想与第三个模型Tag相关联(也就是说,用户和故事可以被标记)。

最初我使用标准外键和m2m关系编写了这个:

class Story(models.Model):
    tags = models.ManyToManyField(Place, through='StoryTagLink')

class Tag(models.Model):
    name = models.CharField(max_length=255, unique=True, db_index=True)
    staff_created = models.BooleanField(default=False)
    created_by = models.ForeignKey(User)
    create_date = models.DateTimeField(auto_now=True, auto_now_add=True, editable=False)

class StoryTagLink(models.Model):
    story = models.ForeignKey(Story, db_index=True)
    tag = models.ForeignKey(Tag, db_index=True)

这自然允许我轻松地做以下事情:

tags = story.tags.all()

{% if story.tags.count %}

处理标签的代码变得非常复杂,我认为最好使用通用关系,因此我没有两次编写相同的代码,一次用于Story-Tag处理,另一次用于User-Tag处理。 (我实际上开始两次输入相同的代码,只是找到 - 替换用户的故事。我认为使用通用关系比尝试破解我自己的解决方案更好。)无论如何,现在我有:

class Story(models.Model):
   tags = generic.GenericRelation(TagLink)

class Tag(models.Model):
    (same as before)

class TagLink(models.Model):
    tag = models.ForeignKey(Tag, db_index=True)  # <========== was this right???
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type',
                                               'object_id')

我将tag模型中的TagLink字段设为原始Tag模型的FK,以保留正式的网站标记列表,因为多个对象可以获得相同的标记,并且我需要每个人都有自己独特的ID和元数据。令人烦恼的副作用是现在当我做story.tags.all()时,我得到了<TagLink: TagLink object> s的列表而不是之前的Tag s。

在尝试研究更好的解决方案时,我注意到像我这样的大多数其他示例似乎都混淆了我的TagTagLink表的等价物。在我的案例中,这似乎不是一个可行的解决方案,但是很多例子都认为这是理所当然的,我想知道我是否在这里遗漏了一些东西,或者我的案例是否真的与其他案例不同。

所以:

  1. 在我的案例中处理Tag和TagLink表的正确方法是什么 - 我是否正确将它们分开?
  2. 如果是这样,是否有更好的方法来构建查询以获取视图和模板中对象的所有标记?
  3. 鉴于我使用通用关系的唯一原因是DRY(我没有列出标签的所有用户和故事的情况 - 我要么列出一个或另一个)并且只有两种类型被标记的对象,我会更好地将一个避免通用关系的解决方案混合在一起,并使用if语句在同一个函数调用中为这两种对象创建和保存表单吗?鉴于普通FK的通用FK比普通FK少得多(我甚至没有开始重新做管理员,对于前者),我开始后悔走这条路了......
  4. 谢谢你的时间!!!

0 个答案:

没有答案