I have this structure, in Django 2.2:
# models.py
class Child(models.Model):
parent2 = models.ForeignKey(Parent_2, on_delete=models.SET_NULL, null=True)
parent = models.ForeignKey(Parent_1, on_delete=models.CASCADE, null=True)
name = models.CharField('Name')
class Parent_1(models.Model):
cost = models.DecimalField('Cost', max_digits=6, decimal_places=2)
date = models.DateField('Date', default=datetime.date.today)
def __init__(self, *args, **kwargs):
super(Parent_1, self).__init__(*args, **kwargs)
self.__formset_is_valid__ = None
# admin.py
class ChildInline(admin.TabularInline):
model = Child
form = ChildInlineForm
class Parent_1Admin(admin.ModelAdmin):
inlines = [ChildInline]
form = Parent_1AdminForm
# form.py
class ChildInlineForm(forms.ModelForm):
class Meta:
model = Child
def clean(self):
cleaned_data = super(ChildInlineForm, self).clean()
self.instance.__formset_is_valid__ = self.is_valid()
# print(self.instance.__formset_is_valid__)
class Parent_1AdminForm(forms.ModelForm):
extra_field = forms.CharField(widget=forms.Textarea(attrs={'rows': 10}))
extra_field.required = False
class Meta:
model = Parent_1
def clean(self):
cleaned_data = super(Parent_1AdminForm, self).clean()
fields_warning = "Please fill 'extra_field' OR ChildInlineForm"
if self.has_changed():
extra_field_cleaned = cleaned_data.get("extra_field")
if not extra_field_cleaned and (self.instance.__formset_is_valid__ is not True):
self.add_error("extra_field", ValidationError(fields_warning, code='%s-extra_field' % self.prefix))
return cleaned_data
I based the code above on this answer to realize a chained validation between Parent1 form and Child Form. I would like a user can fill the extra_field OR at least a formset to have a valid form, but using the logic above:
- if I fill
extra_fieldfield the form is valid and content is saved - if I fill the child form, parent form is not valid because it already has
self.__formset_is_valid__ = NoneI suppose.
How can I fix my code to achieve my goal?