4

In Django 1.11, I have 2 models, Foo and Bar:

class Foo(models.Model):
    name = models.CharField()
    extra = models.BooleanField(default=False)

class Bar(models.Model):
    name = models.CharField()
    extra_foo = models.ForeignKey(Foo)

My admin.py looks like this:

class BarInline(admin.StackedInline):
    model = Bar
    fields = ('name', 'extra_foo')

class FooAdmin(admin.ModelAdmin):
    fields('name')
    inlines = [BarInline]

My problem is that the in the Bar inline form, the dropdown for extra_foo shows all of my existing Foos. I want it to only show Foos for which extra is true. How can I modify the admin to restrict the available options in a select box to a subset of the whole?

GluePear
  • 7,244
  • 20
  • 67
  • 120

2 Answers2

4

I guess, you can use render_change_form

class FooAdmin(admin.ModelAdmin):
     def render_change_form(self, request, context, *args, **kwargs):
         context['adminform'].form.fields['extra_foo'].queryset = Foo.objects.filter(extra=True)
         return super(FooAdmin, self).render_change_form(request, context, *args, **kwargs)

admin.site.register(Foo, FooAdmin)

If you want this to be global then have a look at limit_choices_to

extra_foo = models.ForeignKey(Foo, limit_choices_to={'extra': True})

Credit : filter foreignkey field in django admin

Umair Mohammad
  • 4,489
  • 2
  • 20
  • 34
3

You can achieve that by using limit_choices_to. Change this line:

extra_foo = models.ForeignKey(Foo)

to:

extra_foo = models.ForeignKey(Foo, limit_choices_to={'extra': True})

This will limit the choices for extra_foo to Foo objects that have the property extra set to True.

This approach will however limit the choices not only in the admin but also beyond. If you need to adjust only the admin, you need a different approach.

cezar
  • 11,616
  • 6
  • 48
  • 84