django project mysite 2

 

First, the form form

In order to receive the user's choice vote, we need to show poll interface in a front page

polls/detail.html

<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
    <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
    <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
<input type="submit" value="Vote">
</form>
  • forloop.counter is a variable DJango template system specially provided to indicate the number of your current cycle, the cycle is generally used to add items ordered logarithmic scale.
  • Since we send a POST request, we must consider the safety of a cross-site request forgery, referred to as CSRF (specific meaning please Baidu). Django provides you with a simple way to avoid this trouble, it is added in the form form a {% csrf_token%} tag, label name can not be changed, fixed format, in any position, as long as the form is in the form. This method is convenient Haoshi submission form on the form of the way, but if it is submitting data using ajax way, then do not use this method has.

 

vote view function (polls / views.py) process

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

request.POST is a dictionary-like object, allowing you to submit data access by key name. In this example, request.POST[’choice’]it returns the ID of the selected option, and a type value of a string is always a string, even if it looks like a digital!

request.POST[’choice’]There may trigger a KeyError exception if your choice is not provided in POST data key, in this case, the above code will return the form page and gives an error message. PS: Usually we give a default value, to prevent such an exception, for example request.POST[’choice’,None],

After selecting the counter plus one, is a return HttpResponseRedirectinstead we used previously HttpResponse. HttpResponseRedirect takes one parameter: the redirected URL. Here's a suggestion, when you successfully handle POST data, should maintain a good habit, always returns a HttpResponseRedirect. This is not just for Django, it's a good habit to develop WEB.

We used one above HttpResponseRedirect the constructor reverse()function. It can help us to avoid hard-coded URL in the view function. It first requires a URLconf we specified in the name, and then the data transfer. For example '/polls/3/results/', where 3 is a question.idvalue. After entering the redirection polls:resultscorresponding view, and question.idis passed to it.

 

When someone vote on an issue, vote () view redirects to the questionnaire results display page. Let's write this view processing results pages (polls / views.py):

from django.shortcuts import get_object_or_404, render


def results(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/results.html', {'question': question})

templatepolls/templates/polls/results.html

<h1>{{ question.question_text }}</h1>

<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>

<a href="{% url 'polls:detail' question.id %}">Vote again?</a>

 

 

 

 

Second, the use of generic views: reducing code duplication

Improved URLconf

Open the polls/urls.pyfile, edit it into something like the following:

rom django.urls import path

from . import views

app_name = 'polls'
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    path('<int:pk>/', views.DetailView.as_view(), name='detail'),
    path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
    path('<int:question_id>/vote/', views.vote, name='vote'),
]

Modify View

Next, open polls/views.pya file, delete the index, detail view of the results and, to replace the general view of Django

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        """Return the last five published questions."""
        return Question.objects.order_by('-pub_date')[:5]


class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'


class ResultsView(generic.DetailView):
    model = Question
    template_name = 'polls/results.html'


def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST.get('choice'))
    except (KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

We used two common view ListViewand DetailView(they are inherited as a parent). Both represent "displays a list of objects" and "Display detail page of a particular type of object" abstraction.

  • Each generic view needs to know what it is to act on the model, this model provided by the property.

  • DetailViewNeed to capture the url to the primary key called "pk", so we in the url file 2 and 3 entries <question_id>modified into <pk>.

By default, the DetailViewgeneral view is referred to using a <app name>/<model name>_detail.htmltemplate. In the present example, it is actually used polls/detail.html. template_nameThis attribute is used to specify the name of the template, the template used in place of the default name is automatically generated. (Be sure to carefully observe the code above, condemnation, attention to detail) Similarly, in resutls list view, designated template_nameas 'polls/results.html', thus ensuring although resulst view and the detail view also inherited DetailView class, using the same model: Qeustion but they will still show different pages. (Templates for different Well! So easy!)

Similar, ListView generic view uses a template called default <app name>/<model name>_list.html. We also use template_namethis variable to tell ListView to use our existing  "polls/index.html"template, rather than using its own default one.

In the front part of the tutorial, we provide a template to contain questionand latest_question_listcontext variables. For DetailView, question'll be automatically provided, because we use Django's model (Question), Django will intelligently select the appropriate context variables. However, for the ListView, automatic generation of context variables question_list. To cover it, we offer a context_object_nameproperty that specifies that we want to use latest_question_listinstead question_list.

 

 

Third, static files

In addition to HTML files generated by the server, WEB applications typically need to provide some other necessary documents, such as image files, JavaScript scripts and CSS style sheets, and so on, the user is presented to a full page. In Django, we refer to these documents collectively referred to as "static files", because the contents of these documents is basically fixed, you do not need to dynamically generated.

For small projects, these are not a big problem, you can still file anywhere in your web server can be found. But for large projects, especially those that contain multiple app project, including the treatment of those different sets of static files from the app brings a hassle alive.

But this is the django.contrib.staticfilespurpose: It collects each application (and any place you specify) static files to a place designated unified, and easy to access.

 

Create a directory in the polls staticdirectory. Django looks for static files in there, which is looking for ways to Django corresponding template file is the same in polls / templates / in.

Django's STATICFILES_FINDERSsetting items included in a search list, they know how to find static files from a variety of sources. One of the default Finder Shi AppDirectoriesFinder,

It is for each INSTALLED_APPSto find the next staticsubdirectory, such as the one we just created staticdirectory. admin management site also uses the same directory structure for its static files.

staticCreate a new directory in pollsa subdirectory, and then create a subdirectory in the style.cssfile

 

Good directory structure is that each application should create their own urls, forms, views, models, templates and static, each of the templates contains a subdirectory with the same name as the application, each static application also contains a subdirectory with the same name.

polls/static/polls/style.css

li a {
    color: green;
}

In the template file polls/templates/polls/index.htmlreferenced head

{% load static %}

<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}">

{% static %}Template tags will generate an absolute URL path static files.

Restart the server, access the browser http://localhost:8000/polls/, you'll see a hyperlink into a green Question

Add a background image

In polls/static/polls/creating a directory for storing pictures imagessubdirectory, put `background.gif file in the subdirectory

 Css style file in polls/static/polls/style.cssthe Add

body {
    background: white url("images/background.gif") no-repeat;
}

Reload http://localhost:8000/polls/(CTRL + F5 or directly F5), you will see the loaded background image in the upper left corner of the screen

 

 

prompt:

{% static %}Template tags can not be used in static files, such as style sheets, because they are not generated by Django. You should use a relative path to link to each other static files

Direct access to static files

 

 

 

 

 

Reference Liu Jiang's blog tutorial

 

Guess you like

Origin www.cnblogs.com/xiao-apple36/p/11386224.html