Django 1.10 Using a dropdown menu to filter queries
<p>I have a database with a bunch of pictures and the countries they were taken in. This is for a photo album on this site I'm making. Currently, I have all the pictures on one page. I like this. I want to now be able to search for all the pictures from a certain country, or city. My design calls for two buttons on top (filter by country, filter by city), and all the pictures from the database displayed below when no filter is used. I want these buttons to be a dropdown list of all the countries and cities respectively. When a user clicks on the countries button a dropdown is called - using bootstrap. They can then click on the country of choice and see all the pictures that are there, ordered by city. If they click on the dropdown for cities, then all the pictures from that city are called. If they select countries, then the cities dropdown only displays the cities in that country. Right now, I have no clue how to do this. I can populate the dropdowns - but I get all the photo's countries - meaning repeats. How can I do this?</p>

<p>Here is my views.py:</p>

<pre><code>def photo_album(request):
    queryset_list = Pictures.objects.all()
    query = request.GET.get("q")
    if query:
        queryset_list = queryset_list.filter(
            Q(pictures__icontains=query) |
            Q(picture_name__icontains=query) |
            Q(country__icontains=query) |
            Q(city__icontains=query)
        ).distinct()

    paginator = Paginator(queryset_list, 20)
    page_request_var = "page"
    page = request.GET.get(page_request_var)
    try:
        queryset = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        queryset = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        queryset = paginator.page(paginator.num_pages)

    context = {
        "object_list": queryset,
        "title": "List",
        "page_request_var": page_request_var,
    }
    return render(request, "in_country_pics/photo_album.html", context)
</code></pre>

<p>my html:</p>

<pre><code>&lt;div class="container"&gt;
    &lt;div class="photo-title"&gt;
        &lt;h1&gt;Welcome to Our Photo Album&lt;/h1&gt;
    &lt;/div&gt;
    &lt;div class="col-sm-12 photoalbum-buttons"&gt;
        &lt;form method="GET" action="" class="row"&gt;
            &lt;div class="col-sm-6"&gt;
                &lt;div class="input-group"&gt;
                    &lt;input class="form-control" type="text" name="q" placeholder="Search Posts" value="{{ request.GET.q }}"/&gt;
                    &lt;span class="input-group-btn"&gt;
                        &lt;button class="btn btn-default" type="submit"&gt;Search &lt;i class="fa fa-search"&gt;&lt;/i&gt;&lt;/button&gt;
                    &lt;/span&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/form&gt;

        &lt;div class="dropdown form-actions"&gt;
            &lt;button class="btn btn-primary gradient dropdown-toggle" type="button" data-toggle="dropdown"&gt;
                &lt;i class="fa fa-search"&gt;&lt;/i&gt;
                By Country
            &lt;/button&gt;
            &lt;ul class="dropdown-menu"&gt;
                {% for obj in object_list %}
                    &lt;li &gt;&lt;a href="#"&gt;{{ obj.country }}&lt;/a&gt;&lt;/li&gt;
                {% endfor %}
            &lt;/ul&gt;
        &lt;/div&gt;

        &lt;div class="dropdown form-actions"&gt;
            &lt;button class="btn btn-primary gradient dropdown-toggle" type="button" data-toggle="dropdown"&gt;
                &lt;i class="fa fa-search"&gt;&lt;/i&gt;
                By City
            &lt;/button&gt;
            &lt;ul class="dropdown-menu"&gt;
                {% for obj in object_list %}
                    &lt;li&gt;&lt;a href="#"&gt;{{ obj.city }}&lt;/a&gt;&lt;/li&gt;
                {% endfor %}
            &lt;/ul&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;p id="photo-separator"&gt;______________________________________________&lt;/p&gt;

    &lt;div class="row photo-post"&gt;
        {% for obj in object_list %}
            &lt;div class="col-sm-3"&gt;
                &lt;div class="thumbnail"&gt;
                    &lt;img src="{{ obj.pictures.url }}" class="img-responsive"/&gt;
                    &lt;div class="caption photo-description"&gt;
                        &lt;p class="photo-location"&gt;{{obj.city}}, {{obj.country}}&lt;/p&gt;
                        &lt;p class="photo-time"&gt;Taken: Aug 04, 2016&lt;/p&gt;
                         &lt;p&gt;&lt;a href="" class="btn btn-primary" type="button"&gt;View&lt;/a&gt;&lt;/p&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;
            {% if forloop.counter|divisibleby:4 %}
                &lt;div class='col-sm-12'&gt;&lt;hr/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class='row'&gt;
            {% endif %}
        {% endfor %}
    &lt;/div&gt;

&lt;/div&gt;

{% endblock %}
</code></pre>

<p>In the html, I have the first search bar working, but as a text. I have the below simple bootstrap dropdowns. If using ajax or jquery is best, I'm open to that.</p>

<p>You'll need Ajax to do that.</p>

<p>Follow <a href="https://realpython.com/blog/python/django-and-ajax-form-submissions/" rel="nofollow">this</a> tutorial to help you.</p>

<p>you need to download a <a href="https://raw.githubusercontent.com/realpython/django-form-fun/master/part1/main.js" rel="nofollow">script</a> (it is in the tutorial) to help you with the <em>csrf_token</em>, otherwise, when you submit the form you'll get a django error related with this token.</p>

<p>when calling to the Ajax url like this </p>

<pre><code>$.ajax({
        url: "some path/", // endpoint
</code></pre>

<p>you'll hvae to create that url in your <em>urls.py</em> file:</p>

<pre><code>urlpatterns = [
    url(r'^path/$', views.your_view_name),
]
</code></pre>

<p>this way you can call the view (or just a function in this case) send the info you need to your template.</p>

<p>Later, with jquery you can change the html of the element with its id something like this</p>

<pre><code>$('#your_element_id').html("&lt;p&gt;your updated code goes here&lt;/p&gt;");
</code></pre>

<p>you can also append elementets, just change the <em>.html</em> with <em>.append</em>.
The difference is that .html replace what you have with the code you give, and .apend only adds that code with what you have there.</p>

jquery python django django-models django-templates