Skip to content

Commit

Permalink
Fixed #9649 -- Better error handling in model creation.
Browse files Browse the repository at this point in the history
Previously, you could explicitly assign None to a non-null ForeignKey
(or other) field when creating the model (Child(parent=None), etc). We
now throw an exception when you do that, which matches the behaviour
when you assign None to the attribute after creation.

Thanks to ales.zoulek@gmail.com and ondrej.kohout@gmail.com for some
analysis of this problem.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9983 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
malcolmt committed Mar 6, 2009
1 parent b5d4a8a commit 53da1e4
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 7 deletions.
13 changes: 7 additions & 6 deletions django/db/models/base.py
Expand Up @@ -224,12 +224,13 @@ def __init__(self, *args, **kwargs):
# keywords, or default.

for field in fields_iter:
rel_obj = None
is_related_object = False
if kwargs:
if isinstance(field.rel, ManyToOneRel):
try:
# Assume object instance was passed in.
rel_obj = kwargs.pop(field.name)
is_related_object = True
except KeyError:
try:
# Object instance wasn't passed in -- must be an ID.
Expand All @@ -245,11 +246,11 @@ def __init__(self, *args, **kwargs):
val = kwargs.pop(field.attname, field.get_default())
else:
val = field.get_default()
# If we got passed a related instance, set it using the field.name
# instead of field.attname (e.g. "user" instead of "user_id") so
# that the object gets properly cached (and type checked) by the
# RelatedObjectDescriptor.
if rel_obj:
if is_related_object:
# If we are passed a related instance, set it using the
# field.name instead of field.attname (e.g. "user" instead of
# "user_id") so that the object gets properly cached (and type
# checked) by the RelatedObjectDescriptor.
setattr(self, field.name, rel_obj)
else:
setattr(self, field.attname, val)
Expand Down
13 changes: 12 additions & 1 deletion tests/regressiontests/many_to_one_regress/models.py
@@ -1,5 +1,5 @@
"""
Regression tests for a few FK bugs: #1578, #6886
Regression tests for a few ForeignKey bugs.
"""

from django.db import models
Expand Down Expand Up @@ -106,6 +106,17 @@ def __unicode__(self):
...
ValueError: Cannot assign "<First: First object>": "Child.parent" must be a "Parent" instance.
# Nor can you explicitly assign None to Child.parent during object creation
# (regression for #9649).
>>> Child(name='xyzzy', parent=None)
Traceback (most recent call last):
...
ValueError: Cannot assign None: "Child.parent" does not allow null values.
>>> Child.objects.create(name='xyzzy', parent=None)
Traceback (most recent call last):
...
ValueError: Cannot assign None: "Child.parent" does not allow null values.
# Creation using keyword argument should cache the related object.
>>> p = Parent.objects.get(name="Parent")
>>> c = Child(parent=p)
Expand Down

0 comments on commit 53da1e4

Please sign in to comment.