2017-02-14 12 views
0

Моя проблема в том, что я должен запрашивать базу данных для пользователей, для некоторых полей, которые des, gender, min_age, max_age. Когда я использовал несколько значений, он работал нормально, используя filter_queryset. И затем я использовал несколько значений для gender, но он не включает в себя gender в моем URL-адресе, потому что код split не работает. Итак, я думал, используя несколько if/else, которые будут иметь разные queryset.filter(des__in=[], gender__in=[]) или gender недоступны, тогда запрос ->queryset.filter(des__in=[]). Мне здесь не хватает многих вещей. пожалуйста, помогитене могу понять, правильный способ реализации Django Фильтры

API - /v1/users/query_users?des=1,2&gender=Male,Female&min_age=2&max_age=4

class ProductFilter(django_filters.rest_framework.FilterSet): 
    min_age = django_filters.DateRangeFilter(name="dob", lookup_expr="gte") 
    max_age = django_filters.DateRangeFilter(name="dob", lookup_expr="lte") 
    class Meta: 
     model = UserProfile 
     fields = ['des', 'gender', 'min_age', 'max_age'] 


class QueryUserGroup(generics.ListAPIView): 
    queryset = UserProfile.objects.all() 
    serializer_class = UserProfileSerializer 
    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,) 
    filter_class = ProductFilter 
    permission_classes = [permissions.IsAuthenticatedOrReadOnly] 

    def filter_queryset(self, queryset): 
     des_list = self.request.GET.getlist("des") 
     gender_list = self.request.GET.getlist("gender") 
     des_ids = des_list[0].split(',') 
     gender_ids = gender_list[0].split(',') 
     return queryset.filter(des__in=des_ids, gender__in=gender_ids) 

    def list(self, request, *args, **kwargs): 
     queryset = self.filter_queryset(self.get_queryset()) 
     serializer = UserProfileSerializer(queryset, many=True) 
     return JSONResponse({'data': serializer.data}, status=HTTP_200_OK) 

ответ

1

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

Поскольку вы получаете доступ к первому элементу в списке, вы можете использовать get вместо getlist.

def filter_queryset(self, queryset): 
    des = self.request.GET.get("des") 
    if des is not None: 
     des_ids = des.split(',') 
     queryset = queryset.filter(des__in=des_ids) 

    gender = self.request.GET.get("gender") 
    if gender is not None: 
     gender_ids = gender.split(',') 
     queryset = queryset.filter(gender__in=gender_ids) 

    return queryset 

Если у вас более двух полей, вы могли бы сократить дублированный код, пробегает по списку имен полей:

def filter_queryset(self, queryset): 
    for fieldname in ("des", "gender"): 
     value = self.request.GET.get(fieldname) 
     if value is not None: 
      ids = value.split(',') 
      queryset = queryset.filter(**{'%s__in' % fieldname: ids}) 

    return queryset 
+0

Awesome! благодаря –