Coderaemon
Coderaemon

Reputation: 3867

Filtering Objects in Class based view Django using Query parameters?

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):
    ....

Upvotes: 7

Views: 10822

Answers (2)

Alasdair
Alasdair

Reputation: 308779

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.

Upvotes: 6

Animesh Sharma
Animesh Sharma

Reputation: 3386

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

Upvotes: 12

Related Questions