覆盖表单窗口小部件和/或表单,用于ManyToMany TabularInline

时间:2018-01-14 17:02:37

标签: django django-admin

假设我有两个模型如下(例如来自Django Docs

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, related_name='groups')

以下管理面板:

from django.contrib import admin

class MembershipInline(admin.TabularInline):
    model = Group.members.through

class PersonAdmin(admin.ModelAdmin):
    inlines = [
        MembershipInline,
    ]

class GroupAdmin(admin.ModelAdmin):
    inlines = [
        MembershipInline,
    ]
    exclude = ('members',)

现在,假设我的数据库多年来建立起来了,我有很多Person个,但很少Group个。因此,对于Group,我可以使用默认小部件,但我需要PersonGroupAdmin的自定义小部件。

我的问题是,在MembershipInline内,如何修改它以便覆盖Person小部件?我知道ForeignKey admin.TabularInline的{​​{3}}可以实现这一点,但如何修改此内容以便为ManyToMany admin.TabularInline提供一些内容?换句话说,如何以一种方式而不是另一种方式修改表单?

1 个答案:

答案 0 :(得分:0)

我首先需要将ManyToMany表分开,

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)
    groups = models.ManyToManyField('Group', through='Membership')

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField('Person', through='Membership')

class Membership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.PROTECT)
    group = models.ForeignKey(Group, on_delete=models.PROTECT)

然后我需要像这样创建内联:

from django.contrib import admin
from .models import *
from .forms import *

class MembershipInline(admin.TabularInline):
    model = Membership
    form = MembershipForm

class PersonAdmin(admin.ModelAdmin):
    inlines = [
        MembershipInline,
    ]

class GroupAdmin(admin.ModelAdmin):
    inlines = [
        MembershipInline,
    ]

然后,在forms.py

from django import forms
from .models import *

class MembershipForm(forms.ModelForm):
    class Meta:
        model = Membership
        exclude = ()
        widgets = {
            'person': whatever_widget_i_want
        }

TabularInline类将负责为我删除不需要的字段小部件。