Django之路: 模版篇
一、Django 模版 |
上章是介绍简单的把django.http.HttpResponse的内容显示到网页上,下面就介绍以下如何使用渲染模版的方法来显示内容。本节代码是基于Django 1.8,但 Django 1.4 - Django 1.9操作都是一样的。
温馨提示:如果你想学习Django,那么就请您从现在开始按照笔记记录一步一步的用手把代码敲出来,千万不要偷懒哦。。。。。
1、创建一个zqxt_tmpl项目,并创建一个一个learn的应用,
- root@w:~# django-admin startproject zqxt_tmpl #项目
- root@w:~# cd zqxt_tmpl/
- root@w:~/zqxt_tmpl# python manage.py startapp learn #应用
2、在把创建的应用加到settings.INSTALLED_APPS中
- root@w:~/zqxt_tmpl# sudo vi zqxt_tmpl/settings.py
- ................
- INSTALLED_APPS = (
- 'django.contrib.admin',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.messages',
- 'django.contrib.staticfiles',
- 'learn', #添加的应用
- )
3、打开learn/views.py写一个首页视图
- root@w:~/zqxt_tmpl# sudo vi learn/views.py
- from django.shortcuts import render
- def home(request): #创建一个函数调用home.html
- return render(request, 'home.html')
4、在learn目录下新建一个templates文件夹,在里面创建一个home.html
默认配置下,Django的模版系统会知道在app下面找到templates文件夹中的模版文件。
- root@w:~# mkdir zqxt_tmpl/learn/templates
- root@w:~# touch zqxt_tmpl/learn/templates/home.html
- root@w:~# tree zqxt_tmpl
- zqxt_tmpl
- ├── learn
- │ ├── admin.py
- │ ├── __init__.py
- │ ├── models.py
- │ ├── templates
- │ │ └── home.html
- │ ├── tests.py
- │ └── views.py
- ├── manage.py
- └── zqxt_tmpl
- ├── __init__.py
- ├── __init__.pyc
- ├── settings.py
- ├── settings.pyc
- ├── urls.py
- └── wsgi.py
- 3 directories, 13 files
5、在home.html中写一些内容。
- root@w:~# sudo vi zqxt_tmpl/learn/templates/home.html
- <!DOCTYPE html>
- <html>
- <head>
- <title>欢迎光临</title> #title头部欢迎语
- </head>
- <body>
- 欢迎您访问吴老二博客,希望在此学习愉快 #内部内容
- </body>
- </html>
6、将视图函数对应的网址,更改zqxt_tmpl/zqxt_tmpl/urls.py
- root@w:~# sudo vi zqxt_tmpl/zqxt_tmpl/urls.py
- from django.conf.urls import patterns, include, url
- from django.contrib import admin
- admin.autodiscover()
- urlpatterns = patterns('',
- # Examples:
- url(r'^$', 'learn.views.home', name='home'),#把前面的注释去掉
- # url(r'^blog/', include('blog.urls')),
- url(r'^admin/', include(admin.site.urls)),
- )
Django 1.8.x及以上:
- from django.conf.urls import include, url
- from django.contrib import admin
- from learn import views as learn_views
- urlpatterns = [
- url(r'^$', learn_views.home, name='home'), #news
- url(r'^admin/', include(admin.site.urls)),
- ]
7、【可选】创建数据库表
- root@w:~/zqxt_tmpl# python manage.py syncdb
- Creating tables ...
- Creating table django_admin_log
- Creating table auth_permission
- Creating table auth_group_permissions
- Creating table auth_group
- Creating table auth_user_groups
- Creating table auth_user_user_permissions
- Creating table auth_user
- Creating table django_content_type
- Creating table django_session
- You just installed Django's auth system, which means you don't have any superusers defined.
- Would you like to create one now? (yes/no): yes
- Username (leave blank to use 'root'): root #数据名称默认root
- Email address:
- Password: #数据库密码
- Password (again):
- Superuser created successfully.
- Installing custom SQL ...
- Installing indexes ...
- Installed 0 object(s) from 0 fixture(s)
Django 1.9.x 及上:
- root@w:~/zqxt_tmpl# python manage.py migrate
创建数据库虽然不会用,但是可以让一些提示消失(提示你要创建数据库之类的)
8、运行开发服务器
- root@w:~/zqxt_tmpl# python manage.py runserver 192.168.1.30:8001 #如果本地测试的话就不需要加IP了
- Validating models...
- 0 errors found
- December 24, 2015 - 09:41:55
- Django version 1.6.10, using settings 'zqxt_tmpl.settings'
- Starting development server at http://192.168.1.30:8001/
- Quit the server with CONTROL-C.
网页测试效果:
模版补充知识:
一般的网站通用部分,比如导航,底部,访问统计代码等。
- root@w:~# cd zqxt_tmpl/learn/templates/
- root@w:~/zqxt_tmpl/learn/templates# touch nav.html bottom.html tongji.html
可以先写一个base.html来包含这些通用文件(include)
- root@w:~/zqxt_tmpl/learn/templates# sudo vi base.html
- <!DOCTYPE html>
- <html>
- <head>
- <title>{% block title %}默认标题{% endblock %} -吴老二博客</title>
- </head>
- <body>
- {% include 'nav.html' %}
- {% block content %}
- <div>这里是默认内容,所有继承都来自这个模版,如果不覆盖就显示这里的默认内容.</div>
- {% endblock %}
- {% include 'bottom.html' %}
- {% include 'tongji.html' %}
- </body>
- </html>
如果需要,写足够多的block以便继承的模版可以重写该部分,include是包含其它文件的内容,就是把一些网页共用的部分拿出来,重复利用,改动的时候也方便一些,还可以把广告代码放在一个单独的html中,改动也方便,在用到的时候直接继承base.html就好了,继承后的模版也可以在block块中include其它的模版文件。
这里用首页home.html,继承或者说扩展(extends)原来的base.html,可以简单的这样写,重写部分代码(默认值部分不用修改)
- root@w:~/zqxt_tmpl/learn/templates# sudo vi home.html
- <!DOCTYPE html>
- <html>
- <head>
- <title>欢迎光临</title>
- </head>
- <body>
- {% extends 'base.html' %}
- {% block title %}欢迎光临吴老二博客首页{% endblock %}
- {% block content %}
- {% include 'ad.html' %}
- 这里是吴老二首页,欢迎光临
- {% endblock %}
- </body>
- </html>
浏览器浏览效果:
注:模版一般放在app下的templates下,Django会自动找到,加入每个app都有一个index.html,当我们在views.py中使用的时候,如何判断是当前app的home.html呢?
这就需要把每个app中的templates文件夹在建一个app的名称,仅和该app相关的模版放在app/templates/app目录下。
例如:项目zqxt下有两个app应用分别为tutorial和tryit
root@w:~# tree zqxt
zqxt
├── manage.py
└── zqxt
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
1 directory, 5 files
root@w:~# cd zqxt
root@w:~/zqxt# python manage.py startapp tutorial
root@w:~/zqxt# python manage.py startapp tryit
root@w:~/zqxt# cd
root@w:~#
root@w:~# tree zqxt
zqxt
├── manage.py
├── tryit
│?? ├── admin.py
│?? ├── __init__.py
│?? ├── models.py
│?? ├── tests.py
│?? └── views.py
├── tutorial
│?? ├── admin.py
│?? ├── __init__.py
│?? ├── models.py
│?? ├── tests.py
│?? └── views.py
└── zqxt
├── __init__.py
├── __init__.pyc
├── settings.py
├── settings.pyc
├── urls.py
└── wsgi.py
3 directories, 17 files
root@w:~# cd zqxt/t
tryit/ tutorial/
root@w:~# cd zqxt/tutorial/
root@w:~/zqxt/tutorial# mkdir -p templates/tutorial
root@w:~/zqxt/tutorial# touch templates/tutorial/index.html templates/tutorial/search.html
root@w:~/zqxt/tutorial# cd ..
root@w:~/zqxt# cd t
tryit/ tutorial/
root@w:~/zqxt# cd tryit/
root@w:~/zqxt/tryit# mkdir -p templates/tryit
root@w:~/zqxt/tryit# touch templates/tryit/index.html templates/tryit/poll.html
root@w:~/zqxt/tryit# cd
root@w:~# tree zqxt
zqxt
├── manage.py
├── tryit
│?? ├── admin.py
│?? ├── __init__.py
│?? ├── models.py
│?? ├── templates
│?? │?? └── tryit
│?? │?? ├── index.html
│?? │?? └── poll.html
│?? ├── tests.py
│?? └── views.py
├── tutorial
│?? ├── admin.py
│?? ├── __init__.py
│?? ├── models.py
│?? ├── templates
│?? │?? └── tutorial
│?? │?? ├── index.html
│?? │?? └── search.html
│?? ├── tests.py
│?? └── views.py
└── zqxt
├── __init__.py
├── __init__.pyc
├── settings.py
├── settings.pyc
├── urls.py
└── wsgi.py
7 directories, 21 files
项目zqxt
这在使用的时候“tutorial/index.html”和“tryit/index.html”这样作为app名称的一部分,就不会混淆
二、Django 模版进阶 |
以下内容主要是针对Django模板中的循环,条件判断,常用的标签,过滤器的使用。
1、列表,字典,类的实例的使用
2、循环:迭代显示列表,字典等中的内容
3、条件判断:判断是否显示该内容,比如判断是手机访问,还是电脑访问,给出不一样的代码。
4、标签:for,if这样的功能都是标签。
5、过滤器:管道符号后面的功能,比如{{ var|length }},求变量长度的length就是一个过滤器。
经常需要将一个或多个变量共享给多个页面或者所有页面使用,比如在网页上显示来访者的IP,这个可以是用Django上下文渲染器来做。
实例,显示一个基本的字符串在页面上(在项目zqxt_tmpl上)
- root@w:~/zqxt_tmpl/learn# sudo vi views.py
- # -*- coding: utf-8 -*-
- from django.shortcuts import render
- def home(request):
- string = u"我在吴老二博客学习Django,用它来建网站"
- return render(request, 'home.html', {'string': string})
在视图中锄地了一个字符串名称是string到模版home.html,在模版中这样使用:
- root@w:~/zqxt_tmpl/learn/templates# sudo vi home.html
- {{ string }}
浏览器访问,在本机上运行:
- root@w:~/zqxt_tmpl# python manage.py runserver 192.168.1.30:8000
- Validating models...
- 0 errors found
- December 25, 2015 - 03:25:16
- Django version 1.6.10, using settings 'zqxt_tmpl.settings'
- Starting development server at http://192.168.1.30:8000/
- Quit the server with CONTROL-C.
- [25/Dec/2015 03:25:32] "GET / HTTP/1.1" 200 53
浏览器:
实例二:for循环和list内容的显示在zqxt_tmpl/learn/views.py
- root@w:~/zqxt_tmpl# sudo vi learn/views.py
- # -*- coding: utf-8 -*-
- from django.shortcuts import render
- def home(request):
- TutorialList = ["HTML", "CSS", "jQuery", "Django"]
- return render(request, 'home.html', {'TutorialList': TutorialList})
在视图中传递了一个List到模版zqxt_tmpl/learn/templates/home.html,在模版中使用它:
- root@w:~# sudo vi zqxt_tmpl/learn/templates/home.html
- 教程列表:
- {% for i in TutorialList %}
- {{ i }}
- {% endfor %}
本地运行服务:
- root@w:~/zqxt_tmpl# python manage.py runserver 192.168.1.30:8000
- Validating models...
- 0 errors found
- December 25, 2015 - 03:38:06
- Django version 1.6.10, using settings 'zqxt_tmpl.settings'
- Starting development server at http://192.168.1.30:8000/
- Quit the server with CONTROL-C.
- [25/Dec/2015 03:38:10] "GET / HTTP/1.1" 200 42
for循环要一个结束标记,上面的代码假如对应的是首页的网址(自己修改urls.py),显示在网页上就是:
总结:一般的变量之类的用{{}} (变量),功能类的,比如循环,条件判断是用{% %}(标签)
实例三:显示字典中的内容:
- root@w:~/zqxt_tmpl# sudo vi learn/views.py
- # -*- coding: utf-8 -*-
- from django.shortcuts import render
- def home(request):
- info_dict = {'site': u'吴老二', 'content': u'自己建网站'}
- # TutorialList = ["HTML", "CSS", "jQuery", "Django"]
- return render(request, 'home.html', {'info_dict': info_dict})
- # return render(request, 'home.html', {'TutorialList': TutorialList})
为了和上个例子做对比我把上例注释掉了,您也可以注释掉也可以直接删除掉。
- root@w:~/zqxt_tmpl# sudo vi learn/templates/home.html
- 【站点】:{{ info_dict.site }} 【内容】:{{ info_dict.content }}
- #{% for i in TutorialList %}
- #{{ i }}
- #{% endfor %}
在模版注释了上个实例您也可以删除,这个实例模版中取字典的键是用info_dict.site,而不是Python中的info_dict['site'],效果如下:
注:以上实例在浏览器浏览之前都要运行以下python manage.py runserver IP:prot
还可以这样遍历字典:
- root@w:~/zqxt_tmpl# sudo vi learn/templates/home.html
- {% for key, value in info_dict.items %}
- {{ key }}: {{ value }}
- {% endfor %}
其实就是遍历这样一个List:[('content': u'自己建网站'), ('site': u'吴老二')]
实例四:在模版进行条件判断和for循环的详细操作:
- root@w:~/zqxt_tmpl# sudo vi learn/views.py
- # -*- coding: utf-8 -*-
- from django.shortcuts import render
- def home(request):
- List = map(str, range(100)) #一个长度为100的list
- return render(request, 'home.html', {'List': List})
使用逗号将这些元素连接起来:
- root@w:~/zqxt_tmpl# sudo vi learn/templates/home.html
- {% for item in List %}
- {{ item }},
- {% endfor %}
效果如下:
最后一个元素的后面也有一个逗号,这样不是我们想要的,如何判断是不是遍历到最后一个元素呢?
这里可以用forloop.last这个变量,如果是最后一项其为真,否则为假,更改如下:
- root@w:~/zqxt_tmpl# sudo vi learn/templates/home.html
- {% for item in List %}
- {{ item }}{% if not forloop.last %},{% endif %}
- {% endfor %}
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>
实例五,模版上得到视图对应的网址:
- # 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' %}
这样网址上就会显示出:/add/4/5/这个网址,假如我们以后修改urls.py中的
- r'^add/(\d+)/(\d+)/$'
这一部分,改成另的,比如:
- r'^jiafa/(\d+)/(\d+)/$'
这样,我们不需要在次修改模版,当再次访问的时候,网址就会自动变成/jiafa/4/5/
注意:如果是Django 1.4的话,需要在模版开头上 {% load url from future %} (如果有 extends 的话,加在 extends 下面)
这可以使用as语句将内容取别名(相当于定义一个变量),多次使用(但视图名称到网址转换只进行了一次)
- {% url 'some-url-name' arg arg2 as the_url %}
- <a href="{{ the_url }}">链接到:{{ the_url }}</a>
实例六,模版中的逻辑操作
==,!=,>=,<=,>,<这些比较都可以在模版中使用,比如:
- {% if var >= %}
- 成绩优秀,吴老二博客你没少去吧!学得不错
- {% elif var >= %}
- 成绩良好
- {% elif var >= %}
- 成绩一般
- {% elif var >= %}
- 需要努力
- {% else %}
- 不及格啊,大哥!多去吴老二博客学习啊!
- {% endif %}
and,or,not,in,not in也可以在模版中使用
假如我们判断num是不是在0到100之间:
- {% if num <= and num >= %}
- num在0到100之间
- {% else %}
- 数值不在范围之内!
- {% endif %}
假如我们判断’wulaoer‘
- {% if 'wulaoer' in List %}
- 自强学堂在名单中
- {% endif %}
实例七,模版中获取当前网址,当前用户等:
如果不是在 views.py 中用的 render 函数,是render to response的话,需要将request加入到上下文渲染器
Django 1.8 及以后 修改settings.py
- TEMPLATES = [
- {
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [],
- 'APP_DIRS': True,
- 'OPTIONS': {
- 'context_processors': [
- ...
- 'django.template.context_processors.request',
- ...
- ],
- },
- },
- ]
Django 1.7 及以前修改settings.py:
如果没有TEMPLATE_CONTEXT_PROCESSORS请自行添加下列默认值:
- TEMPLATE_CONTEXT_PROCESSORS = (
- "django.contrib.auth.context_processors.auth",
- "django.core.context_processors.debug",
- "django.core.context_processors.i18n",
- "django.core.context_processors.media",
- "django.core.context_processors.static",
- "django.core.context_processors.tz",
- "django.contrib.messages.context_processors.messages",
- )
然后再加上 django.core.context_processors.request
- TEMPLATE_CONTEXT_PROCESSORS = (
- ...
- "django.core.context_processors.request",
- ...
- )
然后在模版中我们就可以用request了。
获取当前用户:
- {{ 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来删除当前的页面内容。
Django之路: 模版篇的更多相关文章
- Django之路: 基本命令与网址进阶
一.Django 基本命令 温馨提示:如果你想学习Django,那么就请您从现在开始按照笔记记录一步一步的用手把代码敲出来,千万不要偷懒哦..... 1.创建一个Django project djan ...
- 自己瞎捣腾的Win7下Linux安装之路-----理论篇
接着上回说道,我把双系统做好啦,开心.... 之后我就在想几个问题: 1.在Ubuntu装好后,重启电脑却还是win7,等我用EasyBCD之后,才可选择使用装好的Ubuntu呢? 2.在用EasyB ...
- C蛮的全栈之路-node篇(二) 实战一:自动发博客
目录 C蛮的全栈之路-序章 技术栈选择与全栈工程师C蛮的全栈之路-node篇(一) 环境布置C蛮的全栈之路-node篇(二) 实战一:自动发博客 ---------------- 我是分割线 ---- ...
- C蛮的全栈之路-node篇(一) 环境布置
目录 C蛮的全栈之路-序章 技术栈选择与全栈工程师C蛮的全栈之路-node篇(一) 环境布置C蛮的全栈之路-node篇(二) 实战一:自动发博客 ---------------- 我是分割线 ---- ...
- python之路基础篇
基础篇 1.Python基础之初识python 2.Python数据类型之字符串 3.Python数据类型之列表 4.Python数据类型之元祖 5.Python数据类型之字典 6.Python Se ...
- Django之路
备注:本套笔记内容来源于互联网,只做学习使用,如有侵权请联系本笔记作者. 资料内容 Django之路(一)——什么是Web开发 Django之路(二)——Django初识 Django之路(三)——U ...
- .NET持续集成与自动化部署之路第一篇——半天搭建你的Jenkins持续集成与自动化部署系统
.NET持续集成与自动化部署之路第一篇(半天搭建你的Jenkins持续集成与自动化部署系统) 前言 相信每一位程序员都经历过深夜加班上线的痛苦!而作为一个加班上线如家常便饭的码农,更是深感其痛 ...
- STM32学习之路入门篇之指令集及cortex——m3的存储系统
STM32学习之路入门篇之指令集及cortex——m3的存储系统 一.汇编语言基础 一).汇编语言:基本语法 1.汇编指令最典型的书写模式: 标号 操作码 操作数1, 操作数2,... ...
- CYQ.Data 轻量数据层之路 使用篇二曲 MAction 数据查询(十三)----002
原文链接:https://blog.csdn.net/cyq1162/article/details/53303390 前言说明: 本篇继续上一篇内容,本节介绍所有相关查询的使用. 主要内容提要: 1 ...
- (转)Android项目重构之路:实现篇
前两篇文章Android项目重构之路:架构篇和Android项目重构之路:界面篇已经讲了我的项目开始搭建时的架构设计和界面设计,这篇就讲讲具体怎么实现的,以实现最小化可用产品(MVP)的目标,用最简单 ...
随机推荐
- Entity Framework技巧系列之十四 - Tip 56
提示56. 使用反射提供程序编写一个OData Service 在TechEd我收到一大堆有关将数据作为OData暴露的问题. 到目前为止你大概知道可以使用数据服务与Entity Framework将 ...
- LeetCode OJ 292.Nim Gam19. Remove Nth Node From End of List
Given a linked list, remove the nth node from the end of list and return its head. For example, Give ...
- 【Machine Learning in Action --2】K-近邻算法构造手写识别系统
为了简单起见,这里构造的系统只能识别数字0到9,需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小:宽高是32像素的黑白图像.尽管采用文本格式存储图像不能有效地利用内存空间,但是为了方便理 ...
- Java良葛格 学习笔记《二》
正则表达式 . 符合任一字符\d 符合0到9任一个数字字符\D 符合0-9以外的字符\s 符合'\t'.'\n'.'\x0B'.'\f'.'\r'等空格符\w 符合a到z.A到Z.0到9等字符,也就是 ...
- angular跨域访问的问题
CORS跨域资源共享 跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源. Form responseHeaders = (Form) ...
- Redis和Memcached的区别【转】
如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:1 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储.2 Redis支持数据 ...
- Beam me out!
Beam me out! 题目描述 King Remark, first of his name, is a benign ruler and every wrongdoer gets a second ...
- /var/lib/mysql/mysql.sock错误的解决办法
问题描述: 使用mysql -uroot -p登录出现找不到 /var/lib/mysql/mysql.sock或者被使用的问题. 可以用如下命令登录:mysql -p --socket=/tmp/m ...
- GCC: compilation process..
gcc -Iproj/src myfile.c -o myfile gcc -c myfile.c "compile without linking gcc -D DEBUG myfile. ...
- Android :android.os.Process.myTid()与 Thread.currentThread().getId();
这两种方式得到的ID并不是相同的,前者的返回值是int,后者是long. 个人猜测:应该是一个线程的两种得到的方式.类似于一个人有2个名字. 如有不对,请指正!