Commit dce458cd authored by Malcolm Tredinnick's avatar Malcolm Tredinnick
Browse files

[1.0.X] Fixed #10251 -- Fixed model inheritance when there's also an explicit pk field.

Backport of r9970 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@9972 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent b57d86f2
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -436,6 +436,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'):
+4 −4
Original line number Diff line number Diff line
@@ -494,14 +494,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
@@ -1005,13 +1005,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):
+19 −0
Original line number Diff line number Diff line
@@ -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>]

"""}