Fixed #21469 -- Allow set objects in Meta.unique_together.
Thanks to Tim for the review.
This commit is contained in:
parent
4cfe6ba6a3
commit
331d79a77d
|
@ -32,6 +32,7 @@ def normalize_unique_together(unique_together):
|
||||||
tuple of two strings. Normalize it to a tuple of tuples, so that
|
tuple of two strings. Normalize it to a tuple of tuples, so that
|
||||||
calling code can uniformly expect that.
|
calling code can uniformly expect that.
|
||||||
"""
|
"""
|
||||||
|
unique_together = tuple(unique_together)
|
||||||
if unique_together and not isinstance(unique_together[0], (tuple, list)):
|
if unique_together and not isinstance(unique_together[0], (tuple, list)):
|
||||||
unique_together = (unique_together,)
|
unique_together = (unique_together,)
|
||||||
return unique_together
|
return unique_together
|
||||||
|
|
|
@ -4,6 +4,8 @@ import datetime
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.db import models
|
||||||
|
from django.db.models.loading import BaseAppCache
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
from .models import (CustomPKModel, UniqueTogetherModel, UniqueFieldsModel,
|
from .models import (CustomPKModel, UniqueTogetherModel, UniqueFieldsModel,
|
||||||
|
@ -25,13 +27,45 @@ class GetUniqueCheckTests(unittest.TestCase):
|
||||||
def test_unique_together_gets_picked_up_and_converted_to_tuple(self):
|
def test_unique_together_gets_picked_up_and_converted_to_tuple(self):
|
||||||
m = UniqueTogetherModel()
|
m = UniqueTogetherModel()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
([(UniqueTogetherModel, ('ifield', 'cfield',)),
|
([(UniqueTogetherModel, ('ifield', 'cfield')),
|
||||||
(UniqueTogetherModel, ('ifield', 'efield')),
|
(UniqueTogetherModel, ('ifield', 'efield')),
|
||||||
(UniqueTogetherModel, ('id',)), ],
|
(UniqueTogetherModel, ('id',)), ],
|
||||||
[]),
|
[]),
|
||||||
m._get_unique_checks()
|
m._get_unique_checks()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_unique_together_normalization(self):
|
||||||
|
"""
|
||||||
|
Test the Meta.unique_together normalization with different sorts of
|
||||||
|
objects.
|
||||||
|
"""
|
||||||
|
data = {
|
||||||
|
'2-tuple': (('foo', 'bar'),
|
||||||
|
(('foo', 'bar'),)),
|
||||||
|
'list': (['foo', 'bar'],
|
||||||
|
(('foo', 'bar'),)),
|
||||||
|
'already normalized': ((('foo', 'bar'), ('bar', 'baz')),
|
||||||
|
(('foo', 'bar'), ('bar', 'baz'))),
|
||||||
|
'set': ({('foo', 'bar'), ('bar', 'baz')}, # Ref #21469
|
||||||
|
(('foo', 'bar'), ('bar', 'baz'))),
|
||||||
|
}
|
||||||
|
|
||||||
|
for test_name, (unique_together, normalized) in data.items():
|
||||||
|
class M(models.Model):
|
||||||
|
foo = models.IntegerField()
|
||||||
|
bar = models.IntegerField()
|
||||||
|
baz = models.IntegerField()
|
||||||
|
|
||||||
|
Meta = type(str('Meta'), (), {
|
||||||
|
'unique_together': unique_together,
|
||||||
|
'app_cache': BaseAppCache()
|
||||||
|
})
|
||||||
|
|
||||||
|
checks, _ = M()._get_unique_checks()
|
||||||
|
for t in normalized:
|
||||||
|
check = (M, t)
|
||||||
|
self.assertIn(check, checks)
|
||||||
|
|
||||||
def test_primary_key_is_considered_unique(self):
|
def test_primary_key_is_considered_unique(self):
|
||||||
m = CustomPKModel()
|
m = CustomPKModel()
|
||||||
self.assertEqual(([(CustomPKModel, ('my_pk_field',))], []), m._get_unique_checks())
|
self.assertEqual(([(CustomPKModel, ('my_pk_field',))], []), m._get_unique_checks())
|
||||||
|
|
Loading…
Reference in New Issue