Фиксированные значения в models django
Пытаюсь сделать модель, которая бы смогла бы при деплое на сервер, сохранить список который я задал. Но при этом, что бы у пользователя, была возможность добавлять туда свои значения. А так же, что бы пользователь не мог изменить мой заданный список.
models.py
from django.db import models
PRIORITY_CHOICES = ((1, 'High'),
(2, 'Medium'),
(3, 'Low'))
class MyModel(models.Model):
priority = models.IntegerField(choices=PRIORITY_CHOICES)
view.py
class MyModelCreate(generics.CreateAPIView):
authentication_classes = [SessionAuthentication, BasicAuthentication]
permission_classes = [IsAuthenticated]
serializer_class = MyModelSerializer
serializer.py
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = [
'priority',
]
В drf всё отображается корректно , но ввести свой вариант нельзя. Это нужно создавать ещё одну модель, и через неё переопределять MyModel ?
Ответы (1 шт):
Если читать документацию, по Django относительно параметра choices, там есть такой замечательный абзац:
Note that choices can be any sequence object – not necessarily a list or tuple. This lets you construct choices dynamically. But if you find yourself hacking choices to be dynamic, you’re probably better off using a proper database table with a ForeignKey. choices is meant for static data that doesn’t change much, if ever.
Если пересказать суть:
Значение параметра choices может быть любым объектом последовательности, не обязательно list или tuple (самому не приходилось разбираться, поди, речь про генераторы или о чем-то таком, что делает чувак из enSO). Однако, скорее всего, такой путь будет признан грязным хаком и лучше использовать надлежащим образом внешний ключ. choices был задуман только для данных, которые изменяются не чаще, чем никогда.
Как грамотный путь будет выглядеть в контексте примера кода из вопроса:
from django.db import models
class Priority(models.Model):
# Таблицу экземпляров этой модели надо предзаполнить, это можно сделать в файле миграции
# Придется предусмотреть логику, чтобы предзаполненные элементы нельзя было изменять/удалять кому ни попадя
level = models.IntegerField() # 1,2,3...
name = models.IntegerField() # High, Medium, Low...
class MyModel(models.Model):
priority = models.ForeignKey(Priority, on_delete=models.CASCADE)