from typing import Any from django import forms from django.core.files.uploadedfile import UploadedFile from django.utils.datastructures import MultiValueDict from .schemas import ( FieldError, FieldErrorList, FormValidation, FormsetValidation, ) from .schema_utils import create_form_instance def validate_form_instance( form_class: type[forms.BaseForm], data: dict, files: MultiValueDict[str, UploadedFile] | None = None, **kwargs: Any, ) -> tuple[forms.BaseForm, FormValidation]: """ Build a form instance and return (form, structured_validation_errors). """ form = create_form_instance(form_class, data=data, files=files, initial=data, **kwargs) # Run validation form.is_valid() validation = FormValidation( errors=[ FieldErrorList( field=field_name, errors=[ FieldError( message=str(e.message) if hasattr(e, 'message') else str(e), code=getattr(e, "code", None), ) for e in field_errors.as_data() ], ) for field_name, field_errors in form.errors.items() ] ) return form, validation def build_formset_validation(formset: forms.BaseFormSet) -> FormsetValidation: """ Turn a Django formset into a FormsetValidation structure. """ return FormsetValidation( general=[str(e) if e else "" for e in formset.non_form_errors()], per_form=[ FormValidation( errors=[ FieldErrorList( field=field_name, errors=[ FieldError( message=str(e.message) if hasattr(e, 'message') else str(e), code=getattr(e, "code", None), ) for e in field_errors.as_data() ], ) for field_name, field_errors in form.errors.items() ] ) for form in formset ], )