0

我正在尝试创建一种关系,其中可以为博客文章分配任意数量的标签,并且标签可以与任意数量的博客文章相关联。我希望能够使用 Django 管理界面将标签分配给帖子,并将帖子分配给标签。

现在,要创建一篇博文并分配任意数量的标签,这是我的博文模型:

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=100, unique=True, null=True, blank=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    updated_on = models.DateTimeField(auto_now=True)
    tags = models.ManyToManyField("Tags", blank=True)
    content = RichTextUploadingField()
    created_on = models.DateTimeField(auto_now_add=True)

以及定义标签的模型:

class Tag(models.Model):
    name = models.CharField(max_length=20, unique=True)

这行得通。我可以登录到管理界面并创建一堆标签对象,然后创建一个帖子对象并为其分配任意数量的这些标签。

但是,假设我也想做相反的事情。我希望能够登录到管理界面,选择一个标签对象,然后将它与任意数量的帖子对象相关联。

我试图通过ManyToManyFieldTag模型中定义 a 来做到这一点,如下所示:

class Tag(models.Model):
    name = models.CharField(max_length=20, unique=True)
    posts = models.ManyToManyField("Post", blank=True, related_name="posts")

这确实在更改标签页面上显示了一个帖子列表,但我真的只希望它显示与该帖子关联的标签。并且使用管理界面,我希望能够选择其他标签来分配给该帖子。所以我然后尝试使用 a ForeignKey,但这只会让我选择一个帖子。

我知道如何ModelAdmin.change_form_template使用单独的查询覆盖默认管理员以显示分配给帖子的标签。但我不确定是否有办法在不覆盖默认模板的情况下做到这一点。

编辑:我已经修改了这个问题以澄清我想要实现的目标。我现在相信我的模型设置正确。但我(可能错误地)认为我可以将另一个字段添加到第二个模型中,以使其出现在管理界面中。

4

2 回答 2

0

多对多字段是用于定义双向关系的字段。但是,您似乎很困惑,因为在 django 代码上编写时只需要定义一个模型。请参阅多对多关系文档

这里有两个模型。

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    tags = models.ManyToManyField("Tag", related_name='posts')


class Tag(models.Model):
    name = models.CharField(max_length=20, unique=True)

此代码将在您的数据库中创建三个表。posts, tags, 和post_tags. post_tags是中间表。它有id, post_id,tag_id字段。

p1 = Post.objects.create(title='Post 1')
p2 = Post.objects.create(title='Post 2')
p3 = Post.objects.create(title='Post 3')

t1 = Tag.objects.create(title='Tag 1')
t2 = Tag.objects.create(title='Tag 2')
t3 = Tag.objects.create(title='Tag 3')

p1.tags.add(t1, t2)
p1.tags.all()
>>> [Tag 1, Tag 2]

t1.posts.all()
>>> [Post 1]
t2.posts.add(p2, p3)
t2.posts.all()
>>> [Post 1, Post 2, Post 3]

post_tags表项:

id | post_id | tag_id 
---------------------
1  | 1       | 1
2  | 1       | 2
3  | 2       | 1
4  | 3       | 1

多对多字段应仅在一个模型中定义,如果在相反模型中定义,则会创建重复的双向关系。

这个文档解释了如何实现一个可以从标签页面选择帖子的管理员。

于 2020-05-05T03:38:29.403 回答
0

我做的比它需要的要困难得多。为了使用管理界面使用我的问题中的模型为帖子分配标签,我只需要创建一个Inline类:

class TagInline(admin.StackedInline):
    model = Tag.post.through

然后在inlines下面指定它PostAdmin

inlines = [TagInline]

现在,这些关系出现在管理界面的 Posts 对象中。

感谢@YongjinJo 让我走上正轨!

于 2020-05-05T21:40:22.777 回答