django入门-part4

完全翻译自官方文档 https://docs.djangoproject.com/en/1.10/intro/tutorial04/

本节内容讲表单

让我们更新一下pools/detail.html,添加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>

解释一下上面的代码:

form里添加了一个radio单选框,label是单选框的标签,每个单选框的值是 choice.id,当你点了"submit"提交表单时,实际提交的内容是

一个变量choice=choice.id 即 input的name和value,表单提交的方法必须是post

forloop.counte是for循环的一个计数器,表示循环了多少次

{% csrf_token %}  这个是用来防止跨站攻击的,django已经帮我们做好了,放在form上就可以了

提交这个表单时,匹配的url是这个

url(r‘^(?P<question_id>[0-9]+)/vote/$‘, views.vote, name=‘vote‘),

现在更新一下我们的vote的视图

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

解释request.POST 你用post提交表单时传的参数就是用这个接收,是一个字典类型的;对应的request.GET就是接收get请求的参数

request.POST[‘choice‘]当key不存在时,会抛一个KeyError异常,所以代码要捕获这个异常HttpResponseRedirect(url)当成功提交表单返回结果时就用这个函数reverse这个函数是为了避免url的硬编码,本来这个url应该是这样的

url(r‘^(?P<question_id>[0-9]+)/results/$‘, views.results, name=‘results‘),现在呢
reverse(‘polls:results‘, args=(question.id,) 看不明白的请去复习上一节的内容(urls.py里的app_name和url()里的name就是这个用处
 

现在来完成result的视图

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

result的视图有了,下面写展示的模板

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

这个例子就是你选择单选按钮,然后点击提交按钮,跳转到一个新的页面,没有使用ajax.

注意:

vote视图这里有并发问题,当多个人对同一个question投票时,数据库在存和取时就有资源竞争问题了

django的解决方案在此 https://docs.djangoproject.com/en/1.10/ref/models/expressions/#avoiding-race-conditions-using-f

厉害的来了

通用视图

考虑一下我们前面写的视图detail(),results(),index()都是web开发中最通用的操作,根据url的参数从数据库存取内容,然后模板展示,这就是django通用视图考虑的问题,下面让我们用通用视图修改一下我们前面的应用pools

先修改urls.py

from django.conf.urls import url

from . import views

app_name = ‘polls‘
urlpatterns = [
    url(r‘^$‘, views.IndexView.as_view(), name=‘index‘),
    url(r‘^(?P<pk>[0-9]+)/$‘, views.DetailView.as_view(), name=‘detail‘),
    url(r‘^(?P<pk>[0-9]+)/results/$‘, views.ResultsView.as_view(), name=‘results‘),
    url(r‘^(?P<question_id>[0-9]+)/vote/$‘, views.vote, name=‘vote‘),
]

修改视图views.py

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

from .models import Choice, Question

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):
    ... # same as above, no changes needed.

这里我们用了两个新的视图ListView和DetailView

ListView 展示成列表

DetailView 根据不同的model展示不同的详情页

这两个视图都需要一个叫model的属性,它得知道根据那个model展示相应的内容

DetailView通用视图是根据url中的的pk参数来获取数据库内容的,所以我们urls.py做了相应修改

这两个通用视图如果你不传template_name那么会使用默认的模板文件

DetailView使用<app name>/<modelname>_detail.html 本应用中就是 "polls/question_detail.html"

ListView使用<app name>/<modelname>_list.html ,当然你传了template_name它就用你定义的模板了

在前面的章节中我们可以给urls.py里定义的url()定义一个context字典来给view()传参数,通用视图有预定义的变量可以使用

DetailView使用model的小写作为context变量的key

ListView使用model的小写+_list作为context的key

当然你想使用自己的context可以传context_object_name来自定义你的context

更多通用视图的内容请参考 https://docs.djangoproject.com/en/1.10/topics/class-based-views/

本节完

时间: 2024-10-16 18:30:56

django入门-part4的相关文章

django入门 -- 简单流程

django入门 -- 简单流程 这里简单的演示完成一个 django 大概流程,后面会有详细解释 搭建开发环境 以下使用的是 ubuntu 系统 在生产环境中,有的时候,我们开发的项目可能用的是几个不同的 环境,所以通常我们会创建虚拟环境,在虚拟环境中安装我们需要的 配置,这里从配置虚拟环境开始 创建虚拟环境 创建:mkvirtualenv [虚拟环境名称] 删除:rmvirtualenv [虚拟环境名称] 进入:workon [虚拟环境名称] 退出:deactivate 所有的虚拟环境,都位

Django入门笔记

Django入门笔记 **文档包含Django安装包.学习的笔记.代码等 安装 Django参考附件,只需要把附件拷贝到你需要的目录就行.Django是1.8.16版本 Python:在附件中,其中有Django需要的依赖包 编辑器:Aptana,一个强大的IDE工具,可以在上边新建模板,支持各种语言 Django项目创建 **可以用附件中的工程目录或者自己新建 新建工程-创建Django 新建工程-配置Django工程 工程创建完成后,会在工程目录中自动创建以下几个py文件 settings.

python16_day15【Django入门】

一.Django基本 1.什么是框架 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演.对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 1 import socket 2 3 def handle_request(client): 4 5 buf = client.recv(1024) 6 client.send("HTTP

Django入门全套(第三部)

前两部链接 django入门全套(第一部) Django入门全套(第二部) 本章内容: Django 发送邮件 Django cookie Django session Django CSRF Django 发送邮件 我们常常会用到一些发送邮件的功能,比如有人提交了应聘的表单,可以向HR的邮箱发邮件,这样,HR不看网站就可以知道有人在网站上提交了应聘信息.今天我们尝试用django发送邮件做尝试 1.配置相关参数settings 往settings添加下面几行数据 EMAIL_BACKEND =

python学习笔记--Django入门四 管理站点

上一节  Django入门三 Django 与数据库的交互:数据建模 "管理员界面"是基础功能中的重要部分.. 激活管理员界面 管理界面是 Django 中最酷的一部分.但是不是所有人都需要它,所以它是可选的.这也就意味着你需要跟着三个步骤来激活它. 在你的 models 中加入admin metadata. 不是所有的models都能够(或应该)被管理员编辑,你需要给models标记一个管理员接口(interface),通过给models添加一个内部类'admin'完成接口标记.所以

Django入门与实践 17-26章总结

Django入门与实践-第17章:保护视图 Django 有一个内置的视图装饰器 来避免它被未登录的用户访问: 现在如果用户没有登录,将被重定向到登录页面: 现在尝试登录,登录成功后,应用程序会跳转到原来所在的位置. Django入门与实践-第18章:访问已登录用户 现在我么可以改进 new_topic 视图,将发布主题的用户设置当前登录的用户,取代之前直接从数据库查询出来的第一个用户, 之前这份代码是临时的,因为那时候还没有方法去获取登录用户,但是现在可以了: 有两个关键字参数,pk用于唯一标

Django入门-框架目录介绍

Django入门博客:https://www.cnblogs.com/chuangming/p/9076721.html#4098510 备注:使用 Django 框架之后,开发服务端方便了很多.我们只需要做 ①定义函数 ②定义函数和路径的对应关系 这两件事情就可以使得服务端正常响应. 1.安装Django pip install Django 或者直接用pycharm安装 2.新建Django项目[直接使用pycharm] 3.文件具体解释 最外层test01----项目文件夹 里面test0

Django入门第一步:构建一个简单的Django项目

Django入门第一步:构建一个简单的Django项目 1.简介 Django是一个功能完备的Python Web框架,可用于构建复杂的Web应用程序.在本文中,将通过示例跳入并学习Django.您将按照以下步骤创建功能完备的Web应用程序,并一路学习框架的一些最重要的功能以及它们如何协同工作. 学习目标: 了解Django是什么以及为什么他是一个伟大的web框架 了解Django的体系结构以及与其他框架的对比 独立搭建一个简单的Django项目和应用程序(app) 2.为什么要学习Django

Django入门第一步(安装和创建一个简单的项目)

目录 Django入门第一步(安装和创建一个简单的项目) 一. Django项目目录结构 二.注意事项 三.Django安装 3.1.安装命令 3.2.验证django是否安装成功 3.3.使用方法 Django入门第一步(安装和创建一个简单的项目) 在使用Django框架开发web应用程序时,开发阶段同样依赖wsgiref模块来实现Server的功能,我们使用Django框架是为了快速地开发application. 如果使用的是我们自定义的框架来开发web应用,需要事先生成框架包含的一系列基础