Most once sided discussion I've seen on a developers group in a while ;-), 
but I'll go so far as to suggest an API for the Django Core on this one. I 
mean I have a way to advance myself now, but methinks this need is so 
common that perhaps it's best sitting in the Django Core, albeit with a 
setting as it demands an atomic transaction for create and update views. 
Now this rests on a few premises, namely:


   1. That there is nothing overly broken with my suggestion that I am not 
   seeing as yet (I am the noob after all, and while pretty Python and Django 
   savvy, not diving into the core code very often at all, as little as I've 
   needed to, the very benefit of a cool framewor, keeping us isolated from 
   the dirty details ;-).
   2. That the observations I tabled are valid across all three database 
   backends that Django supports. if it's only  1 (Postgres) or 2 then it 
   shoudl definitely stay an enable-able option and not a default behaviour.

A suggested API is as follows:


   1. Implement a  setting to enable this new behaviour. Looking over 
   exiting settings they can get quite long in name (like  
   DATA_UPLOAD_MAX_NUMBER_FIELDS for example) and so perhaps a name like: 
   RELATIONSHIP_VALIDATORS. I take inspiration from this setting:
   
   AUTH_PASSWORD_VALIDATORS¶ 
   
<https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators> 
   
   Default: [] (Empty list)
   
   The list of validators that are used to check the strength of user’s 
   passwords. See Password validation 
   
<https://docs.djangoproject.com/en/2.1/topics/auth/passwords/#password-validation>
 
   for more details. By default, no validation is performed and all passwords 
   are accepted.
   
   And propose:
   
   TOMANY_RELATIONSHIP_VALIDATORS¶ 
   
<https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators> 
   
   Default: False
   
   A boolean that specifies whether to use atomic transactions on in 
   CreateView and UpdateView POST requests in order to support relationship 
   (OneToMany and ManyToMany) validation in the Model itself. If true, 
   Model.clean() is called as usual, then inside an atomic transaction all 
   submitted forms and formsets are saved and Model.clean_relations() is 
   called. It is important to note that when Model.clean() is saved ToMany 
   relationship (creation or changes) are not visible to Model.clean() but are 
   visible in Model.clean_relations() where they can be validated.
   
   2. 
   
   Implement the code in CreateView.post(...) and UpdateView.post(...) that 
   does this, that is a little savvier than my example in previous mail, but 
   if form.is_valid() pass opens a transaction, saves the form and then for 
   each other form or formset in the POSTed data (not sure off hand how to 
   find those, more learning for me), check each with their .is_valid() and if 
   passing save it, then call Model.clean_relations() (for each model involved 
   (associated with any of the submitted forms or formsets). Of course has to 
   work if the model fails to implement clean_relations(), either by checking 
   it's there first of defining a default implementation which pay just pass. 
   
   3. 
   
   If Model.clean_relations() fails (throws an exception), roll back, if 
   not commit. 
   
It's a rough outline that I think can work. And if it's good (which I await 
feedback on from the silent developer community) then there may even be a 
case for defaulting this setting to True, on new projects anyhow as it may 
be sensible to default to False on any existing site (not introduce a new 
transaction layer without warning on existing projects that upgrade Django 
- where there may well be a transaction system in place already).

I mean if it's a good plan, and it actually gets some feedback to that 
efffect or that help it evolve into a good plan, thus far this looks 
eminently like something I could implement and submit as a PR (Pull 
Request), but I'm just as likely to code mine up and run as I am way way 
busy on other stuff ;-).

Regards,

Bernd.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/239d7900-94a8-4491-b973-50e8731b3957%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to