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

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
parent 0e93f60c
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -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'):
+4 −4
Original line number Diff line number Diff line
@@ -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):
+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>]

"""}