Fixed pk uniqueness validation for new objects created outside of a ModelForm. Also removed need for ModelForm to poke at Model._state.adding, keeping it an internal ORM concern.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14613 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
38ba3775ec
commit
008f333bac
|
@ -265,7 +265,7 @@ class ModelState(object):
|
||||||
# If true, uniqueness validation checks will consider this a new, as-yet-unsaved object.
|
# If true, uniqueness validation checks will consider this a new, as-yet-unsaved object.
|
||||||
# Necessary for correct validation of new instances of objects with explicit (non-auto) PKs.
|
# Necessary for correct validation of new instances of objects with explicit (non-auto) PKs.
|
||||||
# This impacts validation only; it has no effect on the actual save.
|
# This impacts validation only; it has no effect on the actual save.
|
||||||
self.adding = False
|
self.adding = True
|
||||||
|
|
||||||
class Model(object):
|
class Model(object):
|
||||||
__metaclass__ = ModelBase
|
__metaclass__ = ModelBase
|
||||||
|
|
|
@ -284,6 +284,8 @@ class QuerySet(object):
|
||||||
|
|
||||||
# Store the source database of the object
|
# Store the source database of the object
|
||||||
obj._state.db = self.db
|
obj._state.db = self.db
|
||||||
|
# This object came from the database; it's not being added.
|
||||||
|
obj._state.adding = False
|
||||||
|
|
||||||
for i, k in enumerate(extra_select):
|
for i, k in enumerate(extra_select):
|
||||||
setattr(obj, k, row[i])
|
setattr(obj, k, row[i])
|
||||||
|
@ -1204,6 +1206,7 @@ def get_cached_row(klass, row, index_start, using, max_depth=0, cur_depth=0,
|
||||||
# If an object was retrieved, set the database state.
|
# If an object was retrieved, set the database state.
|
||||||
if obj:
|
if obj:
|
||||||
obj._state.db = using
|
obj._state.db = using
|
||||||
|
obj._state.adding = False
|
||||||
|
|
||||||
index_end = index_start + field_count + offset
|
index_end = index_start + field_count + offset
|
||||||
# Iterate over each related object, populating any
|
# Iterate over each related object, populating any
|
||||||
|
@ -1387,6 +1390,7 @@ class RawQuerySet(object):
|
||||||
setattr(instance, field, value)
|
setattr(instance, field, value)
|
||||||
|
|
||||||
instance._state.db = self.query.using
|
instance._state.db = self.query.using
|
||||||
|
instance._state.adding = False
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
|
@ -254,10 +254,8 @@ class BaseModelForm(BaseForm):
|
||||||
# if we didn't get an instance, instantiate a new one
|
# if we didn't get an instance, instantiate a new one
|
||||||
self.instance = opts.model()
|
self.instance = opts.model()
|
||||||
object_data = {}
|
object_data = {}
|
||||||
self.instance._state.adding = True
|
|
||||||
else:
|
else:
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.instance._state.adding = False
|
|
||||||
object_data = model_to_dict(instance, opts.fields, opts.exclude)
|
object_data = model_to_dict(instance, opts.fields, opts.exclude)
|
||||||
# if initial was provided, it should override the values from instance
|
# if initial was provided, it should override the values from instance
|
||||||
if initial is not None:
|
if initial is not None:
|
||||||
|
|
|
@ -58,6 +58,8 @@ class BrokenUnicodeMethod(models.Model):
|
||||||
# object).
|
# object).
|
||||||
return 'Názov: %s' % self.name
|
return 'Názov: %s' % self.name
|
||||||
|
|
||||||
|
class NonAutoPK(models.Model):
|
||||||
|
name = models.CharField(max_length=10, primary_key=True)
|
||||||
|
|
||||||
__test__ = {'API_TESTS': """
|
__test__ = {'API_TESTS': """
|
||||||
(NOTE: Part of the regression test here is merely parsing the model
|
(NOTE: Part of the regression test here is merely parsing the model
|
||||||
|
|
|
@ -1,16 +1,26 @@
|
||||||
from models import Worker
|
from django.core.exceptions import ValidationError
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from models import Worker, NonAutoPK
|
||||||
|
|
||||||
|
|
||||||
class RelatedModelOrderedLookupTest(TestCase):
|
class RelatedModelOrderedLookupTest(TestCase):
|
||||||
"""
|
"""
|
||||||
Regression test for #10153: foreign key __gte and __lte lookups.
|
Regression test for #10153: foreign key __gte and __lte lookups.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# The bug is that the following queries would raise:
|
# The bug is that the following queries would raise:
|
||||||
# "TypeError: Related Field has invalid lookup: gte"
|
# "TypeError: Related Field has invalid lookup: gte"
|
||||||
|
|
||||||
def test_related_gte_lookup(self):
|
def test_related_gte_lookup(self):
|
||||||
Worker.objects.filter(department__gte=0)
|
Worker.objects.filter(department__gte=0)
|
||||||
|
|
||||||
def test_related_lte_lookup(self):
|
def test_related_lte_lookup(self):
|
||||||
Worker.objects.filter(department__lte=0)
|
Worker.objects.filter(department__lte=0)
|
||||||
|
|
||||||
|
|
||||||
|
class ModelValidationTest(TestCase):
|
||||||
|
def test_pk_validation(self):
|
||||||
|
one = NonAutoPK.objects.create(name="one")
|
||||||
|
again = NonAutoPK(name="one")
|
||||||
|
self.assertRaises(ValidationError, again.validate_unique)
|
||||||
|
|
Loading…
Reference in New Issue