Code

Ticket #13091: 13091_partial_unique_together.2.diff

File 13091_partial_unique_together.2.diff, 4.1 KB (added by julien, 3 years ago)
Line 
1diff --git a/django/forms/models.py b/django/forms/models.py
2index 912bdf3..0c8c5df 100644
3--- a/django/forms/models.py
4+++ b/django/forms/models.py
5@@ -342,9 +342,8 @@ class BaseModelForm(BaseForm):
6         Calls the instance's validate_unique() method and updates the form's
7         validation errors if any were raised.
8         """
9-        exclude = self._get_validation_exclusions()
10         try:
11-            self.instance.validate_unique(exclude=exclude)
12+            self.instance.validate_unique()
13         except ValidationError, e:
14             self._update_errors(e.message_dict)
15 
16diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py
17index 7d6cab3..80ff365 100644
18--- a/tests/regressiontests/admin_views/models.py
19+++ b/tests/regressiontests/admin_views/models.py
20@@ -704,6 +704,18 @@ class FoodDeliveryAdmin(admin.ModelAdmin):
21     list_display=('reference', 'driver', 'restaurant')
22     list_editable = ('driver', 'restaurant')
23 
24+class UniqueTogether(models.Model):
25+    t1 = models.CharField(max_length=255, blank=True, null=True)
26+    t2 = models.CharField(max_length=255, blank=True, null=True)
27+    t3 = models.CharField(max_length=255, blank=True, null=True)     
28+   
29+    class Meta:
30+        unique_together = ['t1','t2','t3']
31+               
32+class UniqueTogetherAdmin(admin.ModelAdmin):
33+    list_display = ['t3', 't1', 't2']
34+    list_editable = ['t1', 't2',]
35+   
36 
37 admin.site.register(Article, ArticleAdmin)
38 admin.site.register(CustomArticle, CustomArticleAdmin)
39@@ -743,6 +755,7 @@ admin.site.register(WorkHour, WorkHourAdmin)
40 admin.site.register(Reservation)
41 admin.site.register(FoodDelivery, FoodDeliveryAdmin)
42 admin.site.register(RowLevelChangePermissionModel, RowLevelChangePermissionModelAdmin)
43+admin.site.register(UniqueTogether, UniqueTogetherAdmin)
44 
45 # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
46 # That way we cover all four cases:
47diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
48index 642186e..da04137 100644
49--- a/tests/regressiontests/admin_views/tests.py
50+++ b/tests/regressiontests/admin_views/tests.py
51@@ -36,7 +36,7 @@ from models import (Article, BarAccount, CustomArticle, EmptyModel,
52     Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit,
53     Category, Post, Plot, FunkyTag, Chapter, Book, Promo, WorkHour, Employee,
54     Question, Answer, Inquisition, Actor, FoodDelivery,
55-    RowLevelChangePermissionModel)
56+    RowLevelChangePermissionModel, UniqueTogether)
57 
58 
59 class AdminViewBasicTest(TestCase):
60@@ -1373,6 +1373,39 @@ class AdminViewListEditable(TestCase):
61         # 1 select per object = 3 selects
62         self.assertEqual(response.content.count("<select"), 4)
63 
64+    def test_partial_unique_together(self):
65+        """ Ensure that no IntegrityError is raised when editing some (but
66+            not all) of the values specified as unique_together. Refs #13091.
67+        """
68+        UniqueTogether.objects.create(t1='a', t2='b', t3='c')
69+        UniqueTogether.objects.create(t1='b', t2='b', t3='a')
70+        UniqueTogether.objects.create(t1='c', t2='a', t3='c')
71+        data = {
72+            "form-TOTAL_FORMS": "3",
73+            "form-INITIAL_FORMS": "3",
74+            "form-MAX_NUM_FORMS": "0",
75+
76+            "form-0-t1": "a",
77+            "form-0-t2": "b",
78+            "form-0-t3": "c",
79+            "form-0-id": "1",
80+
81+            "form-1-t1": "a",
82+            "form-1-t2": "b",
83+            "form-1-t3": "c",
84+            "form-1-id": "2",
85+
86+            "form-2-t1": "a",
87+            "form-2-t2": "b",
88+            "form-2-t3": "c",
89+            "form-2-id": "3",
90+
91+            "_save": "Save",
92+        }
93+        response = self.client.post('/test_admin/admin/admin_views/uniquetogether/', data)
94+        self.assertContains(response, 'Please correct the errors below.')
95+        self.assertContains(response, 'Unique together with this T1, T2 and T3 already exists.')
96+       
97     def test_post_messages(self):
98         # Ticket 12707: Saving inline editable should not show admin
99         # action warnings