question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name=“choices”)
The choice model is TabularInline with Question on admin.
When saving this form, want to add validation check that if no. of choices is less than 2, it should raise form Validation error. Ideas on how can I do it?
When a django form is saved, it goes through a default cleaning/sanitation process to assure the saved fields meet the constraints set forth in the models.py file. By default, this function is called ‘clean’ inside a custom form class.
# do your form validation here
If you want to assure the number of choices cannot be less than two, you can write a custom clean function that does the server-side validation for you.
# a clean function for each form field is automatically generated, you just have to override it
choices = self.cleaned_data['choices']
if NUM_OF_CHOICES < 2:
Hope this helps
Tried this already but doesn’t work. Debugger doesn’t come up there.
Maybe because choices is not a field of Question model but rather a related name to Choice model.
Flow which I’ve noticed - Question is created first, then for every choice Choice model is called and a backlinking to Question is created.
If that’s the case, I would suggest looking into how to override the init function of the class you’re using. You should be able to prepopulate the choices of this form field you’re using. From there, once you render this field into your template, you can grab the submitted data through the GET or POST request dictionary and apply update your models accordingly. Not on a computer right now so I can’t easily post examples.
You referenced using the admin in your first post - have you specified your custom form in your ModelAdmin specification? (It might be best if you posted your admin.py file for these two classes.)
Also, when posting code here, please enclose it between lines consisting only of three backtick (`) characters. In other words, you’ll have a line of ```, followed by your code, followed by another line of ```. Make sure you use the backtick - ` and not the apostrophe - ’
model = Choice
model = Question
fields = '__all__'
# do something
inlines = [ChoiceAdmin, ]
form = QuestionForm
This is an interesting issue. The function
clean_<fieldname> isn’t going to do you any good, because the inline formset is not a field in that form. It’s an instance of a model formset. There is also the issue that the base class needs to be saved before the formset can be saved because the formset needs the base model pk before those instances can be saved.
You could try working along these lines -
model = Choice
formset = forms.MyInlineFormSet
number_of_entries = len(self.cleaned_data) - len(self.deleted_forms)
if number_of_entries < 2:
# Do something because not enough entries are present
What I don’t know at this point is whether or not the base class has been saved.
Thanks a lot Ken, that worked !!!