Django来敲门~第一部分【7.网页中的表单处理】

上善若水。水善利万物而不争
——老子《道德经》


本节内容

  • 网页中的表单定义
  • 表单提交数据的处理

1. 网页中的表单定义

网页中的表单是前端页面中非常重要的一部分,我们结合官方文档进行讲解

首先改造我们的问题详细信息页面details.html,用于展示问题的同时,展示对应的解决方案;对于解决方案可以进行投票

1.1 改造mysite/polls/templates/details.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>详细问题展示</title>
    <link rel="stylesheet" href="">
</head>
<body>
    <!-- 展示问题描述信息 -->
    <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>
        {% endfor %}
        <input type="submit" value="Vote投票">
    </form>

</body>
</html>

在上述代码中,出现了大量的之前的章节中没有介绍的内容,我们一一说明一下。

  • action="{% url 'polls:vote' question.id %}":表单中的action是要提交的地址,我们通过配置化的URL路由进行处理
  • forloop.counter:表示循环当前正在进行的次数,第一次循环(1),第二次循环(2)以此类推
    *question.choice_set.all:通过question对象,关联查询对应的所有的Choice对象(对应的查询过程,Django在底层已经帮我们自动处理了,类似select * from choice where question_id = #{id}
  • error_message:这个是我们后面再改造detail视图处理函数时,要添加的一个保存错误信息的变量,这里主要用于展示错误信息
    *{%csrf_token%}:这是一个Django内置的指令,主要用于预防跨域请求伪造攻击的(在其他的网页应用中,伪造的跨域请求攻击是一件让人头疼的事情,Django这点做的非常棒呢!)

注意:关于模板视图和模型对象中用到的大部分的API,后续的章节中会有介绍的哦,支持一下我们吧

1.2 改造视图处理函数views.vote

接下来,对于表单提交的数据,我们需要在视图处理函数中接收到并且进行后续的处理

# 定义投票结果
def vote(request, question_id):
    # 获取查询的问题对象
    question = get_object_or_404(Question, pk=question_id)
    print(request.POST)
    try:
        select_choice = question.choice_set.get(pk=request.POST['choice'])
    except Exception as e:
        print(e)
        return render(request, "details.html",
                      {
                          "question": question,
                          "error_message": "你的问题还没有发布解决方案"
                      })
    else:
        # 投票数量增加1
        select_choice.votes += 1
        # 保存到数据库
        select_choice.save()
        # 代码中使用配置的方式跳转到指定的路由
        return HttpResponseRedirect(reverse("polls:results", args=(question.id,)))

对于上述代码,我们做一个简单的介绍,相信大家也就能看得明白了

  • request.POST:是一个用于接收表单通过POST提交的数据的方式
  • request.POST["choice"]:就是接收用户通过POST方式提交的表单中属性为choice的数据的,类似的还有request.GET['attr'];通过这样的方式获取数据,有可能会出现异常(当属性在表单中不存在时出现KeyError异常)
  • HttpResponseRedirect:这是类似前面我们学过的HttpResponse处理类,主要是用于响应用户的请求处理的,它比HttpResponse更加好用的是可以附带独立的参数列表;最后响应的是用户的请求会被重定向而不是转发。
  • reverse():这个函数主要是将之前我们处理的过程中操作的硬编码格式,转换成路由配置的格式,方便统一维护的操作。
1.3 改造results视图函数和mysite/polls/templates/results.html界面

views.results视图处理函数主要是用于进行问题数据查询并跳转到视图界面的,如下:

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

results.html网页主要是用于进行问题和对应解决方案的展示使用的,和details.html界面大同小异

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- 展示问题信息 -->
<h2>{{question.question_text}}</h2>
<!-- 循环遍历所有的解决方案 -->
<ul>
    {% for c in question.choice_set.all %}
    <li>方案:{{c.choice_text}}----[投票结果{{c.votes}}]vote{{ c.votes|pluralize }}</li>
    {% endfor %}
</ul>

<a href="{% url 'polls:detail' question.id%}">继续投票?</a>
</body>
</html>
1.4, 功能测试

接下来,我们重启项目,开始投票功能的测试

打开首页


首页问题列表

查看问题信息
details.html页面查看问题的详细信息

投票处理


results.html页面展示投票结果

这节关于表单的处理就先介绍到这里,对于大家常规的项目使用已经可以完全满足了。下一节内容将对我们页面中的样式进行处理,让页面看着更加的优美


Django来敲门
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容