Reputation: 869
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
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
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