简体   繁体   中英

Query String Parameter Passing between urls.py, views.py and <template_file>.html in Django

I'm building a simple photo portfolio site using Django. My "app" inside this project is called "photoViewer". The "photoViewer/photos/" displays a list of photos, with each photo's thumbnail, date and title. I'd like to add order by date, and order by title capabilities to this view.

To do so, I've added several buttons and I'm thinking of redirecting the user back to the photo list view, but with an additional string appended to the url: "date_desc" or "title_desc" (ie "photoViewer/photos/order_desc" or "photoViewer/photos/title_desc"). I've then added another url pattern to my "photoViewer/urls.py" that attempts to capture this additional string for filter type. I'm hoping to pass this string from my urls.py to the my photoIndex class view in views.py. The class view will check this filter type string and execute the correct logic to order either by date or title accordingly.

My questions: 1. How do I refer to and check this "captured" filter type string appended to the photo list view url in my photoIndexView () class in views.py. 2. How do I pass this string to my photoIndex template.html (or is this not even necessary, since the business logic should be in the views.py and not template file)

photoViewer/urls.py:

from django.conf.urls import patterns, include, url
from photoViewer import views

# map url to view using a URLconf
urlpatterns = patterns('',
   url(r'^$', views.PhotoIndexView.as_view(), name='photo_index'),
   url(r'^about/', views.PhotoViewerAboutView.as_view()),

   #My attempt below to capture any string w/o number as last param
   #route for photo list view w/ potential filter type string passed
   url(r'^photos/(?P<filter_type>[^\d+]*)$', views.PhotoIndexView.as_view(), name='photo_index'),

   #my route for photo detail view
   url(r'^photos/(?P<pk>\d+)/$', views.PhotoDetailView.as_view(), name='photo_detail'),

   ...
)

photoViewer/views.py:

from django.shortcuts import render
from django.http import HttpResponse
from django.views import generic
from photoViewer.models import Photo, Album


class PhotoViewerAboutView (generic.TemplateView):
     template_name = 'photoViewer/photoViewer_about.html'


class PhotoIndexView (generic.ListView):
     template_name = 'photoViewer/photo_index.html'
     context_object_name = 'latest_photo_list'

     def get_queryset(self):
          return Photo.objects.order_by('-date_taken')[:5]
...

photoViewer/templates/photoViewer/photo_index.html

{% extends 'base.html' %}

{% block title %}Photo Index{% endblock %}
{% block contents %}

<h1>Photo Index</h1>
<br>

<button id="sortBtn" type="button" class="btn btn-default">
  Date Taken: <span class="glyphicon glyphicon-sort" aria-hidden="true">  </span>
</button>

<br />
{% if latest_photo_list %}
    {% for photo in latest_photo_list %}
    <div class="container-fluid">
        <div class="row">
          <!-- Total Column width of 12 -->
          <div id = "per-pic" class="col-xs-12 col-md-6">
              <a href="{% url 'photoViewer:photo_detail' photo.id %}">
                <img src="/media/{{ photo.photo_img }}" class="img-thumbnail"  width="100%" height="100%" />
              </a>
              <li>
               <span class="label label-primary">{{ photo.photo_title }}</span>
               <span class="label label-info">{{ photo.date_taken }}</span>
              </li>
          </div>
        </div>
    </div>
    <br>
    {% endfor %}
{% else %}
<p>No Photos are available.</p>
{% endif %}
<script type="text/javascript">
    var sortButton = document.getElementById("sortBtn");
    sortButton.onclick = function () {
        //Append Filter type as string to URL?
        location.href = "date_asc";
    };
 //  sortButton.addEventListener("click", redirectSortBtn, false);
</script>
{% endblock %}

photoViewer/templates/photoViewer/base.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">

    <title>{% block title %}My amazing site{% endblock %}</title>

    <!-- Bootstrap core CSS -->
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">

    <!-- Optional theme -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">


    <!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
    <!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
    <script src="../../assets/js/ie-emulation-modes-warning.js"></script>

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->

       <!--Personal Custom CSS-->
      <link href="/static/css/personal.css" rel="stylesheet">

  </head>

  <body>
    <nav class="navbar">
      <div class="container">
            <ul class="pager" id = "nav_bar">
              <li><a href="/photoViewer/about">About</a></li>
              <li><a href="/photoViewer/photos/">Stream</a></li>
            </ul>

        </div><!--/.navbar-collapse -->
    </nav>


    <div class="jumbotron">
    {% block contents %}

    {% endblock %}
    </div>
      <hr>

      <footer>
        <p>&copy; Company 2014</p>
      </footer>
    </div> <!-- /container -->


    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
   <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <script src="/static/js/ie10-viewport-bug-workaround.js"></script>
  </body>
</html>

You can get URL parameters using self.args or self.kwargs . To change queryset override self.get_queryset . To pass additional variable to template override self.get_context_data . For example:

views.py

class PhotoIndexView (generic.ListView):
     template_name = 'photoViewer/photo_index.html'
     context_object_name = 'latest_photo_list'

     def get_queryset(self):
         filter_type = self.kwargs['filter_type']
         if filter_type == 'date_desc':
             return Photo.objects.order_by('-date_taken')[:5]
         elif  == 'title_desc':
             return Photo.objects.order_by('-title')[:5]
         else:
             # default ordering
             return Photo.objects.all()[:5]

    def get_context_data(self, **kwargs):
         context = super(PhotoIndexView, self).get_context_data(**kwargs)
         context['filter_type'] = self.kwargs['filter_type']
         return context

You can modify get_queryset to type less, something like this

get_queryset(self):
    filter_type = self.kwargs['filter_type']
    qs = Photo.objects.all()
    if filter_type == 'data_desc':
         qs = qs.order_by('-data_taken')
    elif filter_type == 'title_decs':
         qs = qs.order_by('-title')
    return qs[:5]

Also, I'd recommend to change urls.py , something like this

urls.py

   url(r'^photos/(?P<filter_type>[^\d+]*)$', views.PhotoIndexView.as_view(), name='photo_index'),

becomes

   url(r'^photos/(?P<filter_type>(data_desc|title_desc|)$', views.PhotoIndexView.as_view(), name='photo_index'),

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM