python / expert
Snippet
Django ModelForm Sets mit Dynamischer Validierung und Clean Methods
Dieses Snippet demonstriert Django Formset-Validierungsmuster mit Modell-, Feld- und Formset-Ebene Validierung. Die `clean()` Methoden implementieren feldübergreifende Validierung, während die eigenständige `validate_invoice_formset` Funktion Geschäftsregeln über alle Forms hinweg durchsetzt. Diese mehrschichtige Validierungsarchitektur stellt Datenintegrität sicher.
snippet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from django import formsfrom django.core.exceptions import ValidationErrorfrom django.forms import formset_factoryfrom myapp.models import Invoice, InvoiceItemclass InvoiceItemForm(forms.ModelForm):class Meta:model = InvoiceItemfields = ['description', 'quantity', 'unit_price']def clean_quantity(self):quantity = self.cleaned_data['quantity']if quantity <= 0:raise ValidationError('Quantity must be positive')return quantitydef clean(self):super().clean()if self.cleaned_data.get('quantity') and self.cleaned_data.get('unit_price'):total = self.cleaned_data['quantity'] * self.cleaned_data['unit_price']if total > 100000:raise ValidationError('Line total exceeds maximum allowed value')return self.cleaned_dataclass InvoiceForm(forms.ModelForm):class Meta:model = Invoicefields = ['client_name', 'invoice_date', 'notes']def clean_client_name(self):name = self.cleaned_data['client_name']if len(name) < 3:raise ValidationError('Client name too short')return name.upper()def validate_invoice_formset(formset):if formset.total() == 0:raise ValidationError('At least one invoice item required')if formset.total() > 50:raise ValidationError('Maximum 50 items per invoice allowed')totals = []for form in formset.forms:if form.is_valid():qty = form.cleaned_data.get('quantity', 0)price = form.cleaned_data.get('unit_price', 0)totals.append(qty * price)if totals and sum(totals) > 500000:raise ValidationError('Invoice total exceeds credit limit')InvoiceItemFormSet = formset_factory(InvoiceItemForm, extra=1, can_delete=True)InvoiceFormSet = formset_factory(InvoiceForm)
django
Erklärung
1
def clean_quantity(self)
Feld-Ebene Validierung die positive numerische Werte sicherstellt
2
def clean(self)
Feldübergreifende Validierung prüft Geschäftsregeln innerhalb einer Form
3
raise ValidationError(...)
Stoppt Validierungs-Pipeline und assoziiert Fehler mit Feld oder Non-Feld
4
def validate_invoice_formset(formset)
Formset-Ebene Validierung durchsetzt Regeln über alle Forms hinweg
5
formset.total() == 0
Prüft Mindest-Anforderung vor Verarbeitung