Django Admin - Custom cleanup method for a model with a foreignkey field

Consider the following models:

class Arena(models.Model): crowd_capacity = models.PositiveInteger() # more fields here class Section(models.Model): name = models.CharField(max_length=10) crowd_capacity = models.PositiveInteger() arena = models.ForeignKey(Arena, related_name='sections') 

admin.py:

 class SectionInline(admin.StackedInline): model = Section fk_name = 'arena' extra = 1 class ArenaAdmin(admin.ModelAdmin): inlines = [ SectionInline, ] 

I want to add a validation method to verify that the sum of all section.crowd_capacity does not exceed total arena.crowd_capacity.

At first I wanted to write a custom SectionFormSet method with a clean method, but then I did not see how to get arena.crowd_capacity.

I also tried to add a clean method to Arena, it really shows a red validation error, but does not fix this problem. It seems that the Arena cleanup method starts after all sections have been saved, and changing the section.crowd_capacity and we section has caused the problem to have no effect.

The verification method I tried:

 def clean(self): super(Arena, self).clean() capacity = 0 for s in self.sections.all(): capacity += s.crowd_capacity if capacity > self.crowd_capacity: raise ValidationError('The sum of all sections crowd capacity ' 'exceeds arena crowd capacity') 
+4
source share
1 answer

Well, I finally found a way.

To clarify, I want to confirm that the sum of the thickness of all sections does not exceed the total capacity of the arena audience.

Final solution (in admin.py):

 class SectionFormSet(forms.models.BaseInlineFormSet): def clean(self): if any(self.errors): return capacity = 0 for f in self.forms: try: capacity += f.cleaned_data['crowd_capacity'] if capacity > f.cleaned_data['arena'].crowd_capacity: raise ValidationError('The sum of all sections crowd capacity ' 'exceeds arena crowd capacity') except KeyError: # in case of empty form pass class SectionInline(admin.StackedInline): model = Section formset = SectionFormSet class ArenaAdmin(admin.ModelAdmin): inlines = [ SectionInline, ] 

Here it is, no change in the models. It works like a charm :)

+4
source

All Articles