知识点

  1) 编写urls

    配合include()的URL查找过程

    获取正则抓取的值并命名, 给url取名

  2) 模板的编写

    for循环的遍历

    用点的方式执行函数, 不带括号

  3) 视图函数的编写

    HttpResponse和进一步封装的render 

    发送404异常Http404()和进一步封装的方法get_object_or_404() 

  4) 硬编码的URL问题

  5) URL的名字的应用命名空间

1 编写视图

  在投票系统中, 需要显示首页, 投票的详细, 投票页面, 投票结果

  分别要编写index detail results vote视图

  polls/views.py

def detail(request, question_id):
return HttpResponse("You're looking at question %s." % question_id) def results(request, question_id):
response = "You're looking at the results of question %s."
return HttpResponse(response % question_id) def vote(request, question_id):
return HttpResponse("You're voting on question %s." % question_id)

  添加url

  polls/urls.py

from django.conf.urls import url
from . import views urlpatterns = [
# ex: /polls/
url(r'^$', views.index, name='index'),
# ex: /polls/5/
url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
# ex: /polls/5/results/
url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
# ex: /polls/5/vote/
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]

  可以看到

/polls/34/
将访问 detail() /polls/34/results/
将访问 results() /polls/34/vote/
将访问 vote()

  当有人输入/polls/34/访问时, 整个过程是这个样的

    Django先健在mysite.urls这个Python模块, 因为ROOT_URL_CONF设置指向的

    然后找到其中的urlpatterns并按照顺序遍历正则表达式, mysite/urls.py如下

    

    匹配到之后, 会剥离URL中的polls/留下34/到polls/urls.py进一步处理

     最后在polls/urls.py找到并调用视图函数detail(), 并传递参数为:

detail(request=<HttpRequest object>, question_id='34')

  可见, 使用?P<名字>的方式可以传递关键字参数

  当然可以添加URL cruft.html 

url(r'^polls/latest\.html$', views.index),

    - 但是一般不这样做, 太傻了(官方吐槽, 最为致命(ΘдΘ;))

2 进一步编写

  每个视图可以做两种操作, 一个是返回一个HttpResponse对象(包含请求页面的所有内容), 另一个是Http404

  视图函数实现的功能也不局限

    你可以读取数据库的记录, 也可以使用Django的模板系统, 也可使用第三方的模板系统

    你还可以生成PDF, 输出XML, 立即建立一个ZIP文件等等

  现在可以修改一下index对应的视图函数了

  polls/views.py

from django.http import HttpResponse
from polls.models import Question def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
output = ', '.join([q.question_text for q in latest_question_list])
return HttpResponse(output)

  为了分离模板和Python代码, 现在需要在另一个目录下创建模板文件

  项目的TEMPLATES设置了Django将如何加载和渲染模板

  在配置文件中有个APP_DIRS, 如果你设置为True 那么查找模板的时候就会去查找APP的目录

  

  为了便捷起见, Django模板会逐个在INSTALL_APPS的目录下, 查找名为templates的子目录

  至此, 我们创建模板的路径应该为( 在templates再创建子目录是为了区分 )

polls/templates/polls/index.html

    - 在templates再创建子目录是为了设置模板命名空间

    - 因为Django找模板的时候会根据名字来找, 每个app可能有多个名字相同的模板, 这样就不易区分

    - 在使用的使用, 模板名称前带上自己的应用名就好, 如

return render(request, 'polls/index.html', context)

  添加模板

  polls/templates/polls/index.html

{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}

  修改视图函数函数使用模板

  polls/views.py

from django.template import loader

def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = {
'latest_question_list': latest_question_list,
}
return HttpResponse(template.render(context, request))

  上述的加载模板的操作十分常见, 因此有了render来封装这个操作

  polls/views.py

from django.shortcuts import render
from polls.models import Question def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'latest_question_list': latest_question_list}
return render(request, 'polls/index.html', context)

  使用render将封装loader和HttpResponse

  其中-pub_date表示以pub_date字段降序排序, 正常是升序排序

3 发送404

  编写视图函数details的时候, 有可能该question_id是不存在的, 因此应该返回一个404错误

  polls/views.py

from django.http import Http404
from django.shortcuts import render from polls.models import Question
# ...
def detail(request, question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
return render(request, 'polls/detail.html', {'question': question})

  同样抛出404十分常用, 因此有get_object_or_404()来快速封装

  polls/views.py

from django.shortcuts import get_object_or_404, render

from polls.models import Question
# ...
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})

  get_object_or_404(): 第一个参数是Model, 其后是关键参数, 功能相当于执行get(), 当结果为空时抛出Http404

  get_list_or_404(): 用法和get_object_or_404()相同, 只是相当于当用filter(), 同样当结果为空时抛出Http404

4 使用模板系统

  同时我们可以快速的创建一个对应的details模板

  polls/templates/polls/detail.html

<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>

  关于模板的用点来查找属性的方式

    它有一个查找顺序, 比如上述的{{ question.question_text }}, 它会先把question当成是字典进行查找

    如果没找到question_text, 那就把question当成列表, 再去查找

  可以参见更多模板的用法

5 Removing hardcoded URLs in templates

  在polls/index.html中

<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

  这样的链接是 partially hardcoded

  这样的问题是, 如果在项目中这样的链接出现许多次, 而这个链接还有可能发生改变, 这样修改的工作量就会很大

  因此可以使用在之前定义好的name来反向查找

  在模板中使用 {% url %} 来反向获取

<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

7 Namespacing URL names

  接着上面的问题

  在真正的Django项目中肯定会有很多个应用

  那么在每个应用中可能有多个名为detail的URL

  那这个时候如何区分他们呢, 这就需要使用命名空间了

  具体使用如下  

  先给URLconf设置命名空间

  polls/urls.py

from django.conf.urls import url
from polls import views app_name = 'polls'
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]

  然后在使用的使用用 命名空间:名字 的方式来区分

  polls/templates/polls/index.html

<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

  

06 - Django应用第三步的更多相关文章

  1. Java基础:三步学会Java Socket编程

    Java基础:三步学会Java Socket编程 http://tech.163.com 2006-04-10 09:17:18 来源: java-cn 网友评论11 条 论坛        第一步 ...

  2. Django admin site(三)InlineModelAdmin

    InlineModelAdmin class InlineModelAdminclass TabularInlineclass StackedInline 举例,有两个Model: from djan ...

  3. 潭州课堂25班:Ph201805201 django 项目 第三课 码云注册,django项目 (课堂笔记)

    d码云注册,登录, 创建项目: 生成秘钥 想看秘钥: 添加公钥 复制 ssh 连接 通过  git clone <ssh> 连接 在服务器上创建 python3 虚拟环境, 创建项目  p ...

  4. Django基础(三)_分页器、COOKIE与SESSION、FORM表单

    分页器(paginator) 分页器的使用 >>> from django.core.paginator import Paginator >>> objects ...

  5. Django 06 Django模型基础1(ORM简介、数据库连接配置、模型的创建与映射、数据的增删改查)

    Django 06 Django模型基础1(ORM简介.数据库连接配置.模型的创建与映射.数据的增删改查) 一.ORM系统 #django模型映射关系 #模型类-----数据表 #类属性-----表字 ...

  6. 06: django+celery+redis

    目录: 1.1 Celery介绍 1.2 celery 组件 1.3 安装相关包 与 管理命令 1.4 celery与Django执行异步任务 1.5 在django中使用计划任务功能 1.1 Cel ...

  7. Membership三步曲之进阶篇 - 深入剖析Provider Model

    Membership 三步曲之进阶篇 - 深入剖析Provider Model 本文的目标是让每一个人都知道Provider Model 是什么,并且能灵活的在自己的项目中使用它. Membershi ...

  8. Membership三步曲之入门篇 - Membership基础示例

    Membership 三步曲之入门篇 - Membership基础示例 Membership三步曲之入门篇 -  Membership基础示例 Membership三步曲之进阶篇 -  深入剖析Pro ...

  9. ElasticSearch第三步-中文分词

      ElasticSearch系列学习 ElasticSearch第一步-环境配置 ElasticSearch第二步-CRUD之Sense ElasticSearch第三步-中文分词 ElasticS ...

随机推荐

  1. MySQL的max()函数使用时遇到的小问题

    通常我们获取某个表的某个字段最大值时可以使用max()函数. 使用场景举例: 获取某个表id的最大值:SQL: SELECT max(id) FROM table_name; SELECT max(` ...

  2. 【智力题】IO——行测、笔试、面试中遇到的

    昨天(05.23)下午去参加了明源软件的暑期实习宣讲+笔试,第一次听说这个行业,行业和笔试风格完全不一样啊,5道行测智力题+1个问答+ 斐波那契数列 + 洗牌算法(思想.流程图.代码),今年回来后线上 ...

  3. 看了就很快学会jQuery

    一.jQuery简介与第一个jQuery程序 1.1.jQuery简介 1.2.jQuery特点 1.3.jQuery版本 1.4.获得jQuery库 1.5.第一个jQuery程序 二.jQuery ...

  4. [Sdoi2014]数数[数位dp+AC自动机]

    3530: [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 834  Solved: 434[Submit][Status][ ...

  5. java排序(整理)

    冒泡排序(面试都要问的算法) 一.基本思想:每次比较相邻的两个 元素,按需调整顺序   二.题目:要求将 12 35 99 18 76 这 5 个数进行从大到小排序   三.思路: (1)先比较第 1 ...

  6. SocketAsyncEventArgs里的AcceptSocket能独立存在吗?

    独立存在是什么意思? 先来看一个例子.我们知道一个Socket对象(我们叫他ListenScoket)可以调用AcceptAsync并接受一个SocketAsyncEventArgs对象,如果操作成功 ...

  7. TextView属性

    TextView及其子类,当字符内容太长显示不下时可以省略号代替未显示的字符:省略号可以在显示区域的起始,中间,结束位置,或者以跑马灯的方式显示文字(textview的状态为被选中). 其实现只需在x ...

  8. react create app ,nginx服务器配置

    server{ listen 80; server_name www.domain.com domain.com; location ~* \.js$ { root /home/hard/Projec ...

  9. Kattis - friday 【数学】

    题意 每一年的第一天 都是星期天 然后 给出 一年的总天数 和 总月数 以及 每个月 的总天数 求出 有多少个星期五 是当月的13号 思路 对于 每个月 只要判断 当月的13号 是不是 星期五 就可以 ...

  10. QCon2016 上海会议汇总(2) - 团队管理

    QCon 2016上海日程:http://2016.qconshanghai.com/schedule <当你的团队还支撑不起梦想时> - 链尚网技术合伙人 杨荣伟 Figo讲述了如何训练 ...