如何在 Django 管理列表显示页面中编辑 ManyToManyField?

Posted

技术标签:

【中文标题】如何在 Django 管理列表显示页面中编辑 ManyToManyField?【英文标题】:How To Edit ManyToManyField In Django Admin list Display Page? 【发布时间】:2018-12-21 20:29:02 【问题描述】:

我想在 Django 管理列表显示页面中添加可编辑的 Many2Many 字段。 模型结构如下,

class Genre(models.Model):
    name = models.CharField(max_length=250, unique=True)


class Movie(models.Model):
    name = models.CharField(max_length=250)
    genre = models.ManyToManyField(Genre)

我试过了,

class MovieAdmin(admin.ModelAdmin):
    list_display = ['name', 'genre']
    list_editable = ['genre']

上面会抛出一个错误。

【问题讨论】:

你能发布错误吗? 我收到类似“'list_display[1]' 的值不能是 ManyToManyField”的错误 尝试创建through 模型https://docs.djangoproject.com/en/2.0/topics/db/models/#extra-fields-on-many-to-many-relationships(如MovieGenreLink,然后在formset = inlineformset_factory(Movie, Movie.genre.through, fields=(genre,)) 的管理员中创建内联表单。然后使用inlines = [MovieGenreLinkInline] 在您的电影管理员中添加此内联表单。 Django admin: ManyToManyField in list_editable?的可能重复 【参考方案1】:

Django 默认不允许在 ModelAdmin 的 list_editable 中添加 ManyToManyField。所以我们需要重写模型管理方法。

在查看您的模型时,您需要按照以下步骤在列表显示页面中获得可编辑的 ManyToManyField。

在apps/forms.py 中,您需要定义哪些ManyToMany 字段需要在列表显示页面中进行编辑。如下,

from django import forms
from app.models import Genre


class MovieChangeListForm(forms.ModelForm):

    # here we only need to define the field we want to be editable
    genre = forms.ModelMultipleChoiceField(queryset=Genre.objects.all(), 
        required=False)

在app/admin.py 中,您需要覆盖模型管理员的方法。如下,

from django.contrib import admin
from django.contrib.admin.views.main import ChangeList
from app.models import Movie
from app.forms import MovieChangeListForm

class MovieChangeList(ChangeList):

    def __init__(self, request, model, list_display,
        list_display_links, list_filter, date_hierarchy,
        search_fields, list_select_related, list_per_page,
        list_max_show_all, list_editable, model_admin):

        super(MovieChangeList, self).__init__(request, model,
            list_display, list_display_links, list_filter,
            date_hierarchy, search_fields, list_select_related,
            list_per_page, list_max_show_all, list_editable, 
            model_admin)

        # these need to be defined here, and not in MovieAdmin
        self.list_display = ['action_checkbox', 'name', 'genre']
        self.list_display_links = ['name']
        self.list_editable = ['genre']


class MovieAdmin(admin.ModelAdmin):

    def get_changelist(self, request, **kwargs):
        return MovieChangeList

    def get_changelist_form(self, request, **kwargs):
        return MovieChangeListForm


admin.site.register(Movie, MovieAdmin)

现在你们都准备好检查更改,运行服务器并检查电影模型的 django admin。您可以直接从列表显示页面编辑 ManyToMany 字段。

注意 : 如果你打算在列表中使用多个 ManyToManyFields 可编辑,则需要在settings.py 中设置 DATA_UPLOAD_MAX_NUMBER_FIELDS。

【讨论】:

对我来说,我必须在 ChangeList 的方法的 init 中添加一个额外的字段 def __init__(self, request, model, list_display, list_display_links, list_filter, date_hierarchy, search_fields, list_select_related, list_per_page, list_max_show_all, list_editable, model_admin, sortable_by): super(ItemChangeList, self).__init__(request , 模型, list_display, list_display_links, list_filter, date_hierarchy, search_fields, list_select_related, list_per_page, list_max_show_all, list_editable, model_admin, sortable_by) 在 Django2 上效果很好,但在 Django3 上却显示为空表单,哪里有问题?【参考方案2】:

据我了解,您想在管理页面中添加模型。

为此,您只需在 django 应用程序中的 admin.py 文件中执行此操作

admin.site.register(MovieAdmin)

它是自动可编辑的。希望这会有所帮助。

【讨论】:

我已经在 admin.py 中添加了 admin.site.register(Movie, MovieAdmin)

以上是关于如何在 Django 管理列表显示页面中编辑 ManyToManyField?的主要内容,如果未能解决你的问题,请参考以下文章

Django 管理站点:添加用户页面如何工作(编辑更多字段)?

如何在 django 管理页面中的每一行的列表页面上放置一个按钮

在 Django 管理对象页面中显示对象 ID(主键)

Summernote 编辑器未在 django 管理页面上显示任何内容

Django将硬编码的href链接添加到管理模型的表单视图页面

如何只允许管理员(或某些用户)在 Django 中编辑页面?