summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/models/base.py10
-rw-r--r--tests/regressiontests/model_inheritance_regress/models.py7
-rw-r--r--tests/regressiontests/model_inheritance_regress/tests.py17
3 files changed, 30 insertions, 4 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py
index fc38224345..e28add30a9 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -718,9 +718,13 @@ class Model(object):
# Exclude the current object from the query if we are editing an
# instance (as opposed to creating a new one)
- if not self._state.adding and self.pk is not None:
- qs = qs.exclude(pk=self.pk)
-
+ # Note that we need to use the pk as defined by model_class, not
+ # self.pk. These can be different fields because model inheritance
+ # allows single model to have effectively multiple primary keys.
+ # Refs #17615.
+ model_class_pk = self._get_pk_val(model_class._meta)
+ if not self._state.adding and model_class_pk is not None:
+ qs = qs.exclude(pk=model_class_pk)
if qs.exists():
if len(unique_check) == 1:
key = unique_check[0]
diff --git a/tests/regressiontests/model_inheritance_regress/models.py b/tests/regressiontests/model_inheritance_regress/models.py
index bb5d77c51f..161569bcb3 100644
--- a/tests/regressiontests/model_inheritance_regress/models.py
+++ b/tests/regressiontests/model_inheritance_regress/models.py
@@ -163,3 +163,10 @@ class BusStation(Station):
class TrainStation(Station):
zone = models.IntegerField()
+
+class User(models.Model):
+ username = models.CharField(max_length=30, unique=True)
+
+class Profile(User):
+ profile_id = models.AutoField(primary_key=True)
+ extra = models.CharField(max_length=30, blank=True)
diff --git a/tests/regressiontests/model_inheritance_regress/tests.py b/tests/regressiontests/model_inheritance_regress/tests.py
index 8e2c56bd55..3cb6f9d603 100644
--- a/tests/regressiontests/model_inheritance_regress/tests.py
+++ b/tests/regressiontests/model_inheritance_regress/tests.py
@@ -6,6 +6,7 @@ from __future__ import absolute_import
import datetime
from operator import attrgetter
+from django import forms
from django.test import TestCase
@@ -13,7 +14,7 @@ from .models import (Place, Restaurant, ItalianRestaurant, ParkingLot,
ParkingLot2, ParkingLot3, Supplier, Wholesaler, Child, SelfRefParent,
SelfRefChild, ArticleWithAuthor, M2MChild, QualityControl, DerivedM,
Person, BirthdayParty, BachelorParty, MessyBachelorParty,
- InternalCertificationAudit, BusStation, TrainStation)
+ InternalCertificationAudit, BusStation, TrainStation, User, Profile)
class ModelInheritanceTest(TestCase):
@@ -408,3 +409,17 @@ class ModelInheritanceTest(TestCase):
)
self.assertIs(BusStation._meta.pk.model, BusStation)
self.assertIs(TrainStation._meta.pk.model, TrainStation)
+
+ def test_inherited_unique_field_with_form(self):
+ """
+ Test that a model which has different primary key for the parent model
+ passes unique field checking correctly. Refs #17615.
+ """
+ class ProfileForm(forms.ModelForm):
+ class Meta:
+ model = Profile
+ User.objects.create(username="user_only")
+ p = Profile.objects.create(username="user_with_profile")
+ form = ProfileForm({'username': "user_with_profile", 'extra': "hello"},
+ instance=p)
+ self.assertTrue(form.is_valid())