I have a 'Pizza' model that can inherit 'Toppings' from another instance of 'Pizza'. When I go to update the Pizza, to add new toppings, I need to prevent the user from selecting the 'self' instance of Pizza in the parent list.
For Example: I create Margarita pizza with cheese and tomato toppings. I then create another Pizza (Pepperoni) and inherit all toppings form the Margarita. I need to stop Pepperoni from appearing in the 'parents' list to stop a circular reference.
models.py
class Topping(models.Model):
name = models.CharField(max_length=100)
class Pizza(models.Model):
name = models.CharField(max_length=100)
parents = models.ManyToManyField("self", symmetrical=False)
toppings = models.ManyToManyField(Topping)
forms.py
class PizzaForm(ModelForm):
toppings = forms.ModelMultipleChoiceField(
queryset=Topping.objects.all(),
widget=forms.CheckboxSelectMultiple,
required=False
)
parents = forms.ModelMultipleChoiceField(
queryset=Pizza.objects.all(),
widget=forms.CheckboxSelectMultiple,
required=False
)
class Meta:
model = Pizza
fields = '__all__'
views.py
class PizzaUpdateView(UpdateView):
model = Pizza
form_class = PizzaForm
I suspect I need to amend the parent queryset in PizzaForm to exclude a PK, but I'm unsure of how to hand this through to the form from my view.
CodePudding user response:
You can override the init
method of PizzaForm
:
class PizzaForm(ModelForm):
toppings = forms.ModelMultipleChoiceField(
queryset=Topping.objects.all(),
widget=forms.CheckboxSelectMultiple,
required=False
)
parents = forms.ModelMultipleChoiceField(
queryset=Pizza.objects.all(),
widget=forms.CheckboxSelectMultiple,
required=False
)
class Meta:
model = Pizza
fields = '__all__'
def __init__(*args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['parents'].queryset = Pizza.objects.exclude(id=self.instance.id)