Parser: field classes defined in the project itself are not recognised

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

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
35/100
Loại issue
Tính năng
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
django, python
Lĩnh vực
cli

Hướng nghiên cứu

Start in cli/orm_lens/parser.py: BARE_FIELD_TYPES and BARE_FIELD_RE (around lines 82 and 176) decide which bare calls count as fields, and _pull_imported_bases() (around line 935) already follows imports to the defining file. Agree the approach on the issue first. Done means the repro in the issue reports tax_rate, key_filter and groups correctly, a new test covers the two-hop subclass case, and the golden snapshots are updated.

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

Mô tả

enhancement help wanted python

Source: pretix — src/pretix/helpers/models.py:79 (NormalizedDecimalField), src/pretix/base/models/fields.py:31 (MultiStringField), src/pretix/helpers/countries.py:68 (FastCountryField); weblate — weblate/trans/fields.py:10 (RegexField), weblate/utils/fields.py:34 (UsernameField), weblate/auth/models.py:916 (GroupManyToManyField, used at line 1004)

What happens

Big projects wrap Django fields in their own subclasses:

# helpers/models.py
class NormalizedDecimalField(DecimalField): ...

# models.py
tax_rate = NormalizedDecimalField(max_digits=7, decimal_places=4)

A bare call is only a field when its name is in BARE_FIELD_TYPES, so all of these are dropped: from describe, er and cascade (a dropped relation hides its whole edge), and drift lists them as "migrated but no longer declared".

On pretix most of its ~45 drift entries are this (tax_rate, country, phone, restrict_to_status, ...). On weblate it's User.username, User.groups (a M2M subclass, so the relation is lost too), Component.language_regex/variant_regex/key_filter, Screenshot.image.

Repro

core/fields.py

from django.db import models
from django.db.models import DecimalField


class NormalizedDecimalField(DecimalField):
    pass


class RegexField(models.TextField):
    pass


class GroupManyToManyField(models.ManyToManyField):
    pass

shop/models.py

from django.contrib.auth.models import Group
from django.db import models

from core.fields import GroupManyToManyField, NormalizedDecimalField, RegexField


class Product(models.Model):
    name = models.CharField(max_length=100)
    tax_rate = NormalizedDecimalField(max_digits=7, decimal_places=4)
    key_filter = RegexField(blank=True)
    groups = GroupManyToManyField(Group, blank=True)
$ orm-lens describe shop.Product
| `name` | CharField | `max_length=100` |

Expected: tax_rate (DecimalField), key_filter (TextField) and groups as a ManyToManyField relation to Group.

Where

cli/orm_lens/parser.py

  • line 82 / 176, BARE_FIELD_TYPES and BARE_FIELD_RE;
  • line 935, _pull_imported_bases(): already follows a module's imports to the file that defines a name. That's the piece to reuse here.
Suggested fix

One possible shape:

  1. In the body loop, when a line looks like name = SomeName( but SomeName isn't whitelisted, remember it as a candidate instead of dropping it.
  2. After the scan, resolve each candidate through the module's imports (same machinery as _pull_imported_bases). If its class inherits, directly or a few hops up, from a known Django field, record the field with that base's type. If it's a ForeignKey/OneToOneField/ManyToManyField subclass, fill the relation data the usual way.
  3. Unresolvable names stay dropped, as today.

Third-party fields (PhoneNumberField, CountryField, I18nCharField, AutoOneToOneField from django-annoying) are a separate question: a small map of well-known ones is fine as a follow-up, not needed here.

This is the bigger one in the batch, hence help wanted. Comment on the issue with your plan first, happy to talk it through.

How to test
  • A new test file with the repro (two modules, resolved through the import).
  • A subclass two hops away (class A(models.CharField), class B(A)).
  • A name that isn't a field class (x = make_thing(...)) is still ignored.
  • Run the golden snapshots; saleor/zulip may gain fields, update them and list the changes in the PR.
  • cd cli && python -m pytest -q, ruff and mypy pass.

Difficulty: help wanted, most of a day.

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.