Django: Использование словарей в качестве значений для models.Choices
Я пытаюсь сохранить в базе данных периодичность, которая состоит из суммы (например, 2) и единицы измерения (например, месяцы). Пользователю также должен быть предоставлен выбор. Идея состоит в том, чтобы передать это классу, который может использовать эту информацию для вычисления частоты (похоже, но не совсем timedelta
, однако это выходит за рамки данного вопроса).
Я подумал, что было бы здорово сохранить эту информацию в виде диктанта в поле JSONField, а при программном извлечении передать ее прямо моему CustomFrequencyClass
, отвечающему за вычисления.
Ошибка, которую я неизменно получаю, - TypeError: unhashable type: 'dict'
. Или, если я передаю значения в виде кортежей, он скажет мне (fields.E005) 'choices' must be an iterable containing (actual value, human readable name) tuples.
class CustomFrequencyClass:
def __init__(self, *args, **kwargs):
pass
class Report(models.Model):
class ReportFrequency(CustomFrequencyClass, models.Choices):
DAILY = {"days": 1}, "Daily"
WEEKLY = {"days": 7}, "Weekly"
frequency = models.JSONField(choices=ReportFrequency.choices, default=ReportFrequency.DAILY)
Если вы работаете с choices=…
[Django-doc], Django построит словарь за шторками, чтобы сопоставить значения с текстовым представлением, поэтому в данном случае {'days': 1}
- 'Daily'
, так как ключи словаря должны быть хэшируемыми, а словарь не может быть хэшируемым, так как он может быть изменен, поэтому он не работает.
Однако мы можем обернуть словарь в frozendict
[pypi.org], что позволит хэшировать его, но, конечно, под обещанием, что словарь больше не будет обновляться.
from frozendict import frozendict
class Report(models.Model):
class ReportFrequency(models.Choices):
DAILY = frozendict({'days': 1}), 'Daily'
WEEKLY = frozendict({'days': 7}), 'Weekly'
frequency = models.JSONField(
choices=ReportFrequency.choices, default=ReportFrequency.DAILY
)