45

我有这些模型:

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)

我想在管理员中theme添加时过滤字段Company,如下所示:

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)

我尝试了很多东西,但没有任何效果!我怎样才能做到这一点?

4

7 回答 7

57

使用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)
于 2012-04-16T22:17:29.110 回答
47

我实际上更喜欢get_form这样做:

姜戈 < 2:

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

class CompanyAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        form = super(CompanyAdmin, self).get_form(request, obj, **kwargs)
        form.base_fields['theme'].queryset = Theme.objects.filter(name__iexact='company')
        return form
于 2015-10-01T07:43:17.443 回答
16

看这里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)
于 2018-12-06T14:23:55.897 回答
6

在 Django 3 中很容易:

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

admin.site.register(Company,CompanyAdmin)

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

于 2020-04-13T12:43:40.690 回答
3

另一种选择是创建一个自定义模型表单,其中theme字段的查询集属性将被微调以满足您的需求。

class CompanyForm(ModelForm):
    class Meta:
        model = CompanyForm
        fields = __all__ # or a tuple of fields

    def __init__(self, *args, **kwargs):
        super(CompanyForm, self).__init__(*args, **kwargs)
        if self.instance: # Editing and existing instance
            self.fields['theme'].queryset = Theme.objects.filter(name__iexact='company')

这个模型表单也可以在 django 管理区域之外重用。

于 2017-02-23T15:56:13.500 回答
0

我面临需要将过滤器添加到父 ModelAdmin 类(所有其他 ModelAdmins 继承自)的 foreignKey 查询集中,也就是说,我无法确切知道我需要哪个模型,这是我的解决方案:db_field.related_model.objects.filter()

class TSModelAdmin(admin.ModelAdmin):
   exclude = ('site',)
    ...

      def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.related_model:
            kwargs["queryset"] = 
            db_field.related_model.objects.filter(site=request.user.user_profile.site)
        return super().formfield_for_foreignkey(db_field, request, **kwargs)

使用 django 版本2.2.10

于 2020-02-14T08:34:32.830 回答
0

有点无关,但与此类似,因此我将在此处发布。

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

我发现我可以在方法中像这样过滤 pk 值为NULLget_form的条目:


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
于 2020-11-03T15:48:01.120 回答