#python #django #enums
#python #django #перечисления
Вопрос:
Мне трудно использовать перечисления в Django.
Это моя модель запроса:
class RequestStatuses(Enum):
new = 'new'
sent = 'sent'
done = 'done'
class Request(BaseModel):
request_number = models.PositiveIntegerField(default=0)
type = models.CharField(max_length=31, blank=True, null=True)
status = models.CharField(
max_length=31,
choices=[(a.name, a.value) for a in RequestStatuses],
default=RequestStatuses.new
)
sensor = models.ForeignKey(Sensor, on_delete=models.SET_NULL, blank=True, null=True)
device = models.ForeignKey(Device, on_delete=models.SET_NULL, blank=True, null=True)
user = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True)
payload = models.TextField(blank=True, null=True)
Есть разница, когда я создаю запись с использованием string или типа enum, что действительно раздражает…
Это работает просто отлично:
device = Device.objects.create(serial_number=1)
request = Request(
device=self.device,
status=RequestStatuses.sent
)
request.save()
try:
request = device.request_set.filter(
status=RequestStatuses.sent
)[0]
except IndexError:
print(device.request_set.all()[0].status)
pass
Но это вызывает исключение
device = Device.objects.create(serial_number=1)
request = Request(
device=device,
status='sent'
)
request.save()
try:
request = device.request_set.filter(
status=RequestStatuses.sent
)[0]
except IndexError:
print(device.request_set.all()[0].status)
pass
Когда я пытаюсь фильтровать с помощью status=RequestStatuses.sent.value
или просто с помощью sent
string, первый пример выдает исключение, а второй работает.
В чем смысл перечислений, когда вы не можете фильтровать их по строке или наоборот? Как я могу заставить это работать с api, который будет передавать строку в фильтр? Или это просто какая-то проблема с кэшем?
Ответ №1:
В модели запроса вам нужно изменить определение «статуса»
status = models.CharField(
max_length=31,
choices= RequestStatuses.choices(),
default=RequestStatuses.new.value
)
Затем вы можете фильтровать следующим образом.
request = Request.objects.filter(status=RequestStatuses.new.name)
Ответ №2:
Я, честно говоря, не знаю причину, почему и правильно ли это делать, но добавление функций __repr__
и __str__
в перечисление решило проблему.
class RequestStatuses(Enum):
new = 'new'
sent = 'sent'
done = 'done'
def __repr__(self):
return self.name
def __str__(self):
return self.name