Parser: any class whose base name ends in `Mixin` becomes a model, even a QuerySet or a plain helper

Đang mở
#249 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

@noahkhomer18 đang làm issue này rồi.

Từ ngày 14/11/2026.

  • #258 của @noahkhomer18 — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
25/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
django, python
Lĩnh vực
devtools

Hướng nghiên cứu

Start in cli/orm_lens/parser.py: the Mixin$ branch of _looks_like_model() (around line 442) and where _resolve_and_filter() (around line 829) seeds is_model_name from it. Run the repro from the issue to confirm that only projects.Project should be listed. Done when phantom mixins drop out, the abstract-mixin test in test_abstract_and_auth_user.py and the mezzanine golden snapshot still pass, and pytest, ruff and mypy are clean. Note that open pull request #258 already targets this issue, so check it before starting.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

bug good first issue python

Source: label-studio — label_studio/projects/models.py:72, label_studio/tasks/models.py; weblate — weblate/trans/mixins.py:74,81,154

What happens

_looks_like_model() returns True as soon as a base's name ends with Mixin. That's a guess for third-party bases we can't see. But it also fires when the mixin is defined right there in the workspace and is a plain class:

  • label-studio: class ProjectQuerySetWithFSM(FSMStateQuerySetMixin, ProjectQuerySet). ProjectQuerySet is a models.QuerySet, FSMStateQuerySetMixin is a plain class. orm-lens lists projects.ProjectQuerySetWithFSM as a model, and drift says blocking: "declared, but no migration creates it". Four of these, so drift fails the build.
  • weblate: class URLMixin(BaseURLMixin), LoggerMixin(BaseURLMixin), PathMixin(LoggerMixin, URLMixin) in trans/mixins.py. BaseURLMixin is class BaseURLMixin:. They're pulled in because Project inherits PathMixin, and then show up as three blocking drift entries.
Repro

projects/mixins.py

class StateQuerySetMixin:
    def with_state(self):
        return self


class URLMixin:
    def get_absolute_url(self):
        return "/"

projects/models.py

from django.db import models

from .mixins import StateQuerySetMixin, URLMixin


class ProjectQuerySet(models.QuerySet):
    pass


class ProjectQuerySetWithState(StateQuerySetMixin, ProjectQuerySet):
    pass


class PathMixin(URLMixin):
    def full_path(self):
        return self.get_absolute_url()


class Project(models.Model, PathMixin):
    title = models.CharField(max_length=100)

    objects = ProjectQuerySetWithState.as_manager()
$ orm-lens list
projects.ProjectQuerySetWithState
projects.PathMixin
projects.Project

Expected: only projects.Project.

Where

cli/orm_lens/parser.py

  • line 442, _looks_like_model(), the re.search(r"Mixin$", tail) branch;
  • line 829, _resolve_and_filter(), which seeds is_model_name from _looks_like_model() and then runs the fixed point over real definitions.
Suggested fix

Use the name guess only for bases we have no definition for. In _resolve_and_filter(), collect defined = {m.name for m in all_defs} and pass it to _looks_like_model(); skip the Mixin$ branch when tail in defined. A mixin that really is a model (class TimeStampMixin(models.Model)) still gets in through the fixed-point loop, because its own base is models.Model.

test_abstract_and_auth_user.py covers abstract mixins and should stay green. The mezzanine golden fixture has *Mixin classes too, so run the golden tests and update the snapshot if a phantom model drops out (say so in the PR).

How to test
  • A test in cli/tests/test_cross_module_bases.py (or a new file) with the repro: only Project is returned.
  • A mixin defined as class OwnedMixin(models.Model) with abstract = True, plus class Doc(OwnedMixin): Doc is still a model and inherits the fields.
  • cd cli && python -m pytest -q, ruff and mypy pass.

Difficulty: good first issue.

Ngôn ngữ chính
Python
Star
84
Fork
13
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của FROWNINGdev/django-orm-lens

Tất cả issue của FROWNINGdev/django-orm-lens

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.