请稍候,加载中....

No.12 Django表单

现在我们已经可以向数据表中添加数据,并且还可以将数据从数据表中检索并显示出来,但是我们添加数据时并不能真正的实现用户输入控制,这一节课我们将学会通过表单向数据表中添加数据

创建表单模版

创建调查问卷添加表单

在之前的add_question视图函数中,我们每次刷新页面只能固定的提交相同的数据,通过添加表单我们可以向数据表中添加由用户填写的数据

创建polls/templates/polls/add_question.html模版

<form action="/polls/add/" method="post">
    <table>
        <tr>
        <th>调查项目</th>
        </tr>
        <tr>
            <td>
                <textarea name="question_text" id="" cols="30" rows="10"></textarea>
            </td>
        </tr>
    </table>
    <table>
        <tr>
            <th>调查选项</th>
        </tr>
        <tr>
            <td><input type="text" name="choice_1"></td>
            <td><input type="text" name="choice_2"></td>
        </tr>
    </table>
    <table>
        <tr><td><input type="submit" value="添加"></td></tr>
    </table>
</form>
  • 在表单中将action指向add_question视图的url
  • 表单的method设为post,表示数据通过post方式提交
  • 目前我们的能力有限,只能固定的添加两个问题选项

修改ADD视图函数

相应的add_question视图函数也需要做一些相应的修改

修改add视图函数

def add_question(request):
    if request.method == "POST":
        pub_date = timezone.now()
        question_text = request.POST['question_text']
        q = Question(question_text=question_text, pub_date=pub_date)
        try:
            q.save()
        except Exception as e:
            return HttpResponse(e)
        else:
            for i in range(1, 3):
                try:
                    choice_text = request.POST["choice_%s" % i]
                    q.choice_set.create(choice_text=choice_text)
                except Exception as e:
                    return HttpResponse(e)
         
    return render(request, "polls/add_question.html")
  1. 首先添加一条if语句,对request.method进行判断,当表单使用POST方法提交时,request.method的值为“POST”
  2. 如果数据是POST方式提交,那么可以通过request.POST对象提取表单数据,通过表单字段的name值作为key

CSRF_TOKEN

此时访问/polls/add就可以出现提交表单,填写数据进行提交

但是会出现错误提示

Forbidden (403)
CSRF verification failed. Request aborted.

CSRF - Cross-site request forgery,即跨站攻击伪造,主要是保证表单数据只能由自己的站点提交,是一种用户识别方式

现在我们需要给表单添加上csrf_token

修改add_question模版

<form action="/polls/add/" method="post">
   {% csrf_token %}
    <table>
        <tr>
        <th>调查项目</th>
........

修改详情视图

现在可以添加一个调查问卷,然后在问卷详情页进行投票

修改详情页面模版

与添加问卷类似,我们需要给投票部分添加上一个表单,与一个提交按钮

<!-- 增加form -->
<form action="/polls/{{ question.id }}" method="post">
{% csrf_token %} 
<table>
    <tr>
        <td>问卷选项</td><td></td>
    </tr>

    {% for choice in question.choice_set.all %}
    <tr>
        <td>{{ choice.choice_text }}</td>
          <!--  给复选框取名, 将value值设为id -->
        <td><input type="radio" name="choice" value={{ choice.id }}/></td>
    </tr>
    {% endfor %}
    <tr>
       <!--  增加按钮 -->
        <td>
            <input type="submit" value="投票">
        </td>
    </tr>
</table>
</form>

修改详情视图

.......
   # 新增加部分
   if request.method == "POST":
        choice = question.choice_set.get(id=request.POST['choice'])
        choice.votes += 1
        choice.save()

   return render(request, 'polls/detail.html', {'question': question})

添加结果显示

在之前的模版中并没有显示投票结果,现在添加结果页面,将投票结果显示出来

添加polls/result.html

<table>
{% for choice in question.choice_set.all %}
<tr>
     <td>{{ choice.choice_text }}</td> <td>{{ choice.votes }}</td>
</tr>
{% endfor %}
</table>

添加views.result视图函数

在这里,我们可以直接使用get_object_or_404便捷函数来读取数据,省去异常处理

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

添加url规则

我们希望用户通过/polls/result/question_id方式访问结果

修改urls,添加一条规则

urlpatterns = [
    path("", views.index, name="index"),
    path("add", views.add_question, name="add"),
    path('<int:question_id>/', views.detail, name='detail'),
    path('result/<int:question_id>', views.result)
]

修改列表页面

现在还需要为结果页提供一个入口,也就是用户可以通过链接点击查看的地方,我们把这个链接放在列表页面,当用户进入列表页面,点击查看“投票结果”,即可查看对应调查问题的投票结果

{% for question in question_list %}
        <li>
            <a href="/polls/{{ question.id }}/">{{ question.question_text }}</a>
            <br>
            <a href="/polls/result/{{ question.id }}">查看结果</a>
        </li>
    {% endfor %}

现在访问一下你的页面,可以查看结果了没


Python学习手册-