У меня есть модели со многими полями. Для большого количества этих полей (скажем, около 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, но если решение работает только с более свежей версией, меня это тоже интересует.