不确定构建这种情况的正确方法——希望得到一些反馈。
我有两个模型,Story 和 User,我希望将它们与第三个模型 Tag 相关联(也就是说,Users 和 Stories 可以被标记)。
最初我使用标准外键和 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 本身。
在尝试研究更好的解决方案时,我注意到像我这样的大多数其他示例似乎将我的等价物Tag
和TagLink
表混为一谈。在我的情况下,这似乎不是一个可行的解决方案,但是很多例子认为这是理所当然的,我想知道我是否在这里遗漏了一些东西,或者我的情况是否真的与其他情况不同。
所以:
- 在我的情况下,处理 Tag 和 TagLink 表的正确方法是什么——我将它们分开是否正确?
- 如果是这样,是否有更好的方法来构造查询以获取我的视图和模板中对象的所有标签?
- 鉴于我使用通用关系的唯一原因是 DRY(我没有列出所有用户和标签的故事的情况——我要么列出一个,要么列出另一个)并且只有两种对象可以得到已标记,我最好将一个避免通用关系并使用 if 语句为同一函数调用中的两种对象创建和保存表单的解决方案一起破解?鉴于通用 FK 比常规 FK 灵活得多(例如,我什至还没有开始解决重新做管理员的问题),我开始后悔走这条路了……
谢谢你的时间!!!