#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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---