Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Fixed
- ``QuerySet.count()`` now matches the limited query result for the LIMIT/OFFSET edge cases: it returns ``0`` (instead of a negative number) when ``offset()`` exceeds the total row count, and ``0`` (instead of the total) for ``limit(0)``. (#2208)
- Field declarations on models now resolve to their concrete type (e.g. ``CharField[str]``) in Pyright/Pylance instead of ``Field[Unknown]``; the ``Field.__new__`` type-check stub now returns ``Self``. (#2216)
- ``TransactionContext`` now returns a ``TransactionalDBClient`` instead of a raw database connection. This change gives the correct inferred type for the transaction context. (#2232)
- A model with its own ``Meta`` now inherits ``Meta.ordering`` from its abstract base model when it does not define its own. (#2046)


1.1.7
Expand Down
34 changes: 34 additions & 0 deletions tests/test_inheritance.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,37 @@ async def test_basic(db):
await model.save()
assert model.created_at is not None
assert model.modified_at is not None


def test_abstract_meta_ordering_is_inherited():
"""A subclass without its own ``Meta.ordering`` inherits the abstract
base's ordering, while a subclass that defines its own keeps it and an
explicitly empty ordering stays empty (#2046)."""
from tortoise import fields
from tortoise.models import Model

class OrderedBase(Model):
value = fields.IntField()

class Meta:
abstract = True
ordering = ["-value"]

class InheritsOrdering(OrderedBase):
class Meta:
abstract = True

class OwnOrdering(OrderedBase):
class Meta:
abstract = True
ordering = ["value"]

class EmptyOrdering(OrderedBase):
class Meta:
abstract = True
ordering = []

assert OrderedBase._meta._default_ordering != ()
assert InheritsOrdering._meta._default_ordering == OrderedBase._meta._default_ordering
assert OwnOrdering._meta._default_ordering != OrderedBase._meta._default_ordering
assert EmptyOrdering._meta._default_ordering == ()
9 changes: 9 additions & 0 deletions tortoise/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,15 @@ def __new__(cls, name: str, bases: tuple[type, ...], attrs: dict[str, Any]) -> M
pk_attr,
)

# Inherit the default ordering from an abstract base model when the
# subclass's own Meta does not define one (#2046).
if not hasattr(meta_class, "ordering"):
for base in bases:
base_meta = getattr(base, "_meta", None)
if base_meta is not None and base_meta._default_ordering:
meta._default_ordering = base_meta._default_ordering
break

new_class = super().__new__(cls, name, bases, attrs)
for field in meta.fields_map.values():
field.model = new_class # type: ignore
Expand Down
Loading