Django管理员有条件内联?

Ton*_*nta 7 django conditional inline django-admin

我试图找出一种方法,只有当Person.is_member为True时才显示以下RelativeInline.

目前的admin.py:

class RelativeInline(admin.TabularInline):
    model = Relative
    fk_name = 'member'

class PersonAdmin(admin.ModelAdmin):
    inlines = [RelativeInline,]
    ordering = ('first_name',)
    list_filter = ('is_member',)
    search_fields = ('first_name', 'last_name',)
    date_hierarchy = 'member_date'
    list_display = ('first_name', 'last_name', 'is_member', 'member_date', 'photo')

admin.site.register(Person, PersonAdmin)
Run Code Online (Sandbox Code Playgroud)

我能找到的唯一提示是我可以覆盖get_formset,但我找不到一个好例子,所以我的微弱尝试不起作用.

这是我失败的尝试:

class RelativeInline(admin.TabularInline):
    model = Relative
    fk_name = 'member'

class PersonAdmin(admin.ModelAdmin):
    ordering = ('first_name',)
    list_filter = ('is_member',)
    search_fields = ('first_name', 'last_name',)
    date_hierarchy = 'member_date'
    list_display = ('first_name', 'last_name', 'is_member', 'member_date', 'photo')

    def get_formset(self, request, obj=None, **kwargs):
        if obj.is_member:
            inlines = [RelativeInline,]
        return super(PersonAdmin, self).get_formset(request, obj, **kwargs)

admin.site.register(Person, PersonAdmin)
Run Code Online (Sandbox Code Playgroud)

此代码不会生成任何错误,但无论Person.is_member是True还是False,都不会显示内联.


更新:朋友建议我尝试更改:

inlines = [RelativeInline,]
Run Code Online (Sandbox Code Playgroud)

至:

self.inlines = [RelativeInline,]
Run Code Online (Sandbox Code Playgroud)

但无济于事.我也尝试过:

PersonAdmin.inlines = [RelativeInline,]
Run Code Online (Sandbox Code Playgroud)

但结果是一样的 - 没有错误,没有内联.

Ton*_*nta 1

我决定改变整个范式并以不同的方式解决我的问题。我决定不为所有具有条件内联的人员设置单一管理员,而是决定:

  1. 覆盖查询集以仅筛选成员并与该模型的管理员保持relativeinline
  2. 创建代理模型并覆盖其查询集以过滤非成员。该模型的管理不包括RelativeInline。

最后,我认为这是一种更干净的方法。现在可以维护会员,并且可以在内联中添加亲属(非会员)。NonMemberAdmin 允许编辑非成员。

模型.py:

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    is_member = models.BooleanField()
    is_active = models.BooleanField(default=True)

    class Meta:
        verbose_name_plural = 'Members'
        ordering = ('first_name', 'last_name')

class PersonProxy(Person):
    class Meta:
        proxy = True
        verbose_name_plural = 'Non-Members'

class Relationship(models.Model):
    name = models.CharField(max_length=50)

class Relative(models.Model):
    member = models.ForeignKey(Person, related_name='relative_member')
    relative = models.ForeignKey(Person, related_name='relative_relative')
    relationship = models.ForeignKey(Relationship)
Run Code Online (Sandbox Code Playgroud)

管理员.py:

class RelativeInline(admin.TabularInline):
    model = Relative
    fk_name = 'member'


class MemberAdmin(admin.ModelAdmin):
    inlines = [RelativeInline,]
    ordering = ('first_name',)
    # list_filter = ('is_member',)
    search_fields = ('first_name', 'last_name',)
    # date_hierarchy = 'member_date'
    list_display = ('first_name', 'last_name', 'member_date')

    def queryset(self, request):
        return (super(MemberAdmin, self).queryset(request)
                .filter(is_member=True, is_active=True))


class NonMemberAdmin(admin.ModelAdmin):
    ordering = ('first_name',)
    search_fields = ('first_name', 'last_name',)
    list_display = ('first_name', 'last_name')

    def queryset(self, request):
        return (super(NonMemberAdmin, self).queryset(request)
                .filter(is_member=False, is_active=True))


admin.site.register(Person, MemberAdmin)
admin.site.register(PersonProxy, NonMemberAdmin)
Run Code Online (Sandbox Code Playgroud)