在django admin中过滤外键字段

时间:2012-04-16 17:56:00

标签: 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)

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

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)

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

7 个答案:

答案 0 :(得分:29)

使用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)

答案 1 :(得分:25)

我实际上更喜欢在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

答案 2 :(得分:6)

在Django 3中,这很容易:

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

admin.site.register(Company,CompanyAdmin)

这将在屏幕右侧显示一个过滤器,其中包含主题名称列表。

答案 3 :(得分:2)

另一种选择是创建自定义模型表单,其中apollo-client字段的queryset属性将进行微调以满足您的需求。

addTypenameToDocument

此模型表格也可以在django管理区域之外重复使用。

答案 4 :(得分:1)

在这里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)

答案 5 :(得分:0)

我面临着将过滤器添加到父ModelAdmin类(所有其他ModelAdmins继承的)的foreignKey查询集的需求,也就是说,我无法确切知道我需要哪种模型,这是我的解决方案:{{ 1}}

db_field.related_model.objects.filter()

使用的Django版本 2.2.10

答案 6 :(得分:0)

一点无关,但与此类似,因此我将其发布在这里。

我正在寻找一种删除ModelForm外键字段上的 NULL 选择项的方法。我首先认为我可以像在此其他答案中那样过滤查询集,但这没有用。

我发现我可以在get_form方法中过滤pk值为 NULL 的条目:


class CompanyAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        # remove null choice
        form.base_fields["theme"].choices = ((pk, display) for pk, display in form.base_fields["theme"].choices if pk)
        return form