2

I have a django Listview and i am using django-el-pagination's ajax endless pagination to paginate my results and it works well. The problem is I need to apply some filters to it and have no clue on how to do it.

Can i send parameters through GET to the view? Have searched a lot and seems like no one had this problem before.

2 Answers2

1

Data is always returned in the get_queryset() function.

If you want to simply filter from the database, you can just return objects.

class IndexView(AjaxListView):
    template_name = '****'
    context_object_name = '****'
    page_template = '****'

    def get_queryset(self):
        return your_model.objects.filter(title='***').order_by('**')

Else if you want to get data from non-database, you need to implement a proxy accordding to this answer.

If not,the pagination ajax will request all data, then slice it.The proxy make your data sliced while querying.

This is my filter that getting data from ElasticSearch.

class IndexView(AjaxListView):
    template_name = '****'
    context_object_name = '****'
    page_template = '****'

        def get_queryset(self):
    params = {}
    # get query params
        for item in self.request.GET.items():
            if item[0] == 'page' or item[0] == 'querystring_key':
                continue
            params[item[0]] = item[1]

        # no filter
        if len(params) == 0:
            return ****.objects.filter().order_by('-date')

        else:
            return ESResult(params)

class ESResult(object):

    def __init__(self, params):
        self.params = params

    def __len__(self):
        s = self.search_es()
        if s:
            s = s[:1]
            r = s.execute()
            return r['hits']['total']
        else:
            return 0

    def __getitem__(self, item):
        assert isinstance(item, slice)
        result = []
        s = self.search_es()

        if s:
            s = s[item.start:item.stop]   # slice before querying
            r = s.execute()

            for a in r.to_dict()['hits']['hits']:
                one = a['_source']
                one['id'] = int(a['_id'])
                result.append(one)

        return result

    def search_es():
        ...
        # filter request here
        ...
Taosky
  • 11
  • 5
-1

The list object used by AjaxListView is defined by get_queryset() method. To filter the queryset based on the users input, you may refer to POST method:

from app.forms import BlogFilterForm

class Blog(LoginRequiredMixin, AjaxListView):
    context_object_name = "posts"
    template_name = 'blog/blog.html'
    page_template = 'blog/post_list.html'
    success_url = '/blog'

    def get_queryset(self): # define queryset
        queryset = Post.objects.all() # default queryset
        if self.request.method == 'POST': # check if the request method is POST
            form = BlogFilterForm(self.request.POST) # define form
            if form.is_valid(): 
                name = form.cleaned_data['name'] # retrieve data from the form
                if name:
                    queryset = queryset.filter(name=name) # filter queryset
        else:
            queryset = queryset
        return queryset 

    def get_context_data(self, **kwargs):
        context = super(Blog, self).get_context_data(**kwargs)
        context['form'] = BlogFilterForm() # define context to render the form on GET method
        return context

    def post(self, request, *args, **kwargs): # define post method
        return super(Blog, self).get(request, args, kwargs)

The endless pagination should work fine. using filters with django-endless-pagination

Community
  • 1
  • 1
bilbohhh
  • 479
  • 5
  • 11