Fixed #21469 -- Allow set objects in Meta.unique_together.

Thanks to Tim for the review.
This commit is contained in:
Baptiste Mispelon 2013-11-20 10:28:22 +01:00
parent 4cfe6ba6a3
commit 331d79a77d
2 changed files with 36 additions and 1 deletions

View File

@ -32,6 +32,7 @@ def normalize_unique_together(unique_together):
tuple of two strings. Normalize it to a tuple of tuples, so that
calling code can uniformly expect that.
"""
unique_together = tuple(unique_together)
if unique_together and not isinstance(unique_together[0], (tuple, list)):
unique_together = (unique_together,)
return unique_together

View File

@ -4,6 +4,8 @@ import datetime
import unittest
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models.loading import BaseAppCache
from django.test import TestCase
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):
m = UniqueTogetherModel()
self.assertEqual(
([(UniqueTogetherModel, ('ifield', 'cfield',)),
([(UniqueTogetherModel, ('ifield', 'cfield')),
(UniqueTogetherModel, ('ifield', 'efield')),
(UniqueTogetherModel, ('id',)), ],
[]),
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):
m = CustomPKModel()
self.assertEqual(([(CustomPKModel, ('my_pk_field',))], []), m._get_unique_checks())