Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering Objects in Class based view Django using Query parameters?

Tags:

python

django

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):
    ....
like image 912
Coderaemon Avatar asked Aug 12 '15 08:08

Coderaemon


People also ask

Can I filter a Queryset Django?

With the Django QuerySet class, you can apply filters that return QuerySets defined by your filters. The filter() method returns all objects that match the keyword arguments given to the method.

What is the purpose of filter () method in Django?

The filter() method is used to filter you search, and allows you to return only the rows that matches the search term.

How do I filter Queryset in Django REST framework?

The simplest way to filter the queryset of any view that subclasses GenericAPIView is to override the . get_queryset() method. Overriding this method allows you to customize the queryset returned by the view in a number of different ways.


2 Answers

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
like image 111
Animesh Sharma Avatar answered Oct 26 '22 22:10

Animesh Sharma


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.

like image 29
Alasdair Avatar answered Oct 27 '22 00:10

Alasdair