Thanks Aymeric,

I decided to post this problem on django-developers because I've read this 
ticket:
https://code.djangoproject.com/ticket/24731
Sorry for omitting this information.

Has there been a discussion about this topic already?

Would it be hard to implement an easier solution into django?

I spent a few hours working on this issue, I consider myself fluent with 
django and it's quite shocking I had to put such an amount of effort just 
to validate many2many relationships before they are saved to the database.

IMHO it would be better if we could do one of these two (or even both) 
things:

1. make this process easier in future django versions
2. document the current best practice to solve this problem in current 
django to save people's time

What do people you think?

Here's my solution working with django 1.9:
https://github.com/openwisp/django-netjsonconfig/compare/4082988...master

What do you think of it? Can it be improved in some way?

Federico


On Thursday, December 3, 2015 at 1:43:21 PM UTC+1, Aymeric Augustin wrote:
>
> Hello Frederico,
>
> It appears that you're hitting the problem described in the "Avoid 
> catching exceptions inside atomic!" warning on this page:
>
> https://docs.djangoproject.com/en/1.8/topics/db/transactions/#handling-exceptions-within-postgresql-transactions
>
> To obtain that sort of result, I suppose you must be catching an 
> IntegrityError, re-raising a ValidationError, which Django in turn catches, 
> and then you hit that traceback.
>
> Adding an atomic block inside your try/catch block that catches the 
> IntegrityError will resolve that particular problem — putting that part of 
> the discussion into django-users territory.
>
> If this isn't what happens, please post your code and ask for help on 
> django-users.
>
> -- 
> Aymeric
>
> 2015-12-03 13:28 GMT+01:00 Federico Capoano <federico...@gmail.com 
> <javascript:>>:
>
>> Hi everybody,
>>
>> I am sure it has happened to many of you.
>>
>> Validating m2m BEFORE saving the relationships is very hard and time 
>> consuming.
>>
>> Now this solution:
>> http://schinckel.net/2012/02/06/pre-validating-many-to-many-fields./
>>
>> Proposes to solve it with a ModelForm in the admin.
>> Cool, that works.
>>
>> But, if I want to enforce validation on the model, to avoid corrupted 
>> data, I notice the signal is executed in a transaction block, in which if I 
>> raise a ValidationError I get the following:
>>
>> Traceback (most recent call last):
>>   File 
>> "/var/www/django-netjsonconfig/django_netjsonconfig/tests/test_device.py", 
>> line 106, in test_m2m_validation
>>     d.templates.add(t)
>>   File 
>> "/home/nemesis/.virtualenvs/djnetconfig3/lib/python3.4/site-packages/django/db/models/fields/related_descriptors.py",
>>  
>> line 843, in add
>>     self._add_items(self.source_field_name, self.target_field_name, *objs)
>>   File 
>> "/home/nemesis/.virtualenvs/djnetconfig3/lib/python3.4/site-packages/sortedm2m/fields.py",
>>  
>> line 138, in _add_items
>>     for val in vals:
>>   File 
>> "/home/nemesis/.virtualenvs/djnetconfig3/lib/python3.4/site-packages/django/db/models/query.py",
>>  
>> line 258, in __iter__
>>     self._fetch_all()
>>   File 
>> "/home/nemesis/.virtualenvs/djnetconfig3/lib/python3.4/site-packages/django/db/models/query.py",
>>  
>> line 1074, in _fetch_all
>>     self._result_cache = list(self.iterator())
>>   File 
>> "/home/nemesis/.virtualenvs/djnetconfig3/lib/python3.4/site-packages/django/db/models/query.py",
>>  
>> line 158, in __iter__
>>     for row in compiler.results_iter():
>>   File 
>> "/home/nemesis/.virtualenvs/djnetconfig3/lib/python3.4/site-packages/django/db/models/sql/compiler.py",
>>  
>> line 806, in results_iter
>>     results = self.execute_sql(MULTI)
>>   File 
>> "/home/nemesis/.virtualenvs/djnetconfig3/lib/python3.4/site-packages/django/db/models/sql/compiler.py",
>>  
>> line 852, in execute_sql
>>     cursor.execute(sql, params)
>>   File 
>> "/home/nemesis/.virtualenvs/djnetconfig3/lib/python3.4/site-packages/django/db/backends/utils.py",
>>  
>> line 59, in execute
>>     self.db.validate_no_broken_transaction()
>>   File 
>> "/home/nemesis/.virtualenvs/djnetconfig3/lib/python3.4/site-packages/django/db/backends/base/base.py",
>>  
>> line 429, in validate_no_broken_transaction
>>     "An error occurred in the current transaction. You can't "
>> django.db.transaction.TransactionManagementError: An error occurred in 
>> the current transaction. You can't execute queries until the end of the 
>> 'atomic' block.
>>
>> This is surely an area that needs improvement in django.
>>
>> Why is it so hard?
>>
>> Best regards
>> Federico
>>
>> -- 
>> 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 django-develop...@googlegroups.com <javascript:>.
>> To post to this group, send email to django-d...@googlegroups.com 
>> <javascript:>.
>> Visit this group at http://groups.google.com/group/django-developers.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/django-developers/2e6e82d0-0645-4fd7-8905-d327c99b6352%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/django-developers/2e6e82d0-0645-4fd7-8905-d327c99b6352%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> -- 
> Aymeric.
>

-- 
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 django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/2e618015-aaec-4677-9c3a-972956cbe7ba%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to