Yuval Adam
Yuval Adam

Reputation: 165322

Limit ForeignKey choices to ManyToMany field selections

Consider this simple Django model:

class Apple(models.Model):
    oranges = models.ManyToManyField(Orange, related_name='apples')
    selected_orange = models.ForeignKey(Orange, related_name='apples_as_selected')

What's the right way to add a limit_choices_to to the ForeignKey field, such that it will limit choices only to those Orange objects that are selected in this instance?

I would want to do this:

selected_orange = models.ForeignKey(Orange, related_name='apples_as_selected',
    limit_choices_to: {'apples__id': lambda: self.id})

But I'm not sure how to get a reference to self in this case.

Upvotes: 2

Views: 1194

Answers (2)

Travis Lloyd
Travis Lloyd

Reputation: 298

If this is specifically for use in the admin, you can customize the default form used when editing an existing object by overriding the get_form method:

class AppleAdmin(admin.ModelAdmin):

    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        if obj:
            form.base_fields['selected_orange'].queryset = Orange.objects.filter(
                apples__id=obj.id
            )
        return form

Upvotes: 1

Yuval Adam
Yuval Adam

Reputation: 165322

One way to solve this is on the ModelForm level, like so:

class AppleForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['selected_orange'].queryset = Orange.objects.filter(apples__id=self.instance.pk)

class AppleAdmin(admin.ModelAdmin):
    form = AppleForm

Would still apreciate a solution to my original question if an elegant one exists.

Upvotes: 1

Related Questions