<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Eugene-Kwaka</title>
    <description>The latest articles on DEV Community by Eugene-Kwaka (@eugenekwaka).</description>
    <link>https://dev.to/eugenekwaka</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F580986%2F5c644dc4-6443-477b-bd0a-17e743b20c2d.jpg</url>
      <title>DEV Community: Eugene-Kwaka</title>
      <link>https://dev.to/eugenekwaka</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eugenekwaka"/>
    <language>en</language>
    <item>
      <title>How to filter querysets using django-filter package</title>
      <dc:creator>Eugene-Kwaka</dc:creator>
      <pubDate>Wed, 16 Feb 2022 15:21:57 +0000</pubDate>
      <link>https://dev.to/eugenekwaka/how-to-filter-querysets-using-django-filter-package-5058</link>
      <guid>https://dev.to/eugenekwaka/how-to-filter-querysets-using-django-filter-package-5058</guid>
      <description>&lt;p&gt;While recently working on a personal Django project, I applied a search filter functionality by using the django-filter package. Django filter is a popular package that filters a queryset and displays the search results based on the model’s attributes. &lt;/p&gt;

&lt;p&gt;In this article, I will guide you on how to apply the filter functionality in your project. To explain how the package works, I will create a basic Django web project with a model that will apply our filter. Follow up on each step carefully.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;strong&gt;Setup Working Environment and Create Django Project&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Firstly, you have to create a directory for your project and get inside the directory. The directory is where your project and your environment will be in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir myproject 
$ cd myproject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create a virtual environment (venv) to store the project's dependencies using the &lt;strong&gt;py -m venv yourenvname&lt;/strong&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ py -m venv yourenvname
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have to activate the virtual environment. You'll need to activate the venv each time you open the command prompt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yourenvname\scripts\activate.bat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the venv, you then install django.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pip install django
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create the project in our directory using django we've just installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ django-admin startproject myproject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Move in to the project directory you have just created to run the server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd myproject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the server using the command below and then visit this url &lt;a href="http://127.0.0.1:8000/" rel="noopener noreferrer"&gt;http://127.0.0.1:8000/&lt;/a&gt;. You should see a Django Welcome Page to show you that the project was created successfully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ py manage.py runserver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Create an app for the project
&lt;/h2&gt;

&lt;p&gt;Now let's create an app for the project. In the command line, stop the server by pressing &lt;strong&gt;Control+c&lt;/strong&gt;. Then write the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ py manage.py startapp myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating the app, you have to add the app to the "&lt;strong&gt;INSTALLED_APPS&lt;/strong&gt;" list in the &lt;strong&gt;myproject/settings.py&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'myapp',
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Create the Model
&lt;/h2&gt;

&lt;p&gt;Let's create the model that we will use to implement the filter functionality. Name the model &lt;strong&gt;Order&lt;/strong&gt; and create it in the file &lt;strong&gt;myapp/models.py&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from django.db import models

class Order(models.Model):
    STATUS = (
        ('Pending', 'Pending'),
        ('Out for delivery', 'Out for delivery'),
        ('Delivered', 'Delivered'),
    )
    CATEGORY = (
        ('Indoor', 'Indoor'),
        ('Outdoor', 'Outdoor'),
    )
    product = models.CharField(max_length=100, null=True)
    category = models.CharField(max_length=100, null=True, 
    choices=CATEGORY)
    status = models.CharField(max_length=100, null=True, 
    choices=STATUS)
    date_created = models.DateTimeField(auto_now_add=True, 
    null=True)

    def __str__(self):
        return self.product
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the following commands, run the migrations to create a database based on the model above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ py manage.py makemigrations
$ py manage.py migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Register the model in the &lt;strong&gt;myapp/admin.py&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from django.contrib import admin
from .models import Order

# Register your models here.

admin.site.register(Order)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Define the views.
&lt;/h2&gt;

&lt;p&gt;Let's create a view function in the &lt;strong&gt;myapp/views.py&lt;/strong&gt; file. We have to import the Order model from models.py file. The function will retrieve the order objects from the Order model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from .models import Order

def index(request):
    orders = Order.objects.all().order_by('-date_created')
    context = {
            'orders': orders,
    }
    return render(request, 'index.html', context)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Create the url paths
&lt;/h2&gt;

&lt;p&gt;Now we need to configure our url paths. Within the app folder, create a new &lt;strong&gt;urls.py&lt;/strong&gt; file.&lt;br&gt;
&lt;em&gt;myapp/urls.py&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index)
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Projects with multiple apps are common. The apps need their own dedicated url paths. We then update the main project's &lt;strong&gt;myproject/urls.py&lt;/strong&gt; file to include the app's urls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('', include('myapp.urls')),
    path('admin/', admin.site.urls),
]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Create the Templates
&lt;/h2&gt;

&lt;p&gt;In the root folder, let's create a directory for our project's &lt;em&gt;HTML&lt;/em&gt; template file called &lt;strong&gt;index.html&lt;/strong&gt;. The filter form will be in this template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir templates
$ touch templates/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we must configure the &lt;strong&gt;myproject/settings.py&lt;/strong&gt; file to connect Django to our new template directory. Scroll through the file and change the settings in &lt;em&gt;TEMPLATES&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import os
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')], #new
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Write the following code in the &lt;em&gt;HTML&lt;/em&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        &amp;lt;h5&amp;gt;ORDERS:&amp;lt;/h5&amp;gt;
        &amp;lt;br&amp;gt;
        &amp;lt;div class="card card-body ml-3 mr-3"&amp;gt;
            &amp;lt;table class="table table-sm"&amp;gt;
                &amp;lt;tr&amp;gt;
                    &amp;lt;th&amp;gt;Product&amp;lt;/th&amp;gt;        
                    &amp;lt;th&amp;gt;Category&amp;lt;/th&amp;gt;
                    &amp;lt;th&amp;gt;Status&amp;lt;/th&amp;gt;
                    &amp;lt;th&amp;gt;Date Ordered&amp;lt;/th&amp;gt;
                &amp;lt;/tr&amp;gt;
                {% for order in orders %}
                &amp;lt;tr&amp;gt;
                    &amp;lt;td&amp;gt;{{ order.product }}&amp;lt;/td&amp;gt;
                    &amp;lt;td&amp;gt;{{ order.category }}&amp;lt;/td&amp;gt;
                    &amp;lt;td&amp;gt;{{ order.status }}&amp;lt;/td&amp;gt;
                    &amp;lt;td&amp;gt;{{ order.date_created}}&amp;lt;/td&amp;gt;
                &amp;lt;/tr&amp;gt;
                {% endfor %}
            &amp;lt;/table&amp;gt;
        &amp;lt;/div&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create a superuser who will login to the admin page and add data that will be rendered in the template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python manage.py createsuperuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The html template will display data added by the superuser  in the admin page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F71xvvxxmy8ictu07xhcu.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F71xvvxxmy8ictu07xhcu.JPG" alt="Orders Table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Installing django-filter to Filter Querysets
&lt;/h2&gt;

&lt;p&gt;Let's install the django-filter package by running the following command in your shell or command prompt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pip install django-filter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the django-filter package in the &lt;strong&gt;INSTALLED_APPS&lt;/strong&gt; list in the &lt;strong&gt;myproject/settings.py&lt;/strong&gt; just like we added the project's app before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'myapp',
    'django_filters',
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we create a &lt;strong&gt;filters.py&lt;/strong&gt; file in the app directory. The filter will be based on the &lt;strong&gt;Order&lt;/strong&gt; model. We will import the following filter arguments.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CharFilter&lt;/strong&gt; matches the character values passed in the CharField or TextField&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ChoiceFilter&lt;/strong&gt; matches the values that are passed in the &lt;em&gt;choices&lt;/em&gt; argument in the model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DateTimeFromToRangeWidget&lt;/strong&gt; filters values based on the range between two dates. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are filtering the orders based on the following attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;product&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;category&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;status&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;date_created&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import django_filters
from django_filters import DateTimeFromToRangeFilter, ChoiceFilter, CharFilter

from .models import Order

STATUS = (
    ('Pending', 'Pending'),
    ('Out for delivery', 'Out for delivery'),
    ('Delivered', 'Delivered'),
)

CATEGORY = (
    ('Indoor', 'Indoor'),
    ('Outdoor', 'Outdoor'),
)


class OrderFilter(django_filters.FilterSet):
    product = CharFilter(field_name = 'product', 
              lookup_expr='icontains')
    status = ChoiceFilter(choices=STATUS)
    category = ChoiceFilter(choices=CATEGORY)
    date_created = DateTimeFromToRangeFilter(
                  widget=django_filters.widgets.RangeWidget(
                  attrs={'type': 'date'}
    ))

    class Meta:
        model = Order
        fields = [
            'product',
            'category',
            'status',
            'date_created'
        ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will create a filter form by inheriting from  &lt;strong&gt;django_filters.Filterset&lt;/strong&gt; similar to creating Model Forms. &lt;/p&gt;

&lt;p&gt;CharFilter will filter through the products using the &lt;strong&gt;lookup_expr='icontains'&lt;/strong&gt; argument and display the results that match the characters entered in the form. ChoiceFilter will attribute to filtering by choices in the "category" and "status" fields, while DateTimeFromToRangeFilter will display the search results from filtering the orders by "date_created". &lt;/p&gt;

&lt;p&gt;Define the logic for the OrderFilter form inside the &lt;strong&gt;myapp/views.py&lt;/strong&gt; and then render it in the template. &lt;br&gt;
We then carryout the following steps in the view:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Import the OrderFilter from &lt;em&gt;filters.py&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a GET request and the orders queryset we are filtering, to the variable &lt;strong&gt;myFilter&lt;/strong&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rename the variable myFilter to &lt;strong&gt;orders&lt;/strong&gt; queryset.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from .filters import OrderFilter

def index(request):
    orders = Order.objects.all().order_by('-date_created')
    myFilter = OrderFilter(request.GET, queryset=orders)
    orders = myFilter.qs
    context = {
        'orders': orders,
        'myFilter': myFilter,
    }
    return render(request, 'index.html', context)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Copy and paste the following code to create a form in &lt;em&gt;index.html&lt;/em&gt; that will render the filter form. Note that the &lt;em&gt;form method="GET"&lt;/em&gt; because you are sending a GET request for your search queries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="row"&amp;gt;
    &amp;lt;div class="col"&amp;gt;
        &amp;lt;div class="card card-body ml-3 mr-3"&amp;gt;
            &amp;lt;form method="GET" action="" class="form-inline"&amp;gt;
                {% csrf_token %}
                    &amp;lt;div&amp;gt;
                    {{ myFilter.form }}
                    &amp;lt;div&amp;gt;
                        &amp;lt;button type="submit" class="btn btn- 
                        secondary"&amp;gt;SEARCH&amp;lt;/button&amp;gt;
                    &amp;lt;/div&amp;gt;
            &amp;lt;/form&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rerun the server and search your queries based on the filter form.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F92rr6crj7z4akq8a62n8.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F92rr6crj7z4akq8a62n8.JPG" alt="FilterForm"&gt;&lt;/a&gt;&lt;br&gt;
Search for orders based on your filters of choice. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvp0ufk0mzatlazf50kh.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvp0ufk0mzatlazf50kh.JPG" alt="Search Results"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The table will now display your search queries.&lt;/p&gt;

&lt;p&gt;I hope you find this article helpful to your coding journey. Please share among your coder friends. Incase of any questions, let's chat in the Comments Section. Happy coding.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>django</category>
      <category>search</category>
      <category>python</category>
    </item>
  </channel>
</rss>
