博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
07 - Django应用第四步
阅读量:4322 次
发布时间:2019-06-06

本文共 4721 字,大约阅读时间需要 15 分钟。

知识点

  1) 表单的编写

    CSRF问题

    forloop.counter

  2) 视图函数的知识

    GET和POST

    HttpResponseRedirect的使用

    reverse的使用

  3) 通用视图

    CBV(class_base view)

    CVB在URLs的配置, 使用as_view()

    ListView和DetailView

    注意主键获取, 名字用fk

    默认模板的问题

    自带变量问题

1 编写表单

  polls/templates/polls/detail.html

{
{ question.question_text }}

{% if error_message %}

{

{ error_message }}

{% endif %}
{% csrf_token %}{% for choice in question.choice_set.all %}
{% endfor %}

  表单中的第一个input, type为radio表示单选框, name为choice表示提交的时候该input的value会提交成 choice=值 的形式

  form的属性添加了action表示提交地址, method设置为post非常适合用于表单提交数据

  forloop.counter表示for循环的次数, 类似于我们常用的i

  由于提交的表单会修改数据, 这有可能造成CSRF(Cross Site Request Forgeries, 跨站点请求伪造)

  为了防范这类问题, 针对修改内部网站的所有PSOT表达都应该加上{% csrf_token %}

  URLs配置如下

  polls/urls.py

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

  视图函数编写为

  polls/views.py

from django.shortcuts import get_object_or_404, renderfrom django.http import HttpResponseRedirect, HttpResponsefrom django.urls import reversefrom .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()        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

  request可以得到GET和POST两个值, 得到的结果是以个类似于字典的值, 可以用 request.GET['名字'] 或者 request.POST['名字'] 的方式来获取值

  返回使用的是HttpResponseRedirect 而不是常用的HttpResponse, 其只需传入一个参数, 是用于重定向的地址, 类型是字符串

  一般POST成功处理之后都应该使用HttpResponseRedirect, 原因是HttpResponseRedirect可以防止用户在点击回退按钮的时候重复提交表单

  可以使用reverse函数来避免硬编码(hardcode )的URL, reverse()函数可以传入两个参数, 一个是视图名, 一个是URL的参数

    如果question_id为3 那么返回的URL为

'/polls/3/results/'

  现在编写results的视图

  polls/views.py

from django.shortcuts import get_object_or_404, renderdef results(request, question_id):    question = get_object_or_404(Question, pk=question_id)    return render(request, 'polls/results.html', {'question': question})

  再创建results的模板

  polls/templates/polls/results.html

{
{ question.question_text }}

    {% for choice in question.choice_set.all %}
  • {
    { choice.choice_text }} -- {
    { choice.votes }} vote{
    { choice.votes|pluralize }}
  • {% endfor %}
Vote again?

  注意:

    此次的投票系统可能出现一些小BUG

    两个使用者可能在同一时刻提交同一个选项, 该选项的计数可能不正确

    

2 编写通用视图

  通过编写通用的视图, 可以复用代码, 进而减少代码量

  对于通用视图, Django提供了一个快捷方式, 叫做 通用视图系统( "generic views" system)  

  具体步骤为

    1) 转换URLconf

    2) 删除一些旧的,不需要的视图

    3) 根据Django的通用视图编写新视图

  修改URL配置

  polls/urls.py

from django.conf.urls import urlfrom polls import viewsapp_name = 'polls'urlpatterns = [    url(r'^$', views.IndexView.as_view(), name='index'),    url(r'^(?P
[0-9]+)/$', views.DetailView.as_view(), name='detail'), url(r'^(?P
[0-9]+)/results/$', views.ResultsView.as_view(), name='results'), url(r'^(?P
[0-9]+)/vote/$', views.vote, name='vote'),]

    - 注意第二个第三个URL的名字改为了pk

  修改视图

  polls/views.py

from django.shortcuts import get_object_or_404, renderfrom django.http import HttpResponseRedirectfrom django.urls import reversefrom django.views import genericfrom .models import Choice, Questionclass 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):    # 不做修改

  在这当中用到了ListViewDetailView两个通用视图, 分别用于显示

    对象列表

    特定对象的详细信息

  注意两点

    1) 必须要设置model, 要为其指定一个表(这里需要用类)

    2) 在捕获URL的时候, 需要获得主键信息, 这个时候就需要把正则表达式分组命名为pk, 这样命名Django才能正常识别

  默认情况下, DetailView返回的模板名也是有格式的(ListView同理), 格式为

/
_detail.html
/
_list.html

  另外还需要说明的是, 默认会提供一个上下文变量question 和一个全局变量latest_question_list 

  对于DetailView, 使用模型Question会自动提供变量question

  对于ListView, 使用模型Question会自动提供变量question_list

  如果要重写这个变量, 可以通过context_object_name属性来完成, index()函数就修改成了last_question_list

context_object_name = 'latest_question_list'

  如果需要更多内容, 

  

转载于:https://www.cnblogs.com/weihuchao/p/7081513.html

你可能感兴趣的文章
推荐10款左右切换的焦点图源码下载
查看>>
团队-团队编程项目爬取豆瓣电影top250-代码设计规范
查看>>
表头固定内容可滚动表格的3种实现方法
查看>>
想对你说
查看>>
day5 面向对象
查看>>
{算法}Young司机带你轻松KMP
查看>>
不同方法获得视差图比较
查看>>
发现的一个好的socket网页抓取源码
查看>>
jquery解析json
查看>>
实现自动发邮件功能
查看>>
jQuery笔记(二)
查看>>
GJM : Socket TCP 通信连接(四)
查看>>
基于SDP的提议/应答(offer/answer)模型简介
查看>>
PHP生成word文档的三种实现方式
查看>>
GIS当代技术群2084282(opening)
查看>>
arcengine 经典代码(转) 空间查询 在一个图层上画一个polygon,根据该polygon查询出图层上与之相交的polygon并高亮显示出来...
查看>>
BurpSuite中的安全测试插件推荐
查看>>
用存储过程实现获取字符串中的数据添加到列中
查看>>
GZIP压缩传输服务器配置
查看>>
Velocity模版进行shiro验证
查看>>