#9865: inline-edited objects with custom PKs cannot be saved
-----------------------------------------------+----------------------------
          Reporter:  bartosak                  |         Owner:  nobody         
      
            Status:  new                       |     Milestone:  post-1.0       
      
         Component:  django.contrib.formtools  |       Version:  SVN            
      
        Resolution:                            |      Keywords:  
inlineformset_factory
             Stage:  Accepted                  |     Has_patch:  0              
      
        Needs_docs:  0                         |   Needs_tests:  0              
      
Needs_better_patch:  0                         |  
-----------------------------------------------+----------------------------
Changes (by kmtracey):

  * owner:  mtredinnick => nobody
  * summary:  "patients_guardian.pesel may not be NULL" when trying to save
              related object after "is_valid()"  on "save()"
              method => inline-edited objects with custom PKs
              cannot be saved
  * stage:  Unreviewed => Accepted

Comment:

 Why did you assign this to Malcolm?  The general custom around here is for
 people assign a ticket to their own self when they want to indicate they
 are working on it so as to avoid having other people duplicate the work.
 We don't in general assign things to other people, as that's rather like
 saying "Here, you must work on this problem for me", which is a bit rude
 given everyone here is a volunteer.

 This ticket could have benefited from a clearer description at the outset.
 You didn't mention, for example, anything about the input you provided on
 the form.  Saying you had provided a pesel value of <whatever> on the form
 for the guardian you were trying to create would have helped make it clear
 that apparently the provided value for pesel was getting lost somewhere
 along the way to or in save().  I realize you said the form passed
 validation, but it still would have been clearer to explicitly state you
 had provided a value for the field that was coming up "null" in the error
 message.

 Also, complete examples are always better.  You didn't provide the
 complete view function, nor the template you are using, so anyone trying
 to recreate has to fill in the blanks.  It may be pretty obvious what
 should be filled in but it is harder to do than simply cut and paste and
 there's always the danger that the person attempting to recreate fills in
 the blanks differently than what you actually have in a way that affects
 the outcome.

 All that said, there does seem to be a problem here.  Specifically if an
 inline-edited model has a custom non-autofield primary key that is not the
 foreign key back to the parent object, then the assigned-in-the-form
 primary key value is not included when saving, leading to the database
 raising an error because the primary key field is neither an Auto field
 nor allowed to be null.

 I'll attach a patch with a testcase demonstrating the problem and a
 potential fix, but this is not code I am very comfortable with so I'd
 prefer someone else look at it before committing.

 The errors from the new test without the code fix are:

 {{{
 ======================================================================
 FAIL: Doctest: modeltests.model_formsets.models.__test__.API_TESTS
 ----------------------------------------------------------------------
 Traceback (most recent call last):
   File "/home/kmt/tmp/django/trunk/django/test/_doctest.py", line 2180, in
 runTest
     raise self.failureException(self.format_failure(new.getvalue()))
 AssertionError: Failed doctest test for
 modeltests.model_formsets.models.__test__.API_TESTS
   File
 "/home/kmt/tmp/django/trunk/tests/modeltests/model_formsets/models.py",
 line unknown line number, in API_TESTS

 ----------------------------------------------------------------------
 File
 "/home/kmt/tmp/django/trunk/tests/modeltests/model_formsets/models.py",
 line ?, in modeltests.model_formsets.models.__test__.API_TESTS
 Failed example:
     formset.save()
 Exception raised:
     Traceback (most recent call last):
       File "/home/kmt/tmp/django/trunk/django/test/_doctest.py", line
 1267, in __run
         compileflags, 1) in test.globs
       File "<doctest
 modeltests.model_formsets.models.__test__.API_TESTS[99]>", line 1, in
 <module>
         formset.save()
       File "/home/kmt/tmp/django/trunk/django/forms/models.py", line 389,
 in save
         return self.save_existing_objects(commit) +
 self.save_new_objects(commit)
       File "/home/kmt/tmp/django/trunk/django/forms/models.py", line 424,
 in save_new_objects
         self.new_objects.append(self.save_new(form, commit=commit))
       File "/home/kmt/tmp/django/trunk/django/forms/models.py", line 487,
 in save_new
         return save_instance(form, new_obj, exclude=[self._pk_field.name],
 commit=commit)
       File "/home/kmt/tmp/django/trunk/django/forms/models.py", line 74,
 in save_instance
         instance.save()
       File "/home/kmt/tmp/django/trunk/django/db/models/base.py", line
 328, in save
         self.save_base(force_insert=force_insert,
 force_update=force_update)
       File "/home/kmt/tmp/django/trunk/django/db/models/base.py", line
 400, in save_base
         result = manager._insert(values, return_id=update_pk)
       File "/home/kmt/tmp/django/trunk/django/db/models/manager.py", line
 138, in _insert
         return insert_query(self.model, values, **kwargs)
       File "/home/kmt/tmp/django/trunk/django/db/models/query.py", line
 894, in insert_query
         return query.execute_sql(return_id)
       File
 "/home/kmt/tmp/django/trunk/django/db/models/sql/subqueries.py", line 309,
 in execute_sql
         cursor = super(InsertQuery, self).execute_sql(None)
       File "/home/kmt/tmp/django/trunk/django/db/models/sql/query.py",
 line 1756, in execute_sql
         cursor.execute(sql, params)
       File
 "/home/kmt/tmp/django/trunk/django/db/backends/sqlite3/base.py", line 170,
 in execute
         return Database.Cursor.execute(self, query, params)
     IntegrityError: model_formsets_bookwithcustompk.my_pk may not be NULL
 ----------------------------------------------------------------------
 File
 "/home/kmt/tmp/django/trunk/tests/modeltests/model_formsets/models.py",
 line ?, in modeltests.model_formsets.models.__test__.API_TESTS
 Failed example:
     for book in author.bookwithcustompk_set.all():
         print book.title
 Expected:
     Les Fleurs du Mal
 Got nothing


 ----------------------------------------------------------------------
 Ran 559 tests in 387.581s

 FAILED (failures=1)
 Destroying test database...

 }}}

 With the code fix, all existing plus the new test pass (tested on sqlite).

-- 
Ticket URL: <http://code.djangoproject.com/ticket/9865#comment:4>
Django <http://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 post to this group, send email to django-updates@googlegroups.com
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to