Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 6, 2016 21:58:18

ganzhik
Зарегистрирован: 2015-07-13
Сообщения: 34
Репутация: +  0  -
Профиль   Отправить e-mail  

Django Rest Framework filter

Добрый вечер ув. Гуру. помогите разобраться с передачей аргументов в из url в обработчик!
есть модель

class PersonRankEveryday(models.Model):
class Meta:
db_table = 'db_personrank_everyday'

"""
Рейтинг ежедневной статистики.
"""
sites = models.ForeignKey(Sites)
persons = models.ForeignKey(Persons)
rank_day = models.IntegerField(default=0)
data_scan = models.DateField(verbose_name=u'Дата последнего сканирования')

и сериализатор
class PersonRankEverydaySerializer(serializers.HyperlinkedModelSerializer):
site_name = serializers.SerializerMethodField('get_site')
person_name = serializers.SerializerMethodField('get_person')

def get_site(self, keyword):
return str(keyword.sites)

def get_person(self, keyword):
return str(keyword.persons)

class Meta:
model = PersonRankEveryday
fields = ('site_name', 'person_name', 'rank_day', 'data_scan')
url.py
router = DefaultRouter()
router.register(r'rankeveryday', views.PersonRankEverydayViewSet, base_name='PersonRankEverydey')
которая обрабатывает GET http://crawler***********/api/v1/rankeveryday/1/
и получаем json
[{"site_name":"lenta.ru","person_name":"****","rank_day":156,"data_scan":"2016-02-01"},{"site_name":"lenta.ru","person_name":"*****","rank_day":101,"data_scan":"2016-02-01"},{"site_name":"lenta.ru","person_name":"*****i","rank_day":88,"data_scan":"2016-02-01"},{"site_name":"lenta.ru","person_name":"*****","rank_day":134,"data_scan":"2016-02-02"}]
убрал имена воизбежания не нужных реплик
есть сканирование за месяц к примеру надо выбрать по определённому сайту за определенный промежуток времени. Помогите разобраться как сформировать url и передать аргументы во вьюху чтоб отсортировать по нужным датам
вот собственно вьюха
class PersonRankEverydayViewSet(viewsets.ModelViewSet):

"""
A simple ViewSet for Listing or retrieving personrankeveryday.

"""
def list(self, request):
queryset = PersonRankEveryday.objects.all()
serializer = PersonRankEverydaySerializer(queryset, many=True)
return Response(serializer.data)

def retrieve(self, request , pk=None, format=None):
queryset = PersonRankEveryday.objects.filter(sites_id=pk)
serializer = PersonRankEverydaySerializer(queryset, many=True)
return Response(serializer.data)

полный лист и по id json выдается нормально можно использовать filter но он дает возможность отфильтровать по одной дат, а хотелось получить срез по n-количеству дат в промежутке времени как эти даты получить в во вьюхе

Отредактировано ganzhik (Фев. 6, 2016 21:59:27)

Офлайн

#2 Фев. 7, 2016 07:49:33

ayb
Зарегистрирован: 2014-04-01
Сообщения: 297
Репутация: +  24  -
Профиль   Отправить e-mail  

Django Rest Framework filter

1. pip install django-filters==0.2.1
2. Пишешь фильтр с кастомным методом

def date_range_filter(queryset, value):
    return queryset.filter(date__range[value.split(",")])
Сам фильтр :
class YourCoolFilter(django_filters.FilterSet):
    dt_range = django_filters.MethodFilter(action=date_range_filter)
    class Meta:
        model = YourModel
        fields = ("dt_range", ) 
3. Во вьюсете указываешь
filter_backends = (filters.DjangoFilterBackend, )
filter_class = YourCoolFilter

Даты соответственно передавай как-то так : ?dt_range=10.10.2010,11.11.2011

А вообще можно даже проще, если тебе нужно фильтровать только по датам, добавь в метод
if self.request.query_params.get("dt_range"):
    min_, max_ = self.request.query_params.get("dt_range").split(",")
    queryset = queryset.filter(data_scan__range[min_, max_])

Отредактировано ayb (Фев. 7, 2016 11:25:48)

Офлайн

#3 Фев. 7, 2016 13:15:16

ganzhik
Зарегистрирован: 2015-07-13
Сообщения: 34
Репутация: +  0  -
Профиль   Отправить e-mail  

Django Rest Framework filter

Сформировал такой url

http://crawler.**********/api/v1/rankeveryday/1/?dt_range=2016-02-01,2016-02-04

class PersonRankEverydayViewSet(viewsets.ModelViewSet):

"""
A simple ViewSet for Listing or retrieving personrankeveryday.

"""
def list(self, request):
queryset = PersonRankEveryday.objects.all()
serializer = PersonRankEverydaySerializer(queryset, many=True)
return Response(serializer.data)

def retrieve(self, request , pk=None):
queryset = PersonRankEveryday.objects.filter(sites_id=pk)
filter_backends = (filters.DjangoFilterBackend,)
filter_class = CrawlerFilter
serializer = PersonRankEverydaySerializer(queryset, many=True)
return Response(serializer.data)
ормсал филтер
def date_range_filter(queryset, value):
return queryset.filter(date__range[value.split(",")])


class CrawlerFilter(django_filters.FilterSet):
dt_range = django_filters.MethodFilter(action=date_range_filter)
class Meta:
model = PersonRankEveryday
fields = ('dt_range',)
Ошибок нет но и фильтер не срабатывает! может во вьюсете не там прописал в сериализатор передается переменная queryset а там вроде как PersonRankEveryday.objects.filter(sites_id=pk) а кка в сериализатор загнать данныепосле фильтра?

Офлайн

#4 Фев. 7, 2016 13:45:08

ayb
Зарегистрирован: 2014-04-01
Сообщения: 297
Репутация: +  24  -
Профиль   Отправить e-mail  

Django Rest Framework filter

filter_class и filter_backends должны быть в атрибутах вьюсета

Офлайн

#5 Фев. 7, 2016 13:57:30

ganzhik
Зарегистрирован: 2015-07-13
Сообщения: 34
Репутация: +  0  -
Профиль   Отправить e-mail  

Django Rest Framework filter

я понимаю так должно быть пробывал и так до фильтра не доходит все заканчивается в Retrieve

class PersonRankEverydayViewSet(viewsets.ModelViewSet):

"""
A simple ViewSet for Listing or retrieving personrankeveryday.

"""
def list(self, request):
queryset = PersonRankEveryday.objects.all()
serializer = PersonRankEverydaySerializer(queryset, many=True)
return Response(serializer.data)

def retrieve(self, request , pk=None):
queryset = PersonRankEveryday.objects.filter(sites_id=pk)
serializer = PersonRankEverydaySerializer(queryset, many=True)
return Response(serializer.data)

filter_backends = (filters.DjangoFilterBackend,)
filter_class = CrawlerFilter

Офлайн

#6 Фев. 7, 2016 14:11:59

ayb
Зарегистрирован: 2014-04-01
Сообщения: 297
Репутация: +  24  -
Профиль   Отправить e-mail  

Django Rest Framework filter

Значит фильтруй в методе:

def retrieve(self, request , pk=None):
        queryset = PersonRankEveryday.objects.filter(sites_id=pk)
        if self.request.query_params.get("dt_range"):
            min_, max_ = self.request.query_params.get("dt_range").split(",")
            queryset = queryset.filter(data_scan__range[min_, max_])
        serializer = PersonRankEverydaySerializer(queryset, many=True)
        return Response(serializer.data)

Офлайн

#7 Фев. 7, 2016 14:39:58

ganzhik
Зарегистрирован: 2015-07-13
Сообщения: 34
Репутация: +  0  -
Профиль   Отправить e-mail  

Django Rest Framework filter

Респект Уважуха) вообщем спасибки большое!!
queryset = queryset.filter(data_scan__range) немного подправил
queryset = queryset.filter(data_scan__rangemin_, max_)) так заработало а так все гуд! плюсик в копилку

Офлайн

#8 Фев. 7, 2016 14:41:46

ganzhik
Зарегистрирован: 2015-07-13
Сообщения: 34
Репутация: +  0  -
Профиль   Отправить e-mail  

Django Rest Framework filter

queryset = queryset.filter(data_scan__range[min_, max_]) 
queryset = queryset.filter(data_scan__range=(min_, max_))
подправил еще раз спасибо

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version