Python Django管理多对多逆转?

Python Django管理多对多逆转?,python,django,django-models,django-admin,Python,Django,Django Models,Django Admin,问题的答案参考Django文档。其中给出的模型有: 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') 内联管理类包括: cl

问题的答案参考Django文档。其中给出的模型有:

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')
内联管理类包括:

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

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

class GroupAdmin(admin.ModelAdmin):
    inlines = [MembershipInline,]
    exclude = ('members',)
。。。允许从个人页面管理组成员身份,但不能从组页面管理组成员身份。但是,如果管理员只想从组页面管理成员,该怎么办?去掉
exclude
行将允许两个页面管理关系,但Django文档(可能不正确)说“您必须告诉Django的管理员不要显示此小部件”。他们可能的意思是,你“应该”告诉Django的管理员不要显示它——如果你不显示,不会发生什么坏事,但这是多余的

因此,在不更改模型的情况下,是否可以从个人页面而不是组页面中排除成员资格小部件?两种明显的尝试:

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

(第二个使用模型中的
相关名称
)失败,错误为:

'PersonAdmin.exclude' refers to field 'groups' that is missing from the form.

是的,可以将模型更改为将
ManyToManyField
置于
Person
下。但是,由于它是一种对称关系,因此没有逻辑上的理由可以在不更改数据库模式的情况下从个人或组(但不是两者)管理它。Django Admin能否从“组”页面管理组成员资格并将其从“个人”页面中排除?

您没有给出此声明的参考:

Django文档(可能不正确)说“你必须告诉Django的管理员不要显示这个小部件”

因此,我只能参考。它目前说:

Django为定义关系的模型上的多对多字段显示一个管理小部件(在本例中为
Group
)。如果你想使用内联模型来表示多对多关系,你必须告诉Django的管理员不要显示这个小部件,否则你会在你的管理员页面上出现两个小部件来管理这个关系

因此,针对您的正确陈述:

但是,由于它是一种对称关系,因此没有逻辑上的理由可以在不更改数据库模式的情况下从个人或组(但不是两者)管理它

原因是多对多关系必须在某个地方定义;您已选择在组模型上定义它,以便确定默认的管理行为。如果要移动它,则需要进行数据库迁移以实现这一点

另一方面,如果您希望这种记录在案的行为在不改变您对它的使用的情况下有所不同,那么您似乎不会问一个适合StackOverflow的问题。最好在上报告程序的错误,要求更改软件的行为

如果管理员只想管理组中的成员,该怎么办 页面

默认情况下,Django在GroupAdmin中显示Person m2m小部件。您可以正确地使用直通模型来获取内联线,但内联线是一个独立的定义,不受排除的影响。编辑:另一种简单的方式是,您只需在管理员上指定您想要的内联线,而无需在对方的管理员上指定它们

使用内联线:

from core.models import Group, Person

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

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    pass

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

(在Django3.0.3上测试)

当然,我可以重新定义模式并迁移数据库,正如原始问题中所承认的那样。管理界面没有内在的技术原因允许从一端管理对称关系,而不是从另一端管理对称关系-无论关系定义在何处,都应该能够管理成员所属的组或组的成员列表。你只是重申了记录在案的限制,没有提供其存在的理由。Dave正在使用一个贯穿模型来获取内线,当然,他使用哪个方向并不重要。他还提出了两个适当的SO问题!(这就是为什么否决票)“但是如果管理员只想从组页面管理成员怎么办?”“那么在不改变模式的情况下,是否可以从个人页面而不是组页面中排除成员资格小部件?”编辑:实际上是3次-“Django Admin能否从组页面管理组成员身份,并将其从个人页面中排除?”
@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    pass

@admin.register(Group)
class GroupAdmin(admin.ModelAdmin):
    pass
from core.models import Group, Person

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

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    pass

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