Автоматическое создание логического поля-близнеца для полей модели Django - PullRequest
3 голосов
/ 05 ноября 2019

У меня есть модели со многими полями. Для большого количества этих полей (скажем, около 20), но не для всех, я хотел бы автоматически создать двойник BooleanField каждое.

Некоторые требования:

  • поля различного типа (например, CharField, DateField, ...)
  • В будущем будут добавлены новые поля, поэтому я хочу создать это общее решение, так что я будунужно только добавить основное поле и пометить его для добавления двойника
  • В идеале я хотел бы иметь возможность использовать тот же синтаксис ORM для фильтрации, например, если бы я вручную определил логический близнец
  • В большинстве случаев нужны только сами поля, очень редко - логический близнец

Учитывая следующую модель

from django.db.models import model

class MyModel(models.Model):
    ignore_field = models.Charfield(max_length=10)
    my_field = models.Charfield(max_length=30)

Я хотел бы автоматически добавить поле:

    is_fixed_my_field = models.BooleanField(default=False)

То, что я рассмотрел:

1. составные поля

Проблема, с которой я сталкиваюсь при таком подходе, заключается в том, что мне потребуется определить такое составное поле вручную для каждого типа поля, и я также не уверен, что смогупройти kwargs. Кроме того, я не думаю, что смогу сохранить синтаксис по умолчанию для запросов. Вместо этого я должен был бы добавить этот дополнительный уровень на каждом фильтре.

class FixedField(CompositeField):
    value = models.Charfield()  # could I even add the kwargs?
    is_fixed = models.BooleanField()

class MyModel(models.Model):
    ignore_field = models.Charfield(max_length=10)
    my_field = FixedField()

2. настраиваемые поля Моя мечта - создать настраиваемое поле, которое я мог бы использовать следующим образом:

class MyModel(models.Model):
    ignore_field = models.Charfield(max_length=10)
    my_field = FixableField(models.Charfield, max_length=30)

MyModel.objects.filter(is_fixed_my_field=True)
m = MyModel(my_field="foo")
print(m.is_fixed_my_field)  # False

Очевидно, что оно не работает с чем-то вроде

class FixableField:
    def __init__(self, model, field_class: models.Field, *args, **kwargs):
        setattr(model, f"is_fixed_{cannot_get_the_field_name}", models.BooleanField)
        field_class(*args, **kwargs)

потому что, насколько я понимаю, класс не был создан во время генерации миграции.

Возможен ли вообще мой сон?

Примечание1: Я использую postgres в фоновом режиме.

Примечание 2: В настоящее время я использую Django 1.11, но если решение работает только с более свежей версией, меня это тоже интересует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...