Opened 6 hours ago

#36183 new Bug

Model o2o inheritance with abstract models does not "evaluate" a lazy relationship

Reported by: BeryCZ Owned by:
Component: Database layer (models, ORM) Version: 5.1
Severity: Normal Keywords:
Cc: BeryCZ Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When I define models like this

class AbstractPage(models.Model):
    mtime = models.DateTimeField(
        verbose_name="Last modification at",
        auto_now=True,
    )

    class Meta:
        abstract = True


class AbstractPageType(models.Model):
    page = models.OneToOneField(
        "Page",
        verbose_name="ID",
        primary_key=True,
        on_delete=models.CASCADE,
        related_name="%(class)s",
        parent_link=True,
    )
    title = models.CharField(
        verbose_name="Title",
        max_length=255,
        null=False,
        blank=False,
    )

    class Meta:
        abstract = True


class Page(AbstractPage):
    pass


class ArticlePage(AbstractPageType, Page):
    pass

And then I do

ArticlePage.objects.order_by("-mtime").all()

I get

  File "django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "django/db/models/query.py", line 1701, in order_by
    obj.query.add_ordering(*field_names)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "django/db/models/sql/query.py", line 2249, in add_ordering
    self.names_to_path(item.split(LOOKUP_SEP), self.model._meta)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "django/db/models/sql/query.py", line 1777, in names_to_path
    path_to_parent = opts.get_path_to_parent(model)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "django/db/models/options.py", line 755, in get_path_to_parent
    targets = (final_field.remote_field.get_related_field(),)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "django/db/models/fields/reverse_related.py", line 311, in get_related_field
    field = self.model._meta.get_field(self.field_name)
            ^^^^^^^^^^^^^^^^

Exception Type: AttributeError
Exception Value: 'str' object has no attribute '_meta'

It works when I do

class ArticlePage(AbstractPageType, Page):
    page = models.OneToOneField(
        "Page",
        verbose_name="ID",
        primary_key=True,
        on_delete=models.CASCADE,
        related_name="%(class)s",
        parent_link=True,
    )

but I would prefer not to have to define page field in every PageType.

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top