在django admin中过滤外键字段

Asm*_*ari 23 python django

我有这些模型:

class Entity(models.Model):
       name=models.CharField(max_length=100)

class Theme(models.Model):
   name=models.CharField(max_length=100)
   entity=models.OneToOneField(Entity)

class Company(models.Model):
    name=models.CharField(max_length=100)
    theme=models.OneToOneField(Theme,null=True,blank=True)
Run Code Online (Sandbox Code Playgroud)

我想在管理员中添加公司时过滤主题字段,有些事情是这样的:

class CompanyAdmin(admin.ModelAdmin):
   def queryset(self, request):
      qs = super(CompanyAdmin, self).queryset(request)
      qs.theme.queryset = Theme.objects.filter(name__iexact='company')
      return qs

admin.site.register(Company,CompanyAdmin)
Run Code Online (Sandbox Code Playgroud)

我尝试过很多东西,但没有人工作过!我怎么能这样做?

Ben*_*enH 33

使用render_change_form方法:

class CompanyAdmin(admin.ModelAdmin):
    def render_change_form(self, request, context, *args, **kwargs):
         context['adminform'].form.fields['theme'].queryset = Theme.objects.filter(name__iexact='company')
         return super(CompanyAdmin, self).render_change_form(request, context, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

  • 将最后一行改为`return super(CompanyAdmin, self).render_change_form(request, context, *args, **kwargs)` (2认同)

Mor*_*itz 30

我其实更喜欢get_form这样做:

class CompanyAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        form = super(CompanyAdmin, self).get_form(request, obj, **kwargs)
        form.fields['theme'].queryset = Theme.objects.filter(name__iexact='company')
        return form
Run Code Online (Sandbox Code Playgroud)

  • 在Django 2中,您需要调用form.base_fields而不是form.fields来获取属性。 (5认同)
  • 如果您能详细说明使用“get_form”或“render_change_form”之间的差异,那就太好了。 (4认同)
  • 这种方法比接受的方法更好,因为它允许访问obj. (2认同)
  • 我得到类型对象“...Form”没有属性“字段” (2认同)

sla*_*gan 13

看这里http://books.agiliq.com/projects/django-admin-cookbook/en/latest/filter_fk_dropdown.html

@admin.register(Hero)
class HeroAdmin(admin.ModelAdmin, ExportCsvMixin):
    ...
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "category":
            kwargs["queryset"] = Category.objects.filter(name__in=['God', 'Demi God'])
        return super().formfield_for_foreignkey(db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)

  • 文档链接:https://docs.djangoproject.com/fr/3.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_for_foreignkey (2认同)

G.L*_*ret 6

在 Django 3 中很容易:

class CompanyAdmin(admin.ModelAdmin):
    list_display = ('name','theme')
    list_filter = ('theme__name',)

admin.site.register(Company,CompanyAdmin)
Run Code Online (Sandbox Code Playgroud)

这将在屏幕右侧显示一个带有主题名称列表的过滤器。

  • 这并不能回答问题。从 Django 的最早版本开始,列表过滤器就可以在 ModelAdmins 上使用 (2认同)