在Django管理界面中显示模型对象的相关模型数据

时间:2020-05-05 02:13:42

标签: django django-models

我正在尝试创建一种关系,可以为博客文章分配任意数量的标签,并且可以将标签与任意数量的博客文章相关联。我希望能够使用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)

这有效。我可以登录到管理界面并创建一堆标签对象,然后创建一个发布对象并为其分配任意数量的这些标签。

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

我试图通过在ManyToManyField模型中定义一个Tag来做到这一点,例如:

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

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

我知道如何用一个单独的查询覆盖默认管理员ModelAdmin.change_form_template,以显示分配给帖子的标签。但是我不确定是否有一种方法可以覆盖默认模板。

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

2 个答案:

答案 0 :(得分:1)

多对多字段是用于定义双向关系的字段。但是,您似乎很困惑,因为在Django代码上编写模型时只需要定义一个模型即可。参见ManyToMany relationship doc

这是两个模型。

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)

此代码将在您的数据库中创建三个表。 poststagspost_tagspost_tags是中间表。它具有idpost_idtag_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

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

this doc解释了如何实现可以从标签页面选择帖子的管理员。

答案 1 :(得分:0)

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

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

然后在inlines下的PostAdmin中指定它:

inlines = [TagInline]

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

感谢@YongjinJo让我走上正轨!

相关问题