Fixed #17615 -- Corrected unique field validation when using multitable inheritance. The validation used wrong pk value if the parent and child model had different pk fields. Thanks ungenio for the report and patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@17920 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
3d5d0be499
commit
53fb45c6d8
|
@ -718,9 +718,13 @@ class Model(object):
|
||||||
|
|
||||||
# Exclude the current object from the query if we are editing an
|
# Exclude the current object from the query if we are editing an
|
||||||
# instance (as opposed to creating a new one)
|
# instance (as opposed to creating a new one)
|
||||||
if not self._state.adding and self.pk is not None:
|
# Note that we need to use the pk as defined by model_class, not
|
||||||
qs = qs.exclude(pk=self.pk)
|
# 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 qs.exists():
|
||||||
if len(unique_check) == 1:
|
if len(unique_check) == 1:
|
||||||
key = unique_check[0]
|
key = unique_check[0]
|
||||||
|
|
|
@ -163,3 +163,10 @@ class BusStation(Station):
|
||||||
|
|
||||||
class TrainStation(Station):
|
class TrainStation(Station):
|
||||||
zone = models.IntegerField()
|
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)
|
||||||
|
|
|
@ -6,6 +6,7 @@ from __future__ import absolute_import
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
|
from django import forms
|
||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ from .models import (Place, Restaurant, ItalianRestaurant, ParkingLot,
|
||||||
ParkingLot2, ParkingLot3, Supplier, Wholesaler, Child, SelfRefParent,
|
ParkingLot2, ParkingLot3, Supplier, Wholesaler, Child, SelfRefParent,
|
||||||
SelfRefChild, ArticleWithAuthor, M2MChild, QualityControl, DerivedM,
|
SelfRefChild, ArticleWithAuthor, M2MChild, QualityControl, DerivedM,
|
||||||
Person, BirthdayParty, BachelorParty, MessyBachelorParty,
|
Person, BirthdayParty, BachelorParty, MessyBachelorParty,
|
||||||
InternalCertificationAudit, BusStation, TrainStation)
|
InternalCertificationAudit, BusStation, TrainStation, User, Profile)
|
||||||
|
|
||||||
|
|
||||||
class ModelInheritanceTest(TestCase):
|
class ModelInheritanceTest(TestCase):
|
||||||
|
@ -408,3 +409,17 @@ class ModelInheritanceTest(TestCase):
|
||||||
)
|
)
|
||||||
self.assertIs(BusStation._meta.pk.model, BusStation)
|
self.assertIs(BusStation._meta.pk.model, BusStation)
|
||||||
self.assertIs(TrainStation._meta.pk.model, TrainStation)
|
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())
|
||||||
|
|
Loading…
Reference in New Issue