第一个Django App(四)


设计简单表单 form


更新/polls/templates/polls/detail.html,包含一个HTML <form> 元素:

<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>


快速解释:

上述模板显示一个为每个question choice提供一个radio按钮。每个radio按钮的值与question choice的ID关联。每个radio按钮的名字是‘choice’。这意味着,当有人选择一个radio按钮并提交form,这将发送一个POST数据choice=#,这里#是所选choice的ID。这是HTML form的基本概念。form的method设置为‘post’post很重要。


forloop.counter表示该循环中for tag已经使用的次数。


既然已经生成了一个POST表单,需要考虑跨域伪造请求问题。简而言之,所有POST表单在内部URLs的定位必须使用{% csrf_token %}模板标签。


polls/urls.py:

path('<int:question_id>/vote/', views.vote, name='vote'),


编辑polls/views.py:

from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse


from .models import Choice, Question
# ...
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):
        # Redisplay the question voting form.
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))


说明:

1、request.POST为一个类似字典的对象,访问由key名字提交的数据。这种场景下,request.POST['choice']返回选择choice的ID,request.POST的值总是字符串形式的。

2、POST成功之后采用HttpResponseRedirect返回而不是HttpResponse.HttpResponseRedirect,是一种好的web开发实践。

3、resverse()函数帮助避免视图函数中的硬编码。它采用视图的名字作为入参。


使用通用视图:Less code is better


参考:

https://docs.djangoproject.com/en/2.0/intro/tutorial04/



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值