7

I am using Class-based Generic views Listview for listing all objects.

My views.py:

class PostsList(ListView):
    model = Post
    template_name = "index.html"

My Urls.py:

urlpatterns = [
    url(r'^$',PostsList.as_view(), name = "home"),
] 

This gives me a list of all the posts. Now I want to filter/sort posts based on certain fields of Post Model, say price. Do I need to write this myself? If yes Which method of PostsLists class do I override ? def get, def get_context ?

I see the get method for Listview defined as below. In it can I pass URL query-parameters as **kwargs directly or I have to overwrite the below method in my class.

def get(self, request, *args, **kwargs):
    ....

2 Answers 2

12

You can override the get_queryset method:

Keep a mapping of all the parameters that you can get in the url kwargs.

def get_queryset(self):
    queryset = Post.objects.all()

    if self.request.GET.get('price'):
        queryset = queryset.filter(price=self.request.GET.get('price'))
    return queryset
Sign up to request clarification or add additional context in comments.

4 Comments

It takes only one argument. You can check out the original code for get_queryset here. github.com/django/django/blob/master/django/views/generic/…
yes you are right . I added a request argument , later removed it . now It's working.
How do I access url query-parameters in backend ? self.request.GET.get is one way . Can I use self.args or self.kwargs
Depends on your url scheme. Say if your url is like: posts/<post_value>/, you can access the post_value in get_queryset like self.kwargs.get('post_value'). Thus, you can filter your queryset like queryset = queryset.filter(price=self.kwargs.get('price_value'))
6

When using Django's class based views, avoid overriding get() or post() if possible. These methods do a lot, and if you override them, you may have to duplicate a lot of the built in functionality. There are normally more specific methods that you can override.

In your case, you can filter the queryset dynamically with the get_queryset method. You can access GET parameters with self.request.GET. For example:

class PostsList(ListView):
    model = Post

    def get_queryset(self):
        """Filter by price if it is provided in GET parameters"""
        queryset = super(PostsList, self).get_queryset()
        if 'price' in self.request.GET:
            queryset = queryset.filter(price=self.request.GET['price'])
        return queryset

If your url captures arguments, you can access them with self.args (positional) and self.kwargs (name based).

See the docs on dynamic filtering for more info.

6 Comments

Also: you can access args and kwargs from URL using self.args and self.kwargs
Some error is coming : get_queryset() takes exactly 2 arguments (1 given)
First it says request object is not defined. So I put that as an argument in the def get_queryset(self, request) and then a new error is coming : get_queryset() takes exactly 2 arguments (1 given)
Also I'm logging logger.debug(self.kwargs), logger.debug(self.args) and in url im passing query parameters as ?title=1984 they are coming empty in logging.
It should be self.request, not request. I've fixed the code above. You should remove request from def get_request(self).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.