Django: Admin - результаты заказа на основе регулярного выражения - PullRequest
0 голосов
/ 02 марта 2020

У меня проблема с тем, что я хочу упорядочить строки модели в Django admin на основе числа в строке и игнорировать буквы - как XX0345XX, X0346XXX, XXX0347XX. Я думаю, что я должен использовать регулярное выражение для этого. У меня есть запрос SQL (PostgreSQL), который возвращает то, что я хочу:

select * from mytable order by substring(my_field, '\d+')::int DESC

Но у меня возникают проблемы с его применением, чтобы получить тот же результат в Django admin get_queryset(). Я пытался сделать что-то вроде:

def get_queryset():
    return Model.objects.raw("select * from mytable order by substring(my_field, '\d+')::int DESC")

, но проблема в том, что я не возвращаю правильный тип таким способом. Model.objects.raw('...') возвращает RawQuerySet, но get_queryset() должен возвращать QuerySet экземпляр, а не RawQuerySet один, поэтому я не могу сделать это таким образом.

Есть предложения, как решить эту проблему? Спасибо!

Ответы [ 2 ]

0 голосов
/ 03 марта 2020

Как указал @ Azy_Crw4282, вы можете использовать QuerySet.extra() для выполнения необработанных SQL запросов и по-прежнему возвращать результаты в виде QuerySet экземпляра.

Вот как мне удалось сделать регулярное выражение на основе "ORDER BY" на объектах в представлении администратора, на основе числа в строке. Т.е. поля заказа, такие как XX0345XX, X0346XXX, XXX0347XX, основаны на числе, которое они содержат - в основном получают подстроку, которая соответствует регулярному выражению '\d+'.

Просто переопределите функцию get_queryset() в вашем классе admin.ModelAdmin.

Решение:

def get_queryset(self, request):
    sql_query = "CAST(substring(booking_reference, '\d+') as int)"
    bookings = Booking.objects.extra(select={'book_ref_digits': sql_query}).order_by('-book_ref_digits')
    return bookings

Насколько я понимаю, он добавляет новое временное поле, например, book_ref_digits в объекте QuerySet, и тогда вы можете сделать .order_by() на этом.

Примечание. Использование более старой версии Django 1.10.5

0 голосов
/ 02 марта 2020

Вы можете использовать метод .extra () для преобразования из набора rawquery в набор запросов, см. здесь

Этот пример взят из здесь

class CustomManager(manager.Manager):
    def get_queryset():
        qs = self.get_queryset()
        sql = "myapp_model_b.id IN (SELECT UNNEST(myapp_model_a.pk_values) FROM myapp_model_a WHERE myapp_model_a.id='%s')" % index_id
        return qs.extra(where=[sql])
...