как условно добавить поля фильтра и значение в Django - PullRequest
1 голос
/ 06 января 2020

Рассмотрим приведенный ниже пример модели.

class Server(models.Model):
    os = models.CharField(max_length=30)
    server_owner = models.CharField(max_length=30)
    server_located = models.CharField(max_length=20)
    server_name = models.CharField(max_length=20)
    ...
    ...

В будущем у этой модели будет больше полей.

Так что из запроса я получу список значений, которые мне нужны фильтр. Рассмотрим приведенные ниже примеры данных.

os_list = ["Windows", "Linux", "Mac"]
server_owner_list = ["John", "Will", "Jake", "Shyam"],
server_located = ["India", "USA"]
server_name = []
...
...
...

Я хочу исключить пустые списки. В приведенном выше примере имя_сервера является пустым списком. Поэтому при фильтрации по модели сервера я хочу добавить os_list, server_owner_list и server_located и исключить имя_сервера. В будущем в модель БД будут добавлены дополнительные поля, и я мог бы получить дополнительный список значений из запроса клиента. который может иметь пустой список массивов. Поэтому я не хочу писать кучу условий if-else, чтобы проверить, какие списки пусты и не пусты.

Может кто-нибудь помочь мне, как написать для этого масштабируемый ORM.

Редактировать:

поэтому из таблицы реакции внешнего интерфейса я буду использовать фильтрацию столбцов. из раскрывающегося списка столбцов, если пользователь выбирает данные из раскрывающегося списка столбцов, выбранные данные будут там в формате массива. Если пользователь сбрасывает данные, которые он выбрал ранее, будет пустой массив. поэтому, когда пользователь нажимает фильтр, данные передаются в бэкэнд.

Итак, в бэкэнде я получаю пустой список массивов. Так что если

os_filter_val = request.query_params.getlist('osFilter[]')
server_owner_list = request.query_params.getlist('serverOwnerFilter[]')      
Server.Objects.filter(
                os__in=os_filter_val,
                server_owner__in=server_owner_list)

Так что в приведенном выше примере рассмотрите для server_owner_list Я получил пустой массив, и я не хочу включать его в набор запросов фильтра, что я обычно делаю, это.

if len(os_filter_val) > 0 and len(server_owner_list) > 0:
    Server.Objects.filter(
                os__in=os_filter_val,
                server_owner__in=server_owner_list)
else if(os_filter_val) > 0 and len(server_ownder_list) == 0:
    Server.Objects.filter(os__in=os_filter_val)
....
....
....

Так вот, если полей больше, мне нужно написать много условий if-else, чтобы проверить, есть ли какие-нибудь пустые списки. Если его нет, не включайте его в набор запросов.

Так есть ли способ проверить пустой список и добавить только непустые списки без записи условий if-else.

Ответы [ 2 ]

1 голос
/ 06 января 2020

Попробуйте этот код. Измените ИЛИ и И согласно вашему требованию, а также добавьте условие if в параметры вашего URL.

from django.db.models import Q
    os_filter_val = request.query_params.getlist('osFilter[]')
        server_owner_list = request.query_params.getlist('serverOwnerFilter[]')
        q_objects = Q()
        if os_filter_val:
            q_objects.add(Q(os__in=os_filter_val), Q.OR)
        if server_owner_list:
            q_objects.add(Q(server_owner__in=server_owner_list), Q.OR)
        Server.Objects.filter(q_objects,)
1 голос
/ 06 января 2020

Для фильтрации вообще рекомендую Django -Фильтры . Это спасет вас от многих других условий. Для спецификационного фильтра c in вы можете написать собственный класс фильтра:

from rest_framework import generics
from django_filters import rest_framework as filters
from myapp import Server


class ServerFilter(filters.FilterSet):
    osFilter = filters.NumberFilter(field_name="id", lookup_expr='in')

    class Meta:
        model = Server
        fields = ['osFilter',]


class ServerList(generics.ListAPIView):
    queryset = Server.objects.all()
    serializer_class = ServerSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_class = ServerFilter

Но кроме того, я рекомендую вам прочитать о некоторых советах с нулями и диапазонами и базовая фильтрация

...