Author: mtredinnick Date: 2009-03-05 22:51:05 -0600 (Thu, 05 Mar 2009) New Revision: 9983
Modified: django/trunk/django/db/models/base.py django/trunk/tests/regressiontests/many_to_one_regress/models.py Log: Fixed #9649 -- Better error handling in model creation. 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.zou...@gmail.com and ondrej.koh...@gmail.com for some analysis of this problem. Modified: django/trunk/django/db/models/base.py =================================================================== --- django/trunk/django/db/models/base.py 2009-03-06 02:38:38 UTC (rev 9982) +++ django/trunk/django/db/models/base.py 2009-03-06 04:51:05 UTC (rev 9983) @@ -224,12 +224,13 @@ # 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. @@ -245,11 +246,11 @@ 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) Modified: django/trunk/tests/regressiontests/many_to_one_regress/models.py =================================================================== --- django/trunk/tests/regressiontests/many_to_one_regress/models.py 2009-03-06 02:38:38 UTC (rev 9982) +++ django/trunk/tests/regressiontests/many_to_one_regress/models.py 2009-03-06 04:51:05 UTC (rev 9983) @@ -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 @@ -106,6 +106,17 @@ ... 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) --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---