考虑以下情况models.py
,其中一个 Group 包含多个 Person,每个 Person 都有零个或多个电话号码。在这种特殊情况下,共享一个组的人员通常会共享至少一个电话号码,因此使用多对多关系。
class Group(models.Model):
name = models.CharField(max_length=30)
class Person(models.Model):
group = models.ForeignKey(Group)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
class Phone(models.Model):
persons = models.ManyToManyField(Person)
number = models.CharField(max_length=30)
我想在 Django admin 中以单一视图显示这些模型,如下所示。
class PersonInline(admin.StackedInline):
model = Person
class PhoneInline(admin.StackedInline):
model = Phone # also tried: Phone.persons.through
@admin.register(Group)
class GroupAdmin(admin.ModelAdmin):
inlines = [PersonInline, PhoneInline]
但是,Group 和 Phone 之间没有外键,因此会引发SystemCheckError
(以下之一):
<class 'myapp.admin.PhoneInline'>: (admin.E202) 'myapp.Phone' has no ForeignKey to 'myapp.Group'.
<class 'myapp.admin.PhoneInline'>: (admin.E202) 'myapp.Phone_persons' has no ForeignKey to 'myapp.Group'.
是否可以通过 Person 模型完成这项工作?目标是电话内联显示组中所有人员的电话号码记录(奖励:添加新电话时,人员 SelectMultiple 小部件将只需要显示组中的其他人员)。我宁愿避免修改任何模板。如有必要,可以集成第三方应用程序。我可以使用 Django 1.10 或 1.11。
谢谢!
我通过稍微修改我的要求解决了这个问题。我Phone
并没有Person
只要求和之间的关系,而是添加了另一个多对一的关系:在Phone
和之间Group
。对于我的特殊情况,这种方式实际上效果更好;并且 aGroup
应该在删除时级联到相关Person
s 和相关Phone
s。
admin.py
问题中显示的内容没有变化。本models.py
已在一个多线Phone
类,一个ForeignKey字段:
class Phone(models.Model):
group = models.ForeignKey(Group)
persons = models.ManyToManyField(Person)
number = models.CharField(max_length=30)
上面的“奖励”要求Person
内联中的 ManyToManyField 表单小部件仅显示Person
相同Group
. 为此,可以将两个函数添加到admin.py
:
class PersonInline(admin.StackedInline):
model = Person
class PhoneInline(admin.StackedInline):
model = Phone
def formfield_for_manytomany(self, db_field, request=None, **kwargs):
field = super(PhoneInline,
self).formfield_for_manytomany(db_field, request,
**kwargs)
if db_field.name == 'persons':
if request._obj_ is None:
field.queryset = field.queryset.none()
else:
qs = Person.objects.filter(group=request._obj_.id)
field.queryset = qs
field.initial = qs
return field
@admin.register(Group)
class GroupAdmin(admin.ModelAdmin):
inlines = [PersonInline, PhoneInline]
def get_form(self, request, obj=None, **kwargs):
# Save obj reference for future processing in Phone inline
request._obj_ = obj
return super(GroupAdmin, self).get_form(request, obj, **kwargs)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句