У меня довольно сложный запрос, который генерирует Django RawQuerySet
. Этот конкретный запрос возвращает некоторые поля, которые не являются частью модели, на которой основан RawQuerySet
, поэтому я использую .annotate(field_name=models.Value('field_name'))
, чтобы прикрепить его в качестве атрибута к отдельным записям в RawQuerySet
. Наиболее важным настраиваемым полем на самом деле является uuid
, которое я использую для составления URL-адресов с использованием функциональности Django {% url %}
.
Вот проблема: я не использую стандартные uuid
s внутри своего приложения, я использую SmallUUIDs (сжатые UUID.) Они сохраняются в базе данных как собственные uuidfield
s преобразован в более короткие строки в Python. Поэтому мне нужно каким-то образом преобразовать uuid
, возвращенный как часть RawQuerySet
, в SmallUUID
для использования внутри шаблона для генерации URL.
Мой код выглядит примерно так:
query = "SELECT othertable.uuid_field as my_uuid FROM myapp_mymodel
JOIN othertable o ON myapp_mymodel.x = othertable.x"
MyModel.objects.annotate(
my_uuid=models.Value('my_uuid'),
).raw(query)
Теперь здесь есть логическое решение, есть дополнительный kwarg для models.Value
, называемый output_field
, благодаря которому код выглядит следующим образом:
MyModel.objects.annotate(
my_uuid=models.Value('my_uuid', output_field=SmallUUIDField()),
).raw(query)
Но это не работает! Этот kwarg полностью игнорируется, и тип атрибута основан на типе, возвращаемом из базы данных, а не на том, что в output_field
. В моем случае я получаю вывод uuid
, потому что Postgres возвращает тип UUID, но если бы я изменил запрос на SELECT cast othertable.uuid_field as text) as my_uuid
, я бы получил атрибут в формате строки. Похоже, что Django (по крайней мере, версия 1.11.12) на самом деле не волнует, что находится в этом kwarg в этом случае.
Итак, вот что я думаю, это мои потенциальные решения в произвольном порядке:
- Изменить способ форматирования запроса (в Django или в SQL)
- Как-то изменить результирующий набор RawQuerySet, прежде чем он будет передан в представление
- Измените что-то внутри шаблонов, чтобы преобразовать UUID в smalluuid для использования в обратном процессе URL.
Каковы мои лучшие следующие шаги здесь?