Django admin:通过非相邻的多对多关系使用内联

欧文·T·海斯勒

考虑以下情况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。

谢谢!

欧文·T·海斯勒

我通过稍微修改我的要求解决了这个问题。Phone并没有Person只要求和之间的关系,而是添加了另一个多对一的关系:在Phone之间Group对于我的特殊情况,这种方式实际上效果更好;并且 aGroup应该在删除时级联到相关Persons 和相关Phones。

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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Django:通过=与独立模型的多对多关系

来自分类Dev

Django 多对多关系

来自分类Dev

Django中的多对多关系

来自分类Dev

与Django,Python的多对多关系

来自分类Dev

使用Django的Q查询过滤多对多关系

来自分类Dev

使用Django按联接数查询多对多关系

来自分类Dev

如何使用类(Python / Django)过滤多对多关系

来自分类Dev

如何在Django中为多对多关系内联创建对象?

来自分类Dev

Django以多对多关系获取相关对象

来自分类Dev

在Django模型中订购多对多关系

来自分类Dev

Django-setUpTestData与多对多关系

来自分类Dev

Django中与模型继承的多对多关系

来自分类Dev

Django多对一/一对多关系

来自分类Dev

Django Rest Framework实现多对多关系

来自分类Dev

基于多对多关系的Django查询

来自分类Dev

在Django模型中订购多对多关系

来自分类Dev

Django:多对多关系模型定义

来自分类Dev

在Django中注释多对多关系

来自分类Dev

Django模板-显示多对多关系

来自分类Dev

Django 限制多对多关系的选择

来自分类Dev

在 Django 中嵌套多对多关系

来自分类Dev

Django:迭代反向多对多关系

来自分类Dev

添加到多对多关系 django

来自分类Dev

通过Django中的多对多关系返回文件字段以获取Zipview

来自分类Dev

通过 Django 中的 3-way Legacy Junction Table 建立多对多关系

来自分类Dev

多多关系-django

来自分类Dev

在Django Rest中使用中间模型序列化多对多关系

来自分类Dev

Django模型错误:可以使用此多对多关系之前的字段x

来自分类Dev

Django 1.8-中介多对多关系-使用“ ManytoManyField”的结果是什么?