【问题标题】:How to relate many-to-many relationship on same page in django-admin?如何在 django-admin 的同一页面上关联多对多关系?
【发布时间】:2023-03-19 00:27:01
【问题描述】:

我是 django 新手,我正在尝试创建一个简单的博客应用程序。

在我的 models.py 中,我为帖子、评论和标签定义了 3 个模型。

models.py

from django.db import models
from django.contrib.auth.models import User


# Create your models here.


class Post(models.Model):
    title = models.CharField(max_length=200)
    body = models.TextField('post body')
    author = models.ForeignKey(User)
    pub_date = models.DateTimeField('date published')
    is_published = models.BooleanField(default=0)
    featured_image = models.CharField(max_length=200)
    created_date = models.DateTimeField('date created')
    updated_date = models.DateTimeField('date Updated')

    def __str__(self):
        return self.title


class Comment(models.Model):
    post = models.ForeignKey(Post)
    user = models.ForeignKey(User)
    comment_text = models.CharField(max_length=200)
    created_date = models.DateTimeField('date created')
    is_published = models.BooleanField(default=0)

    def __str__(self):
        return self.comment_text


class Tags(models.Model):
    title = models.CharField(max_length=200)
    post = models.ManyToManyField(Post)

    def __str__(self):
        return self.title

如您所见,标签和帖子之间存在多对多的关系。

现在在我的博客模块的管理面板中,我希望用户能够在同一页面上添加帖子、cmets 和标签,即(在创建或更新帖子时)。

我可以成功地为帖子和 cmets 做到这一点, 但是我不知道如何附加标签,以便我可以添加新标签并将它们同时附加到帖子中。我也想为标签字段使用select2 插件。

我的admin.py

from django.core import serializers
from django import forms
from django.http import HttpResponse
from django.utils import timezone
from django.contrib import admin
from .models import Post, Comment, Tags


# Register your models here.


class CommentsInline(admin.StackedInline):
    model = Comment
    extra = 1
    fields = ['comment_text']



class TagsInline(forms.ModelForm):
    # I am not sure what should i put in this class 
    model = Tags
    fields = ('title', )
    filter_vertical = ('post', )


class PostAdmin(admin.ModelAdmin):
    fieldsets = [
        ('Content', {'fields': ('title', 'body', 'is_published')}),
        ('Date Information', {'fields': ('pub_date', )})
    ]

    inlines = [CommentsInline, TagsInline]



admin.site.register(Post, PostAdmin)

当尝试运行上面的代码时,我总是看到这个错误:

“blog.Tags”没有“blog.Post”的外键

【问题讨论】:

    标签: python django tags django-admin many-to-many


    【解决方案1】:

    您正在寻找的是嵌套的内联管理。 Django 没有这个开箱即用,但有一个包 - https://github.com/s-block/django-nested-inline。几年前,我将它与 django 1.5 项目一起使用,它完成了您似乎正在寻找的工作。

    针对您的评论,错误消息是正确的。 TagPost 之间没有直接的外键。 Django 使用ManyToManyField 的中间表。查看admin documentation for many-to-many models 看看是否对您有帮助。

    【讨论】:

    • 这对我不起作用。使用了这个包,但我仍然面临同样的问题。我已经更新了答案,请检查
    【解决方案2】:

    为标签模型中的帖子字段提供相关名称。虽然 Django 为反向关系生成了一个默认的相关名称。我想这将是“post_set”。

    post = models.ManyToManyField(Post, related_name="tags")
    

    然后在管理模型中用于 Post 使用

    filter_horizontal = ('tags',)
    

    您将看到一个不错的小部件,用于添加标签以在管理面板中发布。旁边还有一个 + 按钮,可以即时添加新标签。

    不使用 TagsInline 类。

    PS:IMO 你的 Post 模型应该包含带有 ManytoMany 关系的 tags 字段,因为实际上 post 有标签而不是相反。虽然 Django 不区分这两种情况。

    【讨论】:

    • 收到此错误:the value of filter_horizontal[0] must be a ManytoManyField
    • 你应该在 Post 模型中创建标签字段。我猜Django不支持反向ManytoManyField的filter_horizo​​ntal。
    • 添加帖子模型:tags = models.ManyToManyField(Tags, related_name="posts") 并从标签模型中删除帖子字段。
    • 我得到一个错误,相当于:ImproperlyConfigured: 'PostAdmin.filter_horizontal' refers to field 'tags' that is missing from model 'Tags' 如果我在模型中使用字段名,filter_horizo​​ntal 有效(上例中为post)。
    猜你喜欢
    • 2012-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    • 2013-06-17
    相关资源
    最近更新 更多