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

5
我希望您能在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']

上面会抛出一个错误。

1
你能发布错误信息吗? - Willem Van Onsem
1
我得到了这样的错误信息:“'list_display[1]' 的值不应该是 ManyToManyField”。 - Amal chempazhanthy
1
尝试创建“通过”模型[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]`将此内联表单添加到您的电影管理中。 - Max
2个回答

3
默认情况下,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管理页面中的电影模型。您可以直接从列表显示页面编辑ManyToMany字段。
注意:如果您将在列表中使用多个ManyToManyFields进行编辑,则需要在settings.py中设置DATA_UPLOAD_MAX_NUMBER_FIELDS。

1
对我来说,我需要在 ChangeListinit 方法中添加一个额外的字段。 - Junaid
1
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, 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) - Junaid
在Django2上运行得很好,但在Django3上它显示为空表单,可能出了什么问题? - Ramaz Kadgaev
在 Django3 2023 中,它需要另一个参数。有人知道那是什么吗? - yaozhang

0
据我所知,您想在管理页面中添加模型。
为此,您只需要在Django应用程序的admin.py文件中执行以下操作。

admin.site.register(MovieAdmin)

它是自动可编辑的。希望这可以帮助到您。


我已经在admin.py中添加了如下代码: admin.site.register(Movie, MovieAdmin) - Amal chempazhanthy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接