Набор запросов Django на основе типа ввода - PullRequest
0 голосов
/ 10 мая 2018

на Django 1.9, у меня есть форма, которая позволяет пользователю фильтровать модели на основе их ввода:

def get_queryset(self):
        cvs = Clean.objects.all()
        query = self.request.GET.get('q')

        if query:
            cvs = cvs.filter(Q(cvscore__gte=query)).distinct()
            cvs = cvs.order_by('cvscore')            
        return cvs

Я хочу, чтобы они также могли искать строку и попытались:

cvs = cvs.filter(Q(cvscore__gte=query) | Q(cv__icontains=query)).distinct()

Проблема в том, что если на входе указан str, будет выдано сообщение об ошибке:

invalid literal for int() with base 10: 

Есть ли способ обойти это? Что-то вроде:

def get_queryset(self):
        cvs = Clean.objects.all()
        query = self.request.GET.get('q')

        if query **is an integer**:
            cvs = cvs.filter(Q(cvscore__gte=query)).distinct()
            cvs = cvs.order_by('cvscore')
        else:
            cvs = cvs.filter(Q(cv__icontains=query)).distinct()

        return cvs

Ответы [ 4 ]

0 голосов
/ 10 мая 2018

Внутри запроса все string. Итак, вы должны рассмотреть возможность использования isdigit():
Этот метод возвращает значение true, если все символы в строке являются цифрами и имеется хотя бы один символ, в противном случае - значение false. Подробнее

query = self.request.GET.get('q','') # Note this .get('q','')
if query.isdigit(): # i.e '31231' as string, will be True
   cvs = cvs.filter(Q(cvscore__gte=int(query))).distinct()
   cvs = cvs.order_by('cvscore')
else:
   cvs = cvs.filter(Q(cv__icontains=query)).distinct()
0 голосов
/ 10 мая 2018

Вы можете попробовать что-то вроде этого:

def get_queryset(self):
    cvs = Clean.objects.all()
    query = self.request.GET.get('q')

    cvs = cvs.filter(cv__icontains=query)

    try:
        cvs = cvs.filter(cvscore__gte=query).order_by('cvscore')
    except ValueError:
        # no additional filtering is done if 'query' cannot be coerced to a number
        pass

    cvs = cvs.distinct()
    return cvs
0 голосов
/ 10 мая 2018

Как насчет

def get_queryset(self):
    cvs = Clean.objects.all()
    query = self.request.GET.get('q')
    try:
        cvs = cvs.filter(Q(cvscore__gte=int(query))).distinct()
        cvs = cvs.order_by('cvscore')
    except ValueError:
        cvs = cvs.filter(Q(cv__icontains=query)).distinct()

    return cvs
0 голосов
/ 10 мая 2018

Вы можете проверить это при построении запроса:

expression = Q()
if query.isdigit():
    expression |= Q(cvscore__gte=query)
else:
    expression |= Q(cv__icontains=query)

cvs = cvs.filter(expression).distinct()
...