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())
|
||||
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):
|
||||
"Returns a list of Options objects that are ordered with respect to this object."
|
||||
if not hasattr(self, '_ordered_objects'):
|
||||
|
|
|
@ -643,14 +643,14 @@ class BaseQuery(object):
|
|||
aliases = set()
|
||||
if start_alias:
|
||||
seen = {None: start_alias}
|
||||
root_pk = opts.pk.column
|
||||
for field, model in opts.get_fields_with_model():
|
||||
if start_alias:
|
||||
try:
|
||||
alias = seen[model]
|
||||
except KeyError:
|
||||
link_field = opts.get_ancestor_link(model)
|
||||
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
|
||||
else:
|
||||
# If we're starting from the base model of the queryset, the
|
||||
|
@ -1156,13 +1156,13 @@ class BaseQuery(object):
|
|||
as_sql()).
|
||||
"""
|
||||
opts = self.model._meta
|
||||
root_pk = opts.pk.column
|
||||
root_alias = self.tables[0]
|
||||
seen = {None: root_alias}
|
||||
for field, model in opts.get_fields_with_model():
|
||||
if model not in seen:
|
||||
link_field = opts.get_ancestor_link(model)
|
||||
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
|
||||
|
||||
def remove_inherited_models(self):
|
||||
|
|
|
@ -86,6 +86,19 @@ class Evaluation(Article):
|
|||
class QualityControl(Evaluation):
|
||||
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':"""
|
||||
# Regression for #7350, #7202
|
||||
|
@ -275,4 +288,10 @@ True
|
|||
>>> ArticleWithAuthor.objects.filter(pk=article.pk).update(headline="Oh, no!")
|
||||
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