#12780: Provide a hook for compound form/formset validation in ModelAdmin
-------------------------------+---------------------------------------
Reporter: mrts | Owner: Ramez Issac
Type: New feature | Status: closed
Component: contrib.admin | Version: dev
Severity: Normal | Resolution: wontfix
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+---------------------------------------
Comment (by ldeluigi):
Replying to [comment:13 Natalia Bidart]:
> In order to properly review the PR, I've been investigating solutions
for this ticket, and as I mentioned in
[[https://github.com/django/django/pull/16777|PR #16777]], I think there
is currently enough flexibility in overriding the inline's formset so that
any custom validation involving both the parent form/instance and the
formset themselves can be done there. Following the example referenced in
the ticket description use case, in order to block `Clip` instances to be
approved without a matching `ClipDescription` in the same language, the
customization would look similar to this:
>
> {{{
> # models.py
> from django.db import models
>
>
> LANGS = ['de', 'en', 'es', 'fr', 'it']
>
>
> class Clip(models.Model):
> is_approved = models.BooleanField(default=False)
> language = models.CharField(choices=[(i, i) for i in LANGS],
max_length=2)
>
>
> class ClipDescription(models.Model):
> clip = models.ForeignKey(Clip, on_delete=models.CASCADE)
> text = models.TextField()
> language = models.CharField(choices=[(i, i) for i in LANGS],
max_length=2)
> }}}
>
> {{{
> # admin.py
> from django import forms
> from django.contrib import admin
> from django.core.exceptions import ValidationError
>
> from .models import Clip, ClipDescription
>
>
> class InlineFormset(forms.models.BaseInlineFormSet):
> def clean(self):
> languages = {
> f.cleaned_data['language']
> for f in self.forms
> if 'language' in f.cleaned_data
> # This next line filters out inline objects that did exist
> # but will be deleted if we let this form validate --
> # obviously we don't want to count those if our goal is to
> # enforce a condition of related objects.
> and not f.cleaned_data.get('DELETE', False)
> }
> if (
> self.instance.is_approved
> and self.instance.language not in languages
> ):
> raise ValidationError(
> 'A Clip cannot be approved without a description in the
same language'
> )
>
>
> class ClipDescriptionInline(admin.TabularInline):
> model = ClipDescription
> formset = InlineFormset
>
>
> class ClipAdmin(admin.ModelAdmin):
> inlines = [
> ClipDescriptionInline,
> ]
>
>
> admin.site.register(Clip, ClipAdmin)
> }}}
>
> In summary, I'm proposing to close this issue as invalid/wontfix, but
I'd live to know what others think first.
What if you need to cross-validate two or more different inline formsets
together?
--
Ticket URL: <https://code.djangoproject.com/ticket/12780#comment:17>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/01070189f3f8ba86-6be2b3a9-6dc3-44a3-9be3-078d636c29db-000000%40eu-central-1.amazonses.com.