rsp
rsp

Reputation: 869

How to limit choices in a foreign key in Django but always include current value?

I have used this method here: https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.limit_choices_to

to limit choices on a foriegn key in ModelA to entries in ModelB that are makred as "active". This way, I can just deactivate ModelB entries later when they become obsolete. Then, when users go to enter a new ModelA, only the active ModelB entries are shown.

However, if I go to modify an old ModelA, which references an inactive ModelB, the inactive ModelB does not show up in the list. So I cannot save the information (right now, I'm working via the admin). Is there are good way to handle this? It would be nice to show the correct list (all active ModelB) and then just include the currently selected ModelB also, even if it is inactive.

Upvotes: 0

Views: 3790

Answers (2)

Stephen Baden
Stephen Baden

Reputation: 101

This will do what you want. Basically it checks if the form is being rendered on an existing ModelA object and then if it is, it changes the queryset for the ModelB field to filter all active ModelB objects plus the one that is currently assigned.

class ModelAAdminForm(forms.ModelForm):
    class Meta:
        model = ModelA

    def __init__(self, *args, **kwargs):
        super(ModelAAdminForm, self).__init__(*args, **kwargs)
        if self.instance.id and self.instance.modelb:
            q = Q(active=True)| Q(id=self.instance.modelb.id)
            self.fields['modelb'].queryset = ModelB.objects.filter(q)
        else:
            self.fields['modelb'].queryset = ModelB.objects.filter(active=True)


class ModelAAdmin(admin.ModelAdmin):
    form = ModelAAdminForm

Upvotes: 3

Meitham
Meitham

Reputation: 9670

You could use formfield_for_foreignkey from https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_for_foreignkey

You will have to append the current object value to the Q in the kwargs["queryset"].

Upvotes: 2

Related Questions