码迷,mamicode.com
首页 > 其他好文 > 详细

Django入门笔记【四】

时间:2015-06-24 17:59:27      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:

入门笔记翻译整理自:https://docs.djangoproject.com/en/1.8/

*该笔记将使用一个关于投票网络应用(poll application)的例子来阐述Django的用法。

表单和通用视图(Forms&Generic Views)

1. 简单的表单

修改detail.html中的代码,使之含有<form>元素:

 1 # polls/templates/polls/detail.html
 2 
 3 <h1>{{ question.question_text }}</h1>
 4 
 5 {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
 6 
 7 <form action="{%url ‘polls:vote‘ question.id %}" method="post">
 8 {% csrf_token %}
 9 {% for choice in question.choice_set.all %}
10     <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{choice.id }}" />
11     <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
12 {% endfor %}
13 <input type="submit" value="Vote" />
14 </form>

 以上代码:首先,为选项生成了radio按钮;其次,当你创建数据服务端(data server-side)的表单时,要始终使用method="post";然后,forloop.counter对循环进行计数;最后,由于使用了POST方法,我们需要关心跨站请求伪造(Cross Site Request Forgeries),不过Django提供了对此的保护机制。

我们在入门基础【三】中创建了如下代码:

1 # polls/urls.py
2 
3 url(r^(?P<question_id>[0-9]+/vote/$, views.vote, name=vote),

 

向polls/views.py中添加如下代码:

 1 # polls/views.py
 2 
 3 from django.shortcuts import get_object_or_404, render
 4 from django.http import HttpResponseRedirect, HttpResponse
 5 from django.core.urlresolvers import reverse
 6 
 7 from .models import Choice, Question
 8 # ...
 9 def vote(request, question_id):
10     p = get_object_or_404(Question, pk=question_id)
11     try:
12         selected_choice = p.choice_set.get(pk=request.POST[choice])
13     except (KeyError, Choice.DoesNotExist):
14         # Redisplay the question voting form.
15         return render(request, polls/detail.html,{
16             question: p,
17             ‘‘error_message: "You didnt select a choice.",
18     })
19     else:
20         selected_choice.vote += 1
21         selected_choice.save()
22         # Always return an HttpResponseRedirect after successfully dealing
23         # with POST data. This prevents data from being posted twice if a
24         # user hits the Back button.
25         return HttpResponseRedirect(reverse(polls:results, args=(p.id,)))

 

当有人在问题下投票后,vote()视图会重新定向至结果页面,该页面视图如下:

1 # polls/views.py
2 
3 from django.shortcuts import get_object_or_404, render
4 
5 def results(request, question_id):
6     question = get_object_or_404(Question, pk=question_id)
7     return render(request, polls/results.html, {question: question})

 

现在,创建polls/results.html模板:

 1 # polls/templates/polls/results.html
 2 
 3 <h1>{{ question.question_text }}</h1>
 4 
 5 <ul>
 6 {% for choice in question.choice_set.all %}
 7     <li>{{ choice.choice_text }} -- {{ choice.votes }} vote {{ choice.votes | pluralize }}</li>
 8 {% endfor %}
 9 </ul>
10 
11 <a href="{% url ‘polls:detail‘ question.id %}">Vote again?</a>

 

2. 使用通用视图

注意到,detail()和results()视图很简单,并且冗余。index()视图也很相似。

这些视图代表了一种常见情形:根据URL中的被传递参数,从数据库中获取数据,载入模板,返回渲染后的模板。对于此类情形,可以使用Django提供的通用视图系统。

为了使用通用视图进行代码简化,我们需要进行以下改变:

1.转换URLconf;2.删除陈旧不必要的视图;3.引入基于通用视图的新视图

3. 修改URLconf

 1 # polls/urls.py
 2 
 3 from django.conf.urls import url
 4 
 5 from . import views
 6 
 7 ulrpatterns = [
 8     url(r^$, views.IndexView.as_view(), name=index),
 9     url(r^(?P<pk>[0-9]+)/$, views.DetailView.as_view(), name=detail),
10     url(r^(?P<pk>[0-9]+)/results/$, views.ResultsView.as_view(), name=results),
11     url(r^(?P<question_id>[0-9]+)/vote/$, views.vote, name=vote),
12 ]

 

注意第二和第三个模式从question_id变成了pk。

4. 修改Views 

 1 # polls/views.py
 2 
 3 from django.shortcuts import get_object_or_404, render
 4 from django.http import HttpResponseRedirect
 5 from django.core.urlresolvers import reverse
 6 from django.views import generic
 7 
 8 from .models import Choice, Question
 9 
10 class IndexView(generic.ListView):
11     template_name = polls/index.html
12     context_object_name = latest_question_list
13 
14     def get_queryset(self):
15         """Return the last five published questions."""
16         return Question.objects.order_by(-pub_date)[:5]
17 
18 class DetailView(generic.DetailView):
19     model = Question
20     template_name = polls/detail.html
21     
22 class ResultsView(generic.DetailView):
23     model = Question
24     template_name = polls/results.html
25 
26 def vote(request, question_id):
27     ... # same as above

 

-- The End --

Django入门笔记【四】

标签:

原文地址:http://www.cnblogs.com/py-drama/p/4584258.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!