Fixed #7551 -- Made GFK allow None init argument.

Thanks SamBull for the report.
This commit is contained in:
Bouke Haarsma 2013-10-15 17:24:35 +02:00 committed by Tim Graham
parent 763ac8b642
commit 3918eeb9fd
3 changed files with 29 additions and 3 deletions

View File

@ -59,8 +59,12 @@ class GenericForeignKey(six.with_metaclass(RenameGenericForeignKeyMethods)):
"""
if self.name in kwargs:
value = kwargs.pop(self.name)
if value is not None:
kwargs[self.ct_field] = self.get_content_type(obj=value)
kwargs[self.fk_field] = value._get_pk_val()
else:
kwargs[self.ct_field] = None
kwargs[self.fk_field] = None
def get_content_type(self, obj=None, id=None, using=None):
if obj is not None:

View File

@ -137,3 +137,10 @@ class ConcreteRelatedModel(models.Model):
class ProxyRelatedModel(ConcreteRelatedModel):
class Meta:
proxy = True
# To test fix for #7551
class AllowsNullGFK(models.Model):
content_type = models.ForeignKey(ContentType, null=True)
object_id = models.PositiveIntegerField(null=True)
content_object = generic.GenericForeignKey()

View File

@ -4,11 +4,12 @@ from django import forms
from django.contrib.contenttypes.generic import generic_inlineformset_factory
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase
from django.utils import six
from .models import (TaggedItem, ValuableTaggedItem, Comparison, Animal,
Vegetable, Mineral, Gecko, Rock, ManualPK,
ForProxyModelModel, ForConcreteModelModel,
ProxyRelatedModel, ConcreteRelatedModel)
ProxyRelatedModel, ConcreteRelatedModel, AllowsNullGFK)
class GenericRelationsTests(TestCase):
@ -440,3 +441,17 @@ class ProxyRelatedModelTest(TestCase):
newrel.bases = [base]
newrel = ConcreteRelatedModel.objects.get(pk=newrel.pk)
self.assertEqual(base, newrel.bases.get())
class TestInitWithNoneArgument(TestCase):
def test_none_not_allowed(self):
# TaggedItem requires a content_type, initializing with None should
# raise a ValueError.
with six.assertRaisesRegex(self, ValueError,
'Cannot assign None: "TaggedItem.content_type" does not allow null values'):
TaggedItem(content_object=None)
def test_none_allowed(self):
# AllowsNullGFK doesn't require a content_type, so None argument should
# also be allowed.
AllowsNullGFK(content_object=None)