[英]Django admin: using inlines through a non-adjacent ManyToMany relationship
考慮以下models.py
,其中一個組包含多個具有零個或多個電話號碼的人。 在這種情況下,共享一個群組的人通常會共享至少一個電話號碼,因此使用了多對多關系。
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管理員中以單一視圖顯示這些模型,如下所示。
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
之間。 對於我的特殊情況,這種方法實際上效果更好。 Group
應該在刪除時級聯到相關的Person
和相關的Phone
。
問題中顯示的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表單窗口小部件僅顯示同一Group
中的Person
。 為此,可以將兩個函數添加到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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.