二、路由、模板

一、路由系统

  • 在settings.py文件中通过ROOT_URLCONF指定根级url的配置
  • urlpatterns是一个url()实例的列表
  • 一个url()对象包括:
    • 正则表达式
    • 视图函数
    • 名称name
  • 编写URLconf的注意:
    • 若要从url中捕获一个值,需要在它周围设置一对圆括号
    • 不需要添加一个前导的反斜杠,如应该写作'test/',而不应该写作'/test/'
    • 每个正则表达式前面的r表示字符串不转义
  • 请求的url被看做是一个普通的python字符串,进行匹配时不包括get或post请求的参数及域名
http://www.itcast.cn/python/1/?i=1&p=new,只匹配“/python/1/”部分

1、单一路由对应

url(r'^index$', views.index),

2、基于正则的路由

url(r'^index/(\d*)', views.index),
url(r'^manage/(?P<name>\w*)/(?P<id>\d*)', views.manage),

3、添加额外的参数

url(r'^manage/(?P<name>\w*)', views.manage,{'id':333}),

4、为路由映射设置名称

url(r'^home', views.home, name='h1'),
url(r'^index/(\d*)', views.index, name='h2'), 

设置名称之后,可以在不同的地方调用

URL的反向解析

  • 如果在视图、模板中使用硬编码的链接,在urlconf发生改变时,维护是一件非常麻烦的事情
  • 解决:在做链接时,通过指向urlconf的名称,动态生成链接地址视图:使用from django.urls import reverse函数
  • 模板中使用生成URL     {% url 'h2' 2012 %}
<a href="{% url 'h2' 2012 %}">link</a>

渲染出来的就是
<a href="/h2/2012/">link</a>
  • Model中使用获取URL  自定义get_absolute_url() 方法
class NewType(models.Model):
    caption = models.CharField(max_length=16)


    def get_absolute_url(self):
        """
        为每个对象生成一个URL
        应用:在对象列表中生成查看详细的URL,使用此方法即可!!!
        :return:
        """
        # return '/%s/%s' % (self._meta.db_table, self.id)
        # 或
        from django.urls import reverse
        return reverse('NewType.Detail', kwargs={'nid': self.id})

获取请求匹配成功的URL信息:request.resolver_match

  • 函数中使用生成URL     reverse('h2', args=(2012,))      路径:django.urls.reverse

另外,比如用户收藏夹中收藏的URL是旧的,如何让以前的 /h2/2012/自动跳转到现在新的网址呢?

要知道Django不会帮你做这个,这个需要自己来写一个跳转方法

具体思路是,在 views.py 写一个跳转的函数:

from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse  # Django 1.4.x - Django 1.10.x
#  from django.urls import reverse  # Django 1.10.x - Django 2.x
 
 
def old_h2_redirect(request, a):
    return HttpResponseRedirect(
        reverse('h2', args=(a, ))
    )

url.py中:

 url(r'^old_h2/(\d+)/$', views.old_h2_redirect),
  url(r'^h2/(\d+)/$', views.h2, name='h2'),

5、根据app对路由规则进行分类

url(r'^web/',include('web.urls')),

6、命名空间

a. project.urls.py

from django.conf.urls import url,include
 
urlpatterns = [
    url(r'^a/', include('app01.urls', namespace='author-polls')),
    url(r'^b/', include('app01.urls', namespace='publisher-polls')),
]

b. app01.urls.py

from django.conf.urls import url
from app01 import views
 
app_name = 'app01'
urlpatterns = [
    url(r'^(?P<pk>\d+)/$', views.detail, name='detail')
]

c. app01.views.py

def detail(request, pk):
    print(request.resolver_match)
    return HttpResponse(pk)

以上定义带命名空间的url之后,使用name生成URL时候,应该如下:

  • v = reverse('app01:detail', kwargs={'pk':11})
  • {% url 'app01:detail' pk=12  %}

django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。

二、模板

1、模版的执行

模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
from django import template
t = template.Template('My name is {{ name }}.')
c = template.Context({'name': 'Adrian'})
print t.render(c)
import datetime
from django import template
import DjangoDemo.settings
 
now = datetime.datetime.now()
fp = open(settings.BASE_DIR+'/templates/Home/Index.html')
t = template.Template(fp.read())
fp.close()
html = t.render(template.Context({'current_date': now}))
return HttpResponse(html)
from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime
 
def current_datetime(request):
    now = datetime.datetime.now()
    t = get_template('current_datetime.html')
    html = t.render(Context({'current_date': now}))
    return HttpResponse(html)
return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))
from django.shortcuts import render
import datetime


def index(request):
    now = datetime.datetime.now()
    return render(request, 'index.html', {'current_time':now})

2、模版语言

 模板中也有自己的语言,该语言可以实现数据展示

1 列表,字典,类的实例的使用
2 
3 循环:迭代显示列表,字典等中的内容
4 
5 条件判断:判断是否显示该内容,比如判断是手机访问,还是电脑访问,给出不一样的代码。
6 
7 标签:for,if 这样的功能都是标签。
8 
9 过滤器:管道符号后面的功能,比如{{ var|length }},求变量长度的 length 就是一个过滤器。

a、一般的变量之类的用 {{ }}(变量)

  • {{ item }}

b、循环:迭代显示列表,字典等中的内容

  • {% for item in item_list %}  <a>{{ item }}</a>  {% endfor %}

for 循环要有一个结束标记

  • 在for循环中还有很多有用的东西,如下:

变量

描述

forloop.counter

索引从 1 开始算

forloop.counter0

索引从 0 开始算

forloop.revcounter

索引从最大长度到 1

forloop.revcounter0

索引从最大长度到 0

forloop.first

当遍历的元素为第一项时为真

forloop.last

当遍历的元素为最后一项时为真

forloop.parentloop

用在嵌套的 for 循环中,获取上一层 for 循环的 forloop

  • 当列表中可能为空值时用 for  empty
<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% empty %}
    <li>抱歉,列表为空</li>
{% endfor %}
</ul>

d、判断  {% if ordered_warranty %}  {% else %} {% endif %}

e、网站模板的设计,一般的,我们做网站有一些通用的部分,比如 导航,底部,访问统计代码等等

  • 可以写一个 base.html 来包含这些通用文件(include)
    • 母板:{% block title %}{% endblock %} 子板:{% extends "base.html" %}    {% block title %}{% endblock %}
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}默认标题{% endblock %} - 标题</title>
</head>
<body>
 
{% include 'nav.html' %}   <div>include 是包含其它文件的内容</div>
 
{% block content %}
<div>这里是默认内容,所有继承自这个模板的,如果不覆盖就显示这里的默认内容。</div>
{% endblock %}
 
{% include 'bottom.html' %}
 
{% include 'tongji.html' %}
 
</body>
</html>

如果需要,写足够多的 block 以便继承的模板可以重写该部分,include 是包含其它文件的内容,就是把一些网页共用的部分拿出来,重复利用,改动的时候也方便一些,还可以把广告代码放在一个单独的html中,改动也方便一些,在用到的地方include进去。其它的页面继承自 base.html 就好了,继承后的模板也可以在 block 块中 include 其它的模板文件。

比如我们的首页 home.html,继承或者说扩展(extends)原来的 base.html,可以简单这样写,重写部分代码(默认值的那一部分不用改)

{% extends 'base.html' %} {% block title %}欢迎光临首页{% endblock %} {% block content %} {% include 'ad.html' %} 这里是首页,欢迎光临 {% endblock %}

f、模板上得到视图对应的网址:

# views.py
def add(request, a, b):
    c = int(a) + int(b)
    return HttpResponse(str(c))
 
 
# urls.py
urlpatterns = patterns('',
    url(r'^add/(\d+)/(\d+)/$', 'app.views.add', name='add'),
)
 
 
# template html
{% url 'add' 4 5 %} 

这样网址上就会显示出:/add/4/5/ 这个网址,假如我们以后修改 urls.py 中的 

r'^add/(\d+)/(\d+)/$'

这一部分,改成另的,比如:

r'^jiafa/(\d+)/(\d+)/$'

这样,我们不需要再次修改模板,当再次访问的时候,网址会自动变成 /jiafa/4/5/

还可以使用 as 语句将内容取别名(相当于定义一个变量),多次使用(但视图名称到网址转换只进行了一次)

{% url 'some-url-name' arg arg2 as the_url %}
 
<a href="{{ the_url }}">链接到:{{ the_url }}</a>

g、 ==, !=, >=, <=, >, < 这些比较都可以在模板中使用;and, or, not, in, not in 也可以在模板中使用

h、模板中 获取当前网址,当前用户等:

  • 获取当前用户:
{{ request.user }} 

如果登陆就显示内容,不登陆就不显示内容:

{% if request.user.is_authenticated %}
    {{ request.user.username }},您好!
{% else %}
    请登陆,这里放登陆链接
{% endif %}
  •  获取当前网址:
{{ request.path }}
  •  获取当前 GET 参数
{{ request.GET.urlencode }}
  •  合并到一起用的一个例子
<a href="{{ request.path }}?{{ request.GET.urlencode}}&delete=1">当前网址加参数 delete</a>

比如我们可以判断 delete 参数是不是 1 来删除当前的页面内容。

i、帮助方法: {{ item.event_start|date:"Y-m-d H:i:s"}} {{ bio|truncatewords:"30" }} {{ my_list|first|upper }} {{ name|lower }}

3、自定义simple_tag

a、在app中创建templatetags模块

b、创建任意 .py 文件,如:xx.py

#!/usr/bin/env python
#coding:utf-8
from django import template
from django.utils.safestring import mark_safe
   
register = template.Library()
   
@register.simple_tag
def my_simple_time(v1,v2,v3):
    return  v1 + v2 + v3
   
@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    return mark_safe(result)

c、在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名

{% load xx %} 

d、使用simple_tag

{% my_simple_time 1 2 3%}
{% my_input 'id_username' 'hide'%}

e、在settings中配置当前app,不然django无法找到自定义的simple_tag

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏coding

python的中异常处理处理ZeroDivisionError异常处理 FileNotFoundError 异常异常时保持静默

Python 使用被称为 异常 的特殊对象来管理程序执行期间发生的错误。每当发生让 Python 不知所措的错误时,它都会创建一个异常对象。如果你编写了处理该异...

28720
来自专栏工科狗和生物喵

【计算机本科补全计划】指令:计算机的语言(MIPS) --计算机组成原理 Part2

正文之前 今天折腾了一天的ubuntu windows双系统,在windows下安装ubuntu 16.04 然后 安装引导启动器的时候选择的是/boot所在的...

31340
来自专栏大闲人柴毛毛

Java并发编程的艺术(十二)——线程安全

1. 什么是『线程安全』? 如果一个对象构造完成后,调用者无需额外的操作,就可以在多线程环境下随意地使用,并且不发生错误,那么这个对象就是线程安全的。 2. ...

37850
来自专栏Pythonista

vim与程序员

所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在。

18920
来自专栏安恒网络空间安全讲武堂

专题 | Python编写渗透工具学习笔记一

目录&基础知识 0x00 Python编程中一些模块的简单介绍(基础知识) 0x01web目录扫描程序 --脚本代码的实现和分析 --优化脚本 0x02实现一个...

37270
来自专栏大内老A

使命必达: 深入剖析WCF的可靠会话[协议篇](下)

在《上篇》中,我们认识了从序列创建到终止过程中消息交换的大致流程。接下来,我们进一步将关注点聚焦到单个小消息上,看看在整个基于序列的上下文中,不同类型的消息具有...

24980
来自专栏coder修行路

python中重要的模块--asyncio

一直对asyncio这个库比较感兴趣,毕竟这是官网也非常推荐的一个实现高并发的一个模块,python也是在python 3.4中引入了协程的概念。也通过这次整理...

53770
来自专栏码洞

Channel最佳实践之基本规则【译】

channel[通道]是golang的一种重要特性,正是因为channel的存在才使得golang不同于其它语言。channel使得并发编程变得简单容易有趣。

7510
来自专栏Jackie技术随笔

I/O复用——select函数

select函数让进程告诉内核,等待数个事件,某个事件发生或者达到指定时间时,唤醒进程。

20440
来自专栏逍遥剑客的游戏开发

Nebula3学习笔记(5): IO系统

19740

扫码关注云+社区

领取腾讯云代金券