问题
full story Only validate admin form if condition is true
I am trying to validate that a form has an answer. In order to validate a form in the admin you need to make a new form and tell the admin.ModelAdmin class to use that form.
Is this correct?
I have created a form but now I can't use my inlines form. If I put it in the admin.ModelAdmin it still shows up and I can still fill that part out but it doesn't appear in the form cleaned_data if though it is in the post data.
How do I use ChoiceInline in QuestionAdminForm?
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 4
#TODO: move?
class QuestionAdminForm(forms.ModelForm):
choices = ChoiceInline
class Meta:
model = Question
def clean(self):
data = self.cleaned_data
#logger.info(data)
choices = self.cleaned_data['choices']
#logger.info(data)
if not self.choices_set.filter(
choice=choices.strip(), is_correct=True).exists():
raise forms.ValidationError("Wrong choice!")
# Always return the cleaned data, whether you have changed it or
# not.
return data
class QuestionAdmin(admin.ModelAdmin):
readonly_fields = ('average', 'last_updated')
#list_display = ["question", "module", "average", "quiz"]
#can't have below because M2M question-> module
#list_display = ["question", "module", "average"]
list_display = ["question", "average"]
list_display_links = ["question"]
list_filter = ['modules__name']
search_fields = ["question", "modules__name", "quiz__name"]
inlines = [ChoiceInline]
actions = [duplicate_questions]
form = QuestionAdminForm
回答1:
This is what I ended up doing based on Django admin validation for inline form which rely on the total of a field between all forms
class CombinedFormSet(BaseInlineFormSet):
# Validate formset data here
def clean(self):
super(CombinedFormSet, self).clean()
for form in self.forms:
if not hasattr(form, 'cleaned_data'):
continue
data = self.cleaned_data
valid = False
for i in data:
if i != {}:
if i['is_correct']:
valid = True
if not valid:
#TODO: translate admin?
raise forms.ValidationError("A Question must have an answer.")
# Always return the cleaned data, whether you have changed it or
# not.
return data
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 4
formset = CombinedFormSet
来源:https://stackoverflow.com/questions/16739387/how-to-use-admin-tabularinline-in-a-modelform