前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >二、路由、模板

二、路由、模板

作者头像
酱紫安
发布2018-04-16 15:55:15
1.8K0
发布2018-04-16 15:55:15
举报
文章被收录于专栏:python学习路python学习路

一、路由系统

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

1、单一路由对应

代码语言:javascript
复制
url(r'^index$', views.index),

2、基于正则的路由

代码语言:javascript
复制
url(r'^index/(\d*)', views.index),
url(r'^manage/(?P<name>\w*)/(?P<id>\d*)', views.manage),

3、添加额外的参数

代码语言:javascript
复制
url(r'^manage/(?P<name>\w*)', views.manage,{'id':333}),

4、为路由映射设置名称

代码语言:javascript
复制
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 %}
代码语言:javascript
复制
<a href="{% url 'h2' 2012 %}">link</a>

渲染出来的就是
<a href="/h2/2012/">link</a>
  • Model中使用获取URL  自定义get_absolute_url() 方法
代码语言:javascript
复制
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 写一个跳转的函数:

代码语言:javascript
复制
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中:

代码语言:javascript
复制
 url(r'^old_h2/(\d+)/$', views.old_h2_redirect),
  url(r'^h2/(\d+)/$', views.h2, name='h2'),

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

代码语言:javascript
复制
url(r'^web/',include('web.urls')),

6、命名空间

a. project.urls.py

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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 中获取的数据插入到模版中,最后将信息返回给用户。

代码语言:javascript
复制
def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
代码语言:javascript
复制
from django import template
t = template.Template('My name is {{ name }}.')
c = template.Context({'name': 'Adrian'})
print t.render(c)
代码语言:javascript
复制
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)
代码语言:javascript
复制
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)
代码语言:javascript
复制
return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))
代码语言:javascript
复制
from django.shortcuts import render
import datetime


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

2、模版语言

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

代码语言:javascript
复制
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
代码语言:javascript
复制
<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 %}
代码语言:javascript
复制
<!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,可以简单这样写,重写部分代码(默认值的那一部分不用改)

代码语言:javascript
复制
{% extends 'base.html' %} {% block title %}欢迎光临首页{% endblock %} {% block content %} {% include 'ad.html' %} 这里是首页,欢迎光临 {% endblock %}

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

代码语言:javascript
复制
# 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 中的 

代码语言:javascript
复制
r'^add/(\d+)/(\d+)/$'

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

代码语言:javascript
复制
r'^jiafa/(\d+)/(\d+)/$'

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

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

代码语言:javascript
复制
{% url 'some-url-name' arg arg2 as the_url %}
 
<a href="{{ the_url }}">链接到:{{ the_url }}</a>

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

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

  • 获取当前用户:
代码语言:javascript
复制
{{ request.user }} 

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

代码语言:javascript
复制
{% if request.user.is_authenticated %}
    {{ request.user.username }},您好!
{% else %}
    请登陆,这里放登陆链接
{% endif %}
  •  获取当前网址:
代码语言:javascript
复制
{{ request.path }}
  •  获取当前 GET 参数
代码语言:javascript
复制
{{ request.GET.urlencode }}
  •  合并到一起用的一个例子
代码语言:javascript
复制
<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

代码语言:javascript
复制
#!/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 文件名

代码语言:javascript
复制
{% load xx %} 

d、使用simple_tag

代码语言:javascript
复制
{% my_simple_time 1 2 3%}
{% my_input 'id_username' 'hide'%}

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-04-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、路由系统
  • 二、模板
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档