Fixed #10251 -- Fixed model inheritance when there's also an explicit pk field.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@9970 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
0e93f60c7f
commit
dfd7a6c781
|
@ -435,6 +435,21 @@ class Options(object):
|
||||||
result.update(parent._meta.get_parent_list())
|
result.update(parent._meta.get_parent_list())
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def get_ancestor_link(self, ancestor):
|
||||||
|
"""
|
||||||
|
Returns the field on the current model which points to the given
|
||||||
|
"ancestor". This is possible an indirect link (a pointer to a parent
|
||||||
|
model, which points, eventually, to the ancestor). Used when
|
||||||
|
constructing table joins for model inheritance.
|
||||||
|
|
||||||
|
Returns None if the model isn't an ancestor of this one.
|
||||||
|
"""
|
||||||
|
if ancestor in self.parents:
|
||||||
|
return self.parents[ancestor]
|
||||||
|
for parent in self.parents:
|
||||||
|
if parent._meta.get_ancestor_link(ancestor):
|
||||||
|
return self.parents[parent]
|
||||||
|
|
||||||
def get_ordered_objects(self):
|
def get_ordered_objects(self):
|
||||||
"Returns a list of Options objects that are ordered with respect to this object."
|
"Returns a list of Options objects that are ordered with respect to this object."
|
||||||
if not hasattr(self, '_ordered_objects'):
|
if not hasattr(self, '_ordered_objects'):
|
||||||
|
|
|
@ -643,14 +643,14 @@ class BaseQuery(object):
|
||||||
aliases = set()
|
aliases = set()
|
||||||
if start_alias:
|
if start_alias:
|
||||||
seen = {None: start_alias}
|
seen = {None: start_alias}
|
||||||
root_pk = opts.pk.column
|
|
||||||
for field, model in opts.get_fields_with_model():
|
for field, model in opts.get_fields_with_model():
|
||||||
if start_alias:
|
if start_alias:
|
||||||
try:
|
try:
|
||||||
alias = seen[model]
|
alias = seen[model]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
link_field = opts.get_ancestor_link(model)
|
||||||
alias = self.join((start_alias, model._meta.db_table,
|
alias = self.join((start_alias, model._meta.db_table,
|
||||||
root_pk, model._meta.pk.column))
|
link_field.column, model._meta.pk.column))
|
||||||
seen[model] = alias
|
seen[model] = alias
|
||||||
else:
|
else:
|
||||||
# If we're starting from the base model of the queryset, the
|
# If we're starting from the base model of the queryset, the
|
||||||
|
@ -1156,13 +1156,13 @@ class BaseQuery(object):
|
||||||
as_sql()).
|
as_sql()).
|
||||||
"""
|
"""
|
||||||
opts = self.model._meta
|
opts = self.model._meta
|
||||||
root_pk = opts.pk.column
|
|
||||||
root_alias = self.tables[0]
|
root_alias = self.tables[0]
|
||||||
seen = {None: root_alias}
|
seen = {None: root_alias}
|
||||||
for field, model in opts.get_fields_with_model():
|
for field, model in opts.get_fields_with_model():
|
||||||
if model not in seen:
|
if model not in seen:
|
||||||
|
link_field = opts.get_ancestor_link(model)
|
||||||
seen[model] = self.join((root_alias, model._meta.db_table,
|
seen[model] = self.join((root_alias, model._meta.db_table,
|
||||||
root_pk, model._meta.pk.column))
|
link_field.column, model._meta.pk.column))
|
||||||
self.included_inherited_models = seen
|
self.included_inherited_models = seen
|
||||||
|
|
||||||
def remove_inherited_models(self):
|
def remove_inherited_models(self):
|
||||||
|
|
|
@ -86,6 +86,19 @@ class Evaluation(Article):
|
||||||
class QualityControl(Evaluation):
|
class QualityControl(Evaluation):
|
||||||
assignee = models.CharField(max_length=50)
|
assignee = models.CharField(max_length=50)
|
||||||
|
|
||||||
|
class BaseM(models.Model):
|
||||||
|
base_name = models.CharField(max_length=100)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.base_name
|
||||||
|
|
||||||
|
class DerivedM(BaseM):
|
||||||
|
customPK = models.IntegerField(primary_key=True)
|
||||||
|
derived_name = models.CharField(max_length=100)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return "PK = %d, base_name = %s, derived_name = %s" \
|
||||||
|
% (self.customPK, self.base_name, self.derived_name)
|
||||||
|
|
||||||
__test__ = {'API_TESTS':"""
|
__test__ = {'API_TESTS':"""
|
||||||
# Regression for #7350, #7202
|
# Regression for #7350, #7202
|
||||||
|
@ -275,4 +288,10 @@ True
|
||||||
>>> ArticleWithAuthor.objects.filter(pk=article.pk).update(headline="Oh, no!")
|
>>> ArticleWithAuthor.objects.filter(pk=article.pk).update(headline="Oh, no!")
|
||||||
1
|
1
|
||||||
|
|
||||||
|
>>> DerivedM.objects.create(customPK=44, base_name="b1", derived_name="d1")
|
||||||
|
<DerivedM: PK = 44, base_name = b1, derived_name = d1>
|
||||||
|
>>> DerivedM.objects.all()
|
||||||
|
[<DerivedM: PK = 44, base_name = b1, derived_name = d1>]
|
||||||
|
|
||||||
"""}
|
"""}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue