Reputation: 1260
I have a hard time using Enums in Django.
This is my Request model:
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)
There is a difference when I create the record with string, or the enum type, which is really annoying...
This works just fine:
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
But this throws an exception
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
When I try to filter with status=RequestStatuses.sent.value
or just with sent
string the first example throws an exception and second works.
What is the point of enums, when you can't filter them by string or vice versa? How can I make it work with api - which will pass string to a filter? Or is it just some cache issue?
Upvotes: 4
Views: 4588
Reputation: 11
In Request model you you need to modify definition of "status"
status = models.CharField(
max_length=31,
choices= RequestStatuses.choices(),
default=RequestStatuses.new.value
)
Then you may filter following way.
request = Request.objects.filter(status=RequestStatuses.new.name)
Upvotes: 1
Reputation: 1260
I honestly don't know the reason why and whether it is allright to do this, but adding __repr__
and __str__
functions to the enum resolved the issue.
class RequestStatuses(Enum):
new = 'new'
sent = 'sent'
done = 'done'
def __repr__(self):
return self.name
def __str__(self):
return self.name
Upvotes: 0