Learn Django

List Accounts - Add Search

With the account list page built, and pagination working, it's time to add a search feature. Search is a key feature for the account list. If the user were to have 1000 accounts, they wouldn't want to use the 'next' link to navigate through dozens of pages before they can reach accounts at the end. Instead, they can issue a simple search to navigate to the account they're looking for.

This lesson will show you how to enable search functionality on the AccountList() view.

Step 1: Update the View

Open the /.../crmeasy/crmapp/accounts/views.py file in your IDE to begin. Update get_queryset() method as follows.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class AccountList(ListView):
    model = Account
    paginate_by = 12
    template_name = 'accounts/account_list.html'
    context_object_name = 'accounts'

    def get_queryset(self):
        try:
            a = self.request.GET.get('account',)
        except KeyError:
            a = None
        if a:
            account_list = Account.objects.filter(
                name__icontains=a,
                owner=self.request.user
            )
        else:
            account_list = Account.objects.filter(owner=self.request.user)
        return account_list

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(AccountList, self).dispatch(*args, **kwargs)

Code Review (for new/updated lines)

Lines 8-15: The goal of this new code is to update the queryset to account for a possible user search query.

The first task is to detect if the user is performing a search. This is what lines 8 & 9 do. The code self.request.GET.get('account') checks the URL to see if there's a search e.g. /account/list/?account=acme+corp. If there is a search, the query is assigned to the variable a. If this is not a search, then lines 10 & 11 kick in and a is assigned a non-value.

Once it's determined if this was a search or not, the account_list variable can be set. Lines 12-18 set it to the proper value depending on if a search is being made or not. If a has a value, then filter the accounts by that value and the current user. If it doesn't, then simply return the accounts for that user.

Step 2: Update the Template

Now open the /.../crmeasy/crmapp/templates/accounts/account_list.html file in your IDE. Locate the {# Account Search Form #} comment and add this code beneath it.

1
2
3
4
5
6
7
8
{# Account Search Form #}
<form action="{% url 'account_list' %}" method="get">
    <input id="al-search" type="text"
           name="account" value="{{ request.GET.account }}"
           class="form-control" />
    <input type="submit"
           value="Search" class="btn btn-success" />
</form>

Code Review

Line 3-5: This is the search box input element. You'll notice {{ request.GET.account }} in the value= attribute. Django makes the request object available in templates. What this allows us to do is check to see if the account parameter is present in the URL (e.g. /account/list/?account=acme-corp - if it is we display it's value in the input element. From a user experience perspective, this means that if a user performs a search the input box will show them what they searched for. It's a nice touch that helps the user understand if they are viewing a filtered list or not.

Step 3: Commit Changes

Execute these commands to commit your changes in Git.

1
2
3
4
5
# add files
(venv)$ git add .

# commit files
(venv)$ git commit -m "added search to the account list page"

Track your progress with a free account