Wednesday, February 1, 2017

Re: Validating and cleaning related models ...

Melvyn,

Thanks. Alas That was but one example in an apocryphal model set, and I have rather more relationship criteria to test in a more complex nest of models. I'm still drilling down into Django to see what I can uncover. Notably form.instance for the main form and all the related formsets, to see what I can divine from that. But I'm still wondering if there isn't a rather standard solution to the problem of when and where to test for relationships between models I guess, before they are saved, at the point of validation.

It's looking like maybe I have to RY a bit not DRY ;-), as in override and add to some form handling code somewhere. I'm speculating for now. It's a bit of a slog. But form instances may provide some DRY fruit, we'll see, though I have to override post() to access the form in my Generic view, I can't see it in the Model.clean() context and it's too late by the time I'm in form_valid() or form_invalid().

On Thursday, 26 January 2017 02:51:51 UTC+11, Melvyn Sopacua wrote:

 

So, this criterion boils down to:

* the submitted inline album form has one or more albums OR

* the musician exists and has one or more albums

 

Order of the logic may differ pending the common case, but validation will be:

  • Inspect the form count of the album form set (total minus initial). This may require tweaking (added empty rows, duplicates) but you get the gist. Valid if > 0.
  • Get the musician from the database, using whatever uniquely identifies a musician in the main form. Typical queryset.get() in a try block. Valid if exists and album_set is not None.
  • Invalid

 

This can be done in the main view's form_valid().

 

I do not see a solid way to handle this at the model level, because you will have to save at least an album to validate the rule and both the artist and an album in the case of a new artist.

If you define a through model (in case this is a ManyToMany), you can query that model directly instead of having to go through a possibly missing attribute.

The same applies to querying the Album model directly (in case it is a reverse foreign key).

 

However this still means that it will yield no results if either the artist does not exist or no albums for the artist exist. The model has no clear path to validate the incoming data of a related model - that's what the form should do.

 

From a higher level - it is trivial to generate a list of artists without albums, so maybe implementing a procedure that generates that list for content maintainers to process is the better way to guard integrity, since that also covers the case of a DBA "deleting all albums before 1970".

 

--

Melvyn Sopacua

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/064f415a-406a-4742-8841-753baabdecc3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment