什么是web框架
框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演。
最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。
如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。
正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务。
这个接口就是WSGI:Web Server Gateway Interface。
web框架在一次HTTP数据传输中所起到的作用
初识Django
DJango所用的是MTV模式其中
- Model(模型):负责业务对象与数据库的对象(ORM[对象映射关系]),也就是数据库相关操作
- Template(模板):负责如何把页面渲染展示给用户
- View(视图):负责业务逻辑(Python主要处理衔接前端和后台的数据),并在适当的时候调用Model和Template
此外Django还有一个URL分发器,它的作用是当用户在浏览器搜索栏中输入的URL地址发送给Django的时候,将指定的URL地址发给指定的view函数处理,view函数调用相对应的Model和Template
Django处理web请求的大概流程图
Django的基本命令
1、创建一个django 项目
django-admin startproject mysite(创建的项目名称)
目录形式
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
这些目录和文件的用处是:
- 最外层的:file: mysite/ 根目录只是你项目的容器, Django 不关心它的名字,你可以将它重命名为任何你喜欢的名字。
manage.py
: 一个让你用各种方式管理 Django 项目的命令行工具。你可以阅读 django-admin and manage.py获取所有manage.py
的细节。- 里面一层的
mysite/
目录包含你的项目,它是一个纯 Python 包。它的名字就是当你引用它内部任何东西时需要用到的 Python 包名。 (比如mysite.urls
). mysite/__init__.py
:一个空文件,告诉 Python 这个目录应该被认为是一个 Python 包。mysite/settings.py
:Django 项目的配置文件。mysite/urls.py
:Django 项目的 URL 声明,就像你网站的“目录”。mysite/wsgi.py
:作为你的项目的运行在 WSGI 兼容的Web服务器上的入口。
2、创建一个Django应用(application)
django-admin startapp app01(应用名称)
app01/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
3、启动Django项目
python manage.py runserver 8080
这样Django就启动起来了。现在访问:http://127.0.0.1:8080
4、同步更改数据库表或字段
python manage.py makemigrations
生成迁移代码的makemigrations指令是用模型里面的模型和当前的迁移代码里面的模型做对比,如果有新的修改,就生成新的迁移代码
python manage.py migrate
migrate指令是用于迁移目录中间代码文件和Django的数据库django_migrations表中的代码文件做对比如果表中没有那就对这些没有文件按顺序和依赖关系做迁移应用然后再把代码文件名加进迁移表中。也就是说,在改动models.py的内容之后执行: python manage.py makemigrations .会在该应用下会建立migrations目录,并记录modes.py的改动,但是这个改动还没有作用到数据库文件
5、清空数据库
python manage.py flush
此命令会询问是 yes 还是 no, 选择 yes 会把数据全部清空掉,只留下空表。
6、创建超级管理员
按照提示输入用户名和对应的密码就好了邮箱可以留空,用户名和密码必填
python manage.py createsuperuser username
修改用户名,密码
7、Django 项目环境终端
python manage.py shell
这个命令和 直接运行 python 进入 shell 的区别是:你可以在这个 shell 里面调用当前项目的 models.py 中的 API,对于操作数据的测试非常方便。
8、Django 项目环境终端
python manage.py dbshell
Django 会自动进入在settings.py中设置的数据库,如果是 MySQL 或 postgreSQL,会要求输入数据库用户密码。
在这个终端可以执行数据库的SQL语句。如果您对SQL比较熟悉,可能喜欢这种方式。
9、更多命令
python manage.py
[auth]
changepassword
createsuperuser
[contenttypes]
remove_stale_contenttypes
[django]
check
compilemessages
createcachetable
dbshell
diffsettings
dumpdata
flush
inspectdb
loaddata
makemessages
makemigrations
migrate
sendtestemail
shell
showmigrations
sqlflush
sqlmigrate
sqlsequencereset
squashmigrations
startapp
startproject
test
testserver
[sessions]
clearsessions
[staticfiles]
collectstatic
findstatic
runserver
官网中介绍方法
10 static配置
#3、STATIC文件还可以配置STATICFILES_DIRS,指定额外的静态文件存储位置。 # STATIC_URL的含义与MEDIA_URL类似。 # ---------------------------------------------------------------------------- #注意1: #为了后端的更改不会影响前端的引入,避免造成前端大量修改 STATIC_URL = '/static/' #引用名 STATICFILES_DIRS = ( os.path.join(BASE_DIR,"statics") #实际名 ,即实际文件夹的名字 ) #django对引用名和实际名进行映射,引用时,只能按照引用名来,不能按实际名去找 #<script src="/statics/jquery-3.1.1.js"></script> #------error-----不能直接用,必须用STATIC_URL = '/static/': #<script src="/static/jquery-3.1.1.js"></script> #注意2(statics文件夹写在不同的app下,静态文件的调用): STATIC_URL = '/static/' STATICFILES_DIRS=( ('hello',os.path.join(BASE_DIR,"app01","statics")) , ) #<script src="/static/hello/jquery-1.8.2.min.js"></script> #注意3: STATIC_URL = '/static/' {% load staticfiles %} # <script src={% static "jquery-1.8.2.min.js" %}></script>
URLConf Django路由控制
Django的处理如何请一个请求
- Django确定要使用的根URLconf模块。通常,这是设置值
ROOT_URLCONF
,但是如果传入HttpRequest
对象具有一个urlconf
属性(由中间件设置),则其值将用于代替ROOT_URLCONF
设置。 - Django加载该Python模块并查找变量
urlpatterns
。这应该是一个Python列表django.urls.path()
和/或django.urls.re_path()
实例。 - Django依次匹配每个URL模式,在与请求的URL匹配的第一个模式停下来。
- 一旦某个URL模式匹配,Django就会导入并调用给定的视图,该视图是一个简单的Python函数(或基于类的视图)。该视图通过以下参数传递:
- 一个
HttpRequest
实例。 - 如果匹配的URL模式没有返回任何命名组,则来自正则表达式的匹配作为位置参数提供。
- 关键字参数由路径表达式匹配的任何命名部分组成,并由可选
kwargs
参数todjango.urls.path()
或中 指定的任何参数覆盖django.urls.re_path()
。
- 一个
- 如果没有URL模式匹配,或者在此过程中的任何点发生异常,Django将调用适当的错误处理视图。
总结:URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。
urlpatterns = [ url(正则表达式, views视图函数,参数,别名), ] 参数说明: 一个正则表达式字符串 一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串 可选的要传递给视图函数的默认参数(字典形式) 一个可选的name参数 '''
URLConf示例
#选自官方提供的示例,网址:https://docs.djangoproject.com/en/1.11/topics/http/urls/ from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/([0-9]{4})/$', views.year_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ]
笔记:
- 要从URL中捕获值,只需在其周围放置括号即可。
- 没有必要添加一个前导斜杠,因为每个URL都有。例如,它
^articles
不是^/articles
。 - 的
'r'
正面的每个正则表达式字符串的中是可选的,但推荐使用。它告诉Python一个字符串是“原始的” - 字符串中的任何内容都不应该被转义。请
示例请求:
- 请求
/articles/2005/03/
匹配列表中的第三个条目。Django会调用这个函数 。views.month_archive(request,'2005', '03')
/articles/2005/3/
不匹配任何URL模式,因为列表中的第三项需要两位数字。/articles/2003/
会匹配列表中的第一个模式,而不是第二个模式,因为模式是按顺序测试的,而第一个模式是第一个要传递的测试。随意利用订单来插入像这样的特殊情况。在这里,Django会调用这个函数views.special_case_2003(request)
/articles/2003
不匹配任何这些模式,因为每种模式都要求URL以斜线结尾。/articles/2003/03/03/
将匹配最终模式。Django会调用这个函数。views.article_detail(request,'2003', '03', '03')
有命名分组(name group)
上面的例子使用简单的非命名正则表达式组(通过圆括号)捕获URL的位,并将它们作为位置参数传递给视图。在更高级的用法中,可以使用命名 正则表达式组来捕获URL位并将它们作为关键字 参数传递给视图。
在Python正则表达式中,命名正则表达式组的语法是(?P<name>pattern)
,其中name
是组的名称并且 pattern
是一些要匹配的模式。
这里是上面的例子URLconf,重写为使用命名组:
from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive), url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail), ]
这和前面的例子完全一样,只有一个细微的差别:捕获的值被传递给查看函数,而不是位置参数。例如:
/articles/2005/03/
请求将调用views.month_archive(request, year='2005', month='03')
函数,而不是views.month_archive(request, '2005', '03')
。- 请求
/articles/2003/03/03/
调用该函数 。views.article_detail(request, year='2003', month='03',day='03')
实际上,这意味着你的URLconf稍微更明确一点,不太容易出现参数顺序错误 - 你可以重新排列视图函数定义中的参数。当然,这些好处是以简洁为代价的; 一些开发人员发现命名组语法丑陋而且太冗长。
针对命名组和非命名组:
- 如果有命名参数,则使用这些命名参数,忽略非命名参数。
- 否则,它将以位置参数传递所有的非命名参数。
URLconf搜索的内容
请求的URL被看做是一个普通的Python字符串,URLconf在其上查找并匹配。进行匹配时将不包括GET或POST请求方式的参数以及域名。
例如,在https://www.example.com/myapp/
的请求中,URLconf将查找myapp/
。
在https://www.example.com/myapp/?page=3
的请求中,URLconf也将查找myapp/
。
URLconf不检查使用何种HTTP请求方法,所有请求方法POST、GET、HEAD等都将路由到同一个URL的同一个视图。在视图中,才根据具体请求方法的不同,进行不同的处理。
捕获的参数总是字符
每个捕获的参数都作为一个普通的Python字符串传递给视图,即便被捕获的‘100’看起来像个整数,但实际上是个字符串‘100’。 例如,下面这行URLconf中:
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
传递给views.year_archive()
的year参数将是一个字符串,不是整数,即使[0-9]{4}
只匹配整数字符串。
指定视图参数的默认值
# URLconf from django.conf.urls import url from . import views urlpatterns = [ url(r'^blog/$', views.page), url(r'^blog/page(?P<num>[0-9]+)/$', views.page), ] # View (in blog/views.py) def page(request, num="1"): # Output the appropriate page of blog entries, according to num. ...
在上面的例子中,两个URL模式指向同一个视图views.page
。但是第一个模式不会从URL中捕获任何值。 如果第一个模式匹配,page()函数将使用num参数的默认值"1"。 如果第二个模式匹配,page()将使用捕获的num值。
自定义错误页面
当Django找不到与请求匹配的URL时,或者当抛出一个异常时,将调用一个错误处理视图。错误视图包括400、403、404和500,分别表示请求错误、拒绝服务、页面不存在和服务器错误。它们分别位于:
- handler400 —— django.conf.urls.handler400。
- handler403 —— django.conf.urls.handler403。
- handler404 —— django.conf.urls.handler404。
- handler500 —— django.conf.urls.handler500。
这些值可以在根URLconf中设置。在其它app中的二级URLconf中设置这些变量无效。
Django有内置的HTML模版,用于返回错误页面给用户,但是这些403,404页面实在丑陋,通常我们都自定义错误页面。
首先,在根URLconf中额外增加下面的条目:
from django.conf.urls import url,include from django.contrib import admin from app import views # from django.conf.urls import handler404 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login.html$', views.login,name="LOGIN"), url(r'^index.html', views.index,name="INDEX"), url(r'^app/',include('app.ulrs')) ] handler404 = views.page_not_found #定制404页面,在views函数中写
然后在,views.py文件中增加这个处理视图:
def page_not_found(req): return render(req,'404.html')
再根据自己的需求,创建404.html、400.html等四个页面文件,就可以了。
传递额外的参数给include()
类似上面,也可以传递额外的参数给include()。参数会传递给include指向的urlconf中的每一行。
例如,下面两种URLconf配置方式在功能上完全相同:
实际上在项目的urls.py上面的注释也写到了include其他application到Django路由中
from django.conf.urls import url,include from django.contrib import admin from app import views # from django.conf.urls import handler404 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login.html$', views.login,name="LOGIN"), url(r'^index.html', views.index,name="INDEX"), url(r'^app/',include('app.ulrs')) #引入app下面的urls到路由中 ]
urls中的第三个参数:传递额外的选项给视图函数(了解)
URLconfs具有一个钩子(hook),允许你传递一个Python字典作为额外的关键字参数给视图函数。
像这样:
from django.conf.urls import url from . import views urlpatterns = [ url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}), ]
在上面的例子中,对于/blog/2005/
请求,Django将调用views.year_archive(request, year='2005', foo='bar')
。理论上,你可以在这个字典里传递任何你想要的传递的东西。但是要注意,URL模式捕获的命名关键字参数和在字典中传递的额外参数有可能具有相同的名称,这会发生冲突,要避免。
URLConf中的别名(name)
给URL起一个别名在很多地方都会用到,比如我们在后台提交一个表单提交的地址是http://127.0.0.1/login.html,我们们只需要在form表单的action写href="{% url 'LOGIN' %}",并且就算以后我们提交的URL变了的话,我们的别名在此处依旧是起到作用,可以提交到新的URL地址中来。
from django.conf.urls import url,include from django.contrib import admin from app import views # from django.conf.urls import handler404 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login.html$', views.login,name="LOGIN"), #login.html 别名为LOGIN url(r'^index.html', views.index,name="INDEX"), url(r'^app/',include('app.ulrs')) ]
views视图函数
- 视图函数,简称视图,本质上是一个简单的Python函数,它接受Web请求并且返回Web响应。
- 响应的内容可以是HTML网页、重定向、404错误,XML文档或图像等任何东西。但是,无论视图本身是个什么处理逻辑,最好都返回某种响应。
- 视图函数的代码写在哪里也无所谓,只要它在你的Python目录下面。但是通常我们约定将视图放置在项目或应用程序目录中的名为views.py的文件中。
简单的视图
下面是一个返回当前日期和时间作为HTML文档的视图:
from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
让我们逐行分析一下上面的代码:
- 首先,从
django.http
模块导入了HttpResponse
类,以及Python的datetime库。 - 接着,我们定义了
current_datetime
视图函数。 - 每个视图函数都接收一个HttpRequest对象作为第一位置参数,一般取名为request,你可以取别的名字,但这不符合潜规则,最好不要那么做。
- 视图函数的名称没有强制规则,但尽量不要和Python及Django内置的各种名称重名,并且尽量精确地反映出它的功能,比如这里的
current_datetime
。 - 该视图返回一个HttpResponse对象,其中包含生成的HTML页面。
PS:简单的说客户端发过来一个请求首先通过urlConf解析到对应的views视图函数当中,其中这个函数有一个参数(必写)request,这个request包含了所有的请求对象,如果我们需要返回一个字符串的话就使用HttpResponse返回一段字符串。在上面的示例中我们看见current_datetime中有一个位置参数request,它里面包含的是http请求的对象,服务器端相应的对象是HttpResponse。
render方法
render(request, template_name, context=None, content_type=None, status=None, using=None)[source]
结合一个给定的模板和一个给定的上下文字典,返回一个渲染后的HttpResponse对象。
必需参数:
- request:视图函数处理的当前请求,封装了请求头的所有数据,其实就是视图参数request。
- template_name:要使用的模板的完整名称或者模板名称的列表。如果是一个列表,将使用其中能够查找到的第一个模板。
可选参数:
- context:添加到模板上下文的一个数据字典。默认是一个空字典。可以将认可需要提供给模板的数据以字典的格式添加进去。这里有个小技巧,使用Python内置的locals()方法,可以方便的将函数作用于内的所有变量一次性添加。
- content_type:用于生成的文档的MIME类型。 默认为
DEFAULT_CONTENT_TYPE
设置的值。 - status:响应的状态代码。 默认为200。
- using:用于加载模板使用的模板引擎的NAME。
示例:
首先我们先看一下我们的urls配置文件:
再来看下我们的views对应的函数
def login(request): #客户如果是以Get方式发送数据 # request.GET #客户如果是以Post方式发送数据,获取数据需要用 #requset.(get|post):获取到的数据类型是dict query 用法和字典一样 if request.method == "POST": #判断请求方式,如果是POST走这个方法 res = request.POST username = res.get('username') 获取客户端传过来的值 password = res.get('password') if username == "Leon" and password == r'abc123,': return redirect('/index.html/') return render(request,"login.html") #如果是GET就返回一个登陆的页面
对应的template视图
首先我们得指导通过视图函数(views)渲染过后的HTML不是普通的HTML文件,它在被浏览器解析之前会对Django的一些特殊数据进行一些渲染,将数据渲染后调整成HTML页面返回给浏览器解析。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>登录页面</h1> <form action="{% url 'LOGIN' %}" method="POST"> 这里URL是一种特殊用法,意思后面就是引用urls里面定义好的别名 用户名:<p><input type="text" name="username"></p> 密码:<p><input type="password" name="password"></p> <input type="submit" value="提交"> </form> </body> </html>
redirect方法
redirect(to, permanent=False, args, *kwargs)[source]
根据传递进来的url参数,返回HttpResponseRedirect。
参数to可以是:
- 一个模型:将调用模型的
get_absolute_url()
函数,反向解析出目的url; - 视图名称:可能带有参数:reverse()将用于反向解析url;
- 一个绝对的或相对的URL:将原封不动的作为重定向的目标位置。
默认情况下是临时重定向,如果设置permanent=True
将永久重定向。
示例
1.调用对象的get_absolute_url()方法来重定向URL: from django.shortcuts import redirect def my_view(request): ... object = MyModel.objects.get(...) return redirect(object) 2.传递视图名,使用reverse()方法反向解析url: def my_view(request): ... return redirect('some-view-name', foo='bar') 重定向到硬编码的URL: def my_view(request): ... return redirect('/some/url/') 重定向到一个完整的URL: def my_view(request): ... return redirect('https://example.com/') 所有上述形式都接受permanent参数;如果设置为True,将返回永久重定向: def my_view(request): ... object = MyModel.objects.get(...) return redirect(object, permanent=True)
PS:在上面的login函数中如果留意到我们提交POST请求如果成功的话,我们return了一个 redirect('/index.html/')方法,这个就属于一种非常常用的一个方式,其中index.html是urls中定义的一个路径。记住redirect方法重定向只可以是urls中已经定义好的路径
Template模版基础
你可能已经注意到我们在例子视图中返回文本的方式有点特别。 也就是说,HTML被直接硬编码在 Python代码之中。
def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
尽管这种技术便于解释视图是如何工作的,但直接将HTML硬编码到你的视图里却并不是一个好主意。 让我们来看一下为什么:
-
对页面设计进行的任何改变都必须对 Python 代码进行相应的修改。 站点设计的修改往往比底层 Python 代码的修改要频繁得多,因此如果可以在不进行 Python 代码修改的情况下变更设计,那将会方便得多。
-
Python 代码编写和 HTML 设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同部门)来完成。 设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。
-
程序员编写 Python代码和设计人员制作模板两项工作同时进行的效率是最高的,远胜于让一个人等待另一个人完成对某个既包含 Python又包含 HTML 的文件的编辑工作。
基于这些原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式,这就是本章要具体讨论的问题。
settings.py配置引擎
模板引擎通过settings中的TEMPLATES
设置来配置。这是一个列表,与引擎一一对应,每个元素都是一个引擎配置字典。由startproject命令生成的settings.py
会自定定义如下的值:
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { # ... some options here ... }, }, ]
由于绝大多数引擎都是从文件加载模板的,所以每种模板引擎都包含两项通用设置:
- DIRS:定义了一个目录列表,模板引擎按列表顺序搜索这些目录以查找模板源文件。
- APP_DIRS:告诉模板引擎是否应该进入每个已安装的应用中查找模板。通常请将该选项保持为True。
模板(Template)基本语法
Django模板语言的语法包括四种结构。
1.变量
变量的值是来自views视图函数中render返回的一个字典或者是(locals);在模板中引用一个来自于视图函数中的一个变量也是很简单的只需要再用双大括号将变量引进去就行了({{ 变量名 }}),例如:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div class="meau"> <div class="logo">LOGO</div> </div> <h1>欢迎来到{{ username }}的页面</h1> #这里就是引用了一个username的一个变量 </body> </html>
字典查询,属性查询和列表索引查找都是通过圆点符号.
来实现。所以圆点在模版引擎中是万能的上帝,不知道该怎么写下去的时候,就尝试点点点....:
{{ my_dict.key }}
{{ my_object.attribute }}
{{ my_list.0 }}
2、标签
模版语言中的标签类似Python中的函数,功能多样,使用灵活。可以输出内容、控制结构,甚至可以访问其他的模板标签。如果申明这是一个便签可以使用{% %},例如:
我们之前在引入别名的时候就用到了标签。
部分标签需要使用起始和闭合标签,典型代表为for循环标签和if判断标签:
{% if user.is_authenticated %}Hello, {{ user.username }}.{% endif %}
{% for i in username%} {{ uesrname}} {% endfor %}
3、过滤器
过滤器用于修改变量或标签参数的值
# 1 add : 给变量加上相应的值 # # 2 addslashes : 给变量中的引号前加上斜线 # # 3 capfirst : 首字母大写 # # 4 cut : 从字符串中移除指定的字符 # # 5 date : 格式化日期字符串 # # 6 default : 如果值是False,就替换成设置的默认值,否则就是用本来的值 # # 7 default_if_none: 如果值是None,就替换成设置的默认值,否则就使用本来的值 #实例: #value1="aBcDe" {{ value1|upper }}<br> #value2=5 {{ value2|add:3 }}<br> #value3='he llo wo r ld' {{ value3|cut:' ' }}<br> #import datetime #value4=datetime.datetime.now() {{ value4|date:'Y-m-d' }}<br> #value5=[] {{ value5|default:'空的' }}<br> #value6='<a href="#">跳转</a>' {{ value6 }} {% autoescape off %} {{ value6 }} {% endautoescape %} {{ value6|safe }}<br> {{ value6|striptags }} #value7='1234' {{ value7|filesizeformat }}<br> {{ value7|first }}<br> {{ value7|length }}<br> {{ value7|slice:":-1" }}<br> #value8='http://www.baidu.com/?a=1&b=3' {{ value8|urlencode }}<br> value9='hello I am yuan'
4. 注释
模版语言的注释看起来像这样:
{# this won't be rendered #} # 单行注释
Template模板使用方法延伸
1、深度查找——万能的局点号
在到目前为止的例子中,我们通过 context render()方法的第3个参数也就是请求时的上下文 传递的简单参数值主要是字符串,然而,模板系统能够非常简洁地处理更加复杂的数据结构,例如list、dictionary和自定义的对象。在 Django 模板中遍历复杂数据结构的关键是句点字符 (.)。
#最好是用几个例子来说明一下。 # 首先,句点可用于访问列表索引,例如: >>> from django.template import Template, Context >>> t = Template('Item 2 is {{ items.2 }}.') >>> c = Context({'items': ['apples', 'bananas', 'carrots']}) >>> t.render(c) 'Item 2 is carrots.' #假设你要向模板传递一个 Python 字典。 要通过字典键访问该字典的值,可使用一个句点: >>> from django.template import Template, Context >>> person = {'name': 'Sally', 'age': '43'} >>> t = Template('{{ person.name }} is {{ person.age }} years old.') >>> c = Context({'person': person}) >>> t.render(c) 'Sally is 43 years old.' #同样,也可以通过句点来访问对象的属性。 比方说, Python 的 datetime.date 对象有 #year 、 month 和 day 几个属性,你同样可以在模板中使用句点来访问这些属性: >>> from django.template import Template, Context >>> import datetime >>> d = datetime.date(1993, 5, 2) >>> d.year >>> d.month >>> d.day >>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.') >>> c = Context({'date': d}) >>> t.render(c) 'The month is 5 and the year is 1993.' # 这个例子使用了一个自定义的类,演示了通过实例变量加一点(dots)来访问它的属性,这个方法适 # 用于任意的对象。 >>> from django.template import Template, Context >>> class Person(object): ... def __init__(self, first_name, last_name): ... self.first_name, self.last_name = first_name, last_name >>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.') >>> c = Context({'person': Person('John', 'Smith')}) >>> t.render(c) 'Hello, John Smith.' # 点语法也可以用来引用对象的方法。 例如,每个 Python 字符串都有 upper() 和 isdigit() # 方法,你在模板中可以使用同样的句点语法来调用它们: >>> from django.template import Template, Context >>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}') >>> t.render(Context({'var': 'hello'})) 'hello -- HELLO -- False' >>> t.render(Context({'var': '123'})) '123 -- 123 -- True' # 注意这里调用方法时并* 没有* 使用圆括号 而且也无法给该方法传递参数;你只能调用不需参数的 # 方法。
2、if语句的使用
{% if %}标签计算一个变量值,如果是“true”,即它存在、不为空并且不是false的boolean值,系统则会显示{% if %}和{% endif %}间的所有内容
{% if num >= 100 and 8 %} {% if num > 200 %} <p>num大于200</p> {% else %} <p>num大于100小于200</p> {% endif %} {% elif num < 100%} <p>num小于100</p> {% else %} <p>num等于100</p> {% endif %} {% if %} 标签接受and,or或者not来测试多个变量值或者否定一个给定的变量 {% if %} 标签不允许同一标签里同时出现and和or,否则逻辑容易产生歧义,例如下面的标签是不合法的: {% if obj1 and obj2 or obj3 %}
3、for语句的使用
{% for %}标签允许你按顺序遍历一个序列中的各个元素,每次循环模板系统都会渲染{% for %}和{% endfor %}之间的所有内容
<ul> {% for obj in list %} <li>{{ obj.name }}</li> {% endfor %} </ul> #{% for %}标签可以嵌套: {% for country in countries %} <h1>{{ country.name }}</h1> <ul> {% for city in country.city_list %} <li>{{ city }}</li> {% endfor %} </ul> {% endfor %} #系统不支持中断循环,系统也不支持continue语句,{% for %}标签内置了一个forloop模板变量, #这个变量含有一些属性可以提供给你一些关于循环的信息 1,forloop.counter表示循环的次数,它从1开始计数,第一次循环设为1: {% for item in todo_list %} <p>{{ forloop.counter }}: {{ item }}</p> {% endfor %} 2,forloop.counter0 类似于forloop.counter,但它是从0开始计数,第一次循环设为0 3,forloop.revcounter 4,forloop.revcounter0 5,forloop.first当第一次循环时值为True,在特别情况下很有用: {% for object in objects %} {% if forloop.first %}<li class="first">{% else %}<li>{% endif %} {{ object }} </li> {% endfor %} # 富有魔力的forloop变量只能在循环中得到,当模板解析器到达{% endfor %}时forloop就消失了 # 如果你的模板context已经包含一个叫forloop的变量,Django会用{% for %}标签替代它 # Django会在for标签的块中覆盖你定义的forloop变量的值 # 在其他非循环的地方,你的forloop变量仍然可用 #{% empty %} {{li }} {% for i in li %} <li>{{ forloop.counter0 }}----{{ i }}</li> {% empty %} <li>this is empty!</li> {% endfor %} # [11, 22, 33, 44, 55] # 0----11 # 1----22 # 2----33 # 3----44 # 4----55
4、更多补充
略
数据库操作ORM
一、什么是ORM:
ORM:Object Relational Mapping,关系对象映射,这里的object在这里也就是指的Python里面的类了。实际上就是用Python中的类对应了数据库中的一张表。Python中的实例对应了表的记录。
总结:一个模型(model)就是一个单独的、确定的数据的信息源,包含了数据的字段和操作方法。通常,每个模型映射为一张数据库中的表。
基本的原则如下:
- 每个模型在Django中的存在形式为一个Python类
- 每个模型都是django.db.models.Model的子类
- 模型的每个字段(属性)代表数据表的某一列
- Django将自动为你生成数据库访问API
二、支持的数据库类型
sqllite、mysql、Oracle、postgresql,默认Django中使用的是SQLlite数据库。如果我们想使用mysql数据库的话需要在settings.py中设置。
三、对应关系模型创建
四、django的ORM基本使用
from mysite import models #django 的 views视图函数 def add_book(requests): #使用ORM在数据库创建一条记录 #创建方式一 models.Books.objects.create(title='三体',name='刘佩慈') #创建方式二 b=Books(title="aaa",name='bbb') b.save() def del_book(requests): #删除一个数据 name = requests.POST.get('name') models.Books.objects.filter(name=name).delete() def edit_book(requests): 更新一条数据 name = requests.POST.get('name') #第一种方式 b = models.Books.object.get(name=name) #此数据必须是一个,要不就报错 b.title('cccc') b.save() #第二种方式 b1 = models.Books.object.filter(name=name).update(title="cccc")