Filip
Filip

Reputation: 1864

Django: Filter paginated list with another URL parameter

I have list of games that I am displaying with Paginator. I would like to also be able to filter games by their genre.

In my view I have simple code to check, if genre parameter ("zanr") is part of the URL:

genre = request.GET.get('zanr')

if genre:
    free_games_list = free_games_list.filter(category__id=genre)

On my view page, I have HTML Select with genre names and their ID as values.

I have not so pretty JS code that redirects to new page after item in Select is selected:

 $('#select').change(function () {

        var selectElement = $(this);

        var url = window.location.href;

        if (url.indexOf('?') > -1) {
            url += '&zanr=' + selectElement.val();
        } else {
            url += '?zanr=' + selectElement.val();
        }

        window.location.href = url;
    });

This works fine with the first genre select. But when I select another genre, the parameter in URL is now simply duplicated like so: zanr=5&zanr=4&zanr=3

I thought about doing more JS to remove the parameter but I guess there will be far better and simpler option how to do this.

I also tried doing it as a Select inside of Form but had problems passing the selected value..

Upvotes: 0

Views: 946

Answers (2)

K. Cogswell
K. Cogswell

Reputation: 61

Try handling the query string creation in your django view instead of javascript.

def myView(request):
    query_string = ''
    genre = request.GET.get('zanr') 
    if genre:
        query_string += '&zanr={0}'.format(genre)
        free_games_list = free_games_list.filter(category__id=genre)

    # Pass query_string to template

Then in your template append this value to your paginator buttons.

<form action="{% url 'game_list' %}" method="GET">
  <label>Zanr</label>
  <select name="zanr">
    <option value="3">3</option>
    <option value="4">4</option>
  </select>
</form>

# ...        

<ul class="pagination">
  {% if objects.has_previous %}
<li>
  <a href="?page={{ objects.previous_page_number }}{{ query_string }}">&laquo;</a>
</li>
{% else %}
  <li class="disabled"><span>&laquo;</span></li>
{% endif %}

# ...

<script>
$('#select').change(function () {
  var form= $(this).parent();
  form.submit();
});
</script>

Upvotes: 1

Aamir Rind
Aamir Rind

Reputation: 39689

Instead of playing with the URL i'll recommend to use the form, and within form you should include hidden pagination params to preserve pagination criteria:

<form action="{% url 'my_search_url' %}" method="GET">
    <label for="zanr">Zanr</label>
    <select name="zanr" onchange="this.form.submit()">
        <option value="1" {% if genre == '1' %}selected{% endif %}>A</option>
        <option value="2" {% if genre == '2' %}selected{% endif %}>B</option>
    </select>
    <!-- Add hidden pagination params here -->
</form>

Send back genre in context from view to show the selected gener in dropdown.

Upvotes: 1

Related Questions