Django: как хранить несколько типов данных в одном поле модели
Я хочу создать модель базы данных, несколько похожую на приведенный ниже пример:
Идея заключается в том, что пользователь (или любая модель) может иметь несколько различных характеристик (или чего угодно) с различными значениями. Характеристика может быть чем угодно, например, целым числом (зарплата), датой (дата рождения) или множественным выбором (компетенции, например, C, Python и т.д.). Чтобы сохранить простой дизайн базы данных, я попробовал подход, при котором у меня есть только одна таблица Feature, которая имеет опциональные варианты выбора через таблицу Choice, вместо того, чтобы иметь отдельную таблицу базы данных для каждого типа характеристик. Выбор пользователем значения характеристики хранится в поле "значение" таблицы User_has_Feature, которое представляет собой поле CharField, которое может хранить несколько различных типов данных, таких как целое число, дата, выбор, множественный выбор и т.д.
Мой вопрос в том, как я могу проверить все данные так, чтобы они проверялись на соответствие типу данных поля, а также правильно отображались в админке или UI (имея разные виджеты UI для разных типов)?
Я пробовал подход, при котором я храню тип поля для каждой функции в таблице Field, которая может быть CharField, IntegerField, DateField и т.д. Затем в User_has_Feature model clean() я могу динамически проверять тип поля, например:
FIELDS = {
'DateField': DateField,
'IntegerField': IntegerField,
etc.
}
def clean(self):
class_ = FIELDS.get(self.feature.field)
if class_ in [DateField, IntegerField, ...]:
field = class_()
field.clean(self.value)
elif class_ in [ModelChoiceField, ModelMultipleChoiceField]:
etc.
Этот подход отлично работает для валидации, но он не помогает для виджетов администратора, а также данные всегда перемещаются как строка, вместо целого числа, даты, списка и т.д.. Поэтому я начал исследовать возможность создания пользовательского поля модели ValueField, которое наследует CharField, и будет хранить все данные как строку в базе данных, но будет динамически менять виджет и тип данных (to_python) для значения. Пока что успеха нет, все, что я пробую, кажется, слишком сложным.
Для меня это кажется довольно распространенной потребностью, поэтому я ожидаю, что какое-то "простое" решение уже существует. Или тогда мне нужно попробовать другой подход к проектированию базы данных вообще.
Вы можете использовать Django Content Types Framework docs
Основная идея заключается в том, что вы можете создавать специальные классы (модели) для ваших функций, а CTF может помочь вам связать функции с Пользователем (в вашем случае). Я использую это для привязки различных моделей к модели Logging, и каждый экземпляр logging содержит прямую ссылку на нужный экземпляр модели, который он регистрирует