小生博客:http://xsboke.blog.51cto.com
-------谢谢您的参考,如有疑问,欢迎交流
一、静态文件
二、路由映射
三、视图函数
四、template(模板)基础
-
关于静态文件
1.1 首先需要在配置文件settings.py中指定静态目录
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"statics"),
)1.2 然后在html中使用django模板语言指定静态文件
{% load static from staticfiles %}1.3 也可以这样写
# 指定前缀 STATIC_URL = '/a/' STATICFILES_DIRS = ( os.path.join(BASE_DIR,"statics"), )
-
路由映射
Django URL是一个URL和视图函数的映射表
urlpatterns = [
path('admin/', admin.site.urls),
]urlpatterns = [
url(正则表达式,views视图函数,参数,别名)
]
参数:可选的要传递给视图函数的默认参数
别名:一个可选的name参数,用于前端注意:要想使用url去配置路径需要加载模块:from django.conf.urls import url
2.1 无名分组
url(r'^articles/[0-9]{4}/([0-9]{4})/([0-9]+)/$',views.special_case_2018),
^articles:以articles开头匹配articles
/:目录符号
[0-9]{4}:包含一个4位数,每一位的范围是0-9
():加括号的意思是传入一个参数
这时候,views.py需要这样写(使用HttpResponsen需要导入这个模块):
def special_case_2018(req,变量) #可以传入多个变量,用逗号分隔
return HttpResposen(变量+"year") #将用户输入的内容返回到浏览器上2.2 命名分组
2.2.1 讲解
import reret = re.search('(?P
\d{3})/(?P \w{3})','weeew34ttt123/ooo') ?P:固定格式,意思是这种分组是有名字的 :匹配的名字就是id,可以看做是一个变量,是匹配内容的变量 \d{3}:是匹配的内容,3个数字。 \w{3}:就是3个字母 'weeew34ttt123/ooo':这段字符串就是被匹配的内容,最终结果会匹配出"123/ooo" print(ret.group()) :取出所有匹配到的内容 print(ret.group('id')) :只取出名字为的id的内容 print(ret.group('name')):只取出名字为的name的内容 2.2.2 url格式
urlpatterns = [
url(r'^articles/(?P[0-9]{4})/(?P [0-9]{4})/$',views.year_archive),
]views.py配置 def year_archive(req,year,month): # 使用命名分组,形参必须是url中定义的名字,顺序可以不同 return HttpResposen(year+"y"+month+"m")
2.3 参数三
urlpatterns = [
url(r'index',views.index,{"name":'dashan'}),
]def index(req,name): return HttpResposen(name) # 返回"dashan" # 如果在使用参数的同时,使用了命名分组,两边的名字如果一样,那么参数会覆盖命名分组
2.4 参数四
urlpatterns = [
url(r'index',views.index,name="dashan"), # name是固定的写法,name就是别名
] # name="dashang",代替的就是index,就是index的别名这时候,前端可以通过别名去找到视图函数
2.5 url映射分发(include)
当有上万页面时,你就得在urls.py中写上万条url匹配,造成数据量大,容易写重,容易造成结藕解决方法:在每个app下创建一个urls.py,全局的urls.py只做一个映射 2.5.1 全局urls.py from django.conf.urls import url,include from appname import views urlpatterns = [ url(r'^appname',include('appname.urls')), ] 2.5.2 app的urls.py from django.conf.urls import url,include urlpatterns = [ url(r'page1/page1.1',views.page1), # page1是紧跟appname的内容 url(r'page2',views.page2), ]
-
视图函数
HTTP请求中产生两个核心对象:
http请求:HttpRequest对象
http响应:HttpResponse对象
所在位置:django.http# 获取两种请求方法 request.POST.get request.GET.get
3.1 HttpRequest对象的属性
path: 请求页面的全路径,不包括域名
method: 请求中使用的HTTP方法的字符串表示,全大写表示。例如GET和POST
if req.method == "POST" or req.method == "GET"
GET: 包含所有HTTP GET参数的类字典对象
POST: 包含所有HTTP POST参数的类字典对象
服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过
HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用
if req.POST 来判断是否使用的HTTP POST 方法,应该使用 if req.method == "POST"COOKIES: 包含所有cookies的标准python字典对象;key和values都是字符串 FILE: 包含所有上传文件的类字典对象;files中的米一个key都是标签中 name的属性值,files中的每一个values同时也是一个标准的python字典对象,包含下面是哪个keys: filename: 上传文件名,用字符串表示 content_type: 上传文件的Content Type content: 上传文件的原始内容 user: 是一个Django.contrib.auth.models.User对象,代表当前登录的用户,如果访问用户当前没有登录, user将初始化为django.contrib.auth.models.AnonymousUser的实例。你可以通过user的 is_authenticated()方法来辨别用户是否登录: if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware时,该属性 才可用 session: 唯一可读写的属性,代表当前会话的字典对象;只有激活Django中的session支持时该属性才可用
3.2 HttpResponse对象
对于HttpRequest对象来说,是由django自动创建的,但是,HttpResponse对象就必须我们自己创建,
每个view请求处理方法必须返回一个HttpResponse对象。HttpResponse类在django.http.HttpResponse 在HttpResponse对象上扩展的常用方法: 页面渲染: render(),render_to_response(), # 使用render_to_response()方法需要引入render_to_response模块 return render(req,"index.html") return render_to_response("index.html") -- 有坑不建议使用 本地变量:locals(): 可以直接将函数中所有的变量传给模板,locals是本地变量的意思,将本地变量传入html中 例: views.py 中写 name="dashan" return render_to_response("index.html",{"a":name}) html就得写 {{ a }} 当views.py 这样写 name="dashan" return render_to_response("index.html",locals()) html就可以这样写,直接调用变量,而不需要使用参数调用 {{ name }} 注意,使用render也可以 页面跳转(重定向): redirect() return redirect("http://www.baidu.com") return redirect("http://www.baidu.com") render 是直接渲染某个页面并返回,redirect是重定向到指定的views函数,同时也会做一定的判断, 比如用户登录。
-
template基础
在向前端输出字符串时使用模板语言进行处理,而不是使用 "欢迎 %s 登录" %(name) ,这种方式是为了实现前后端分离
什么是模板语言?
格式:HTML + 逻辑控制语句,如果HTML中存在模板语言,则HTML就叫模板,而不是HTML模板语言的作用?
起到前端到后端的纽带作用render(request,"index.html",{"name":name}) "index.html" 就叫模板 {"name":name} 就叫上下文,Context 在pycharm的terminal界面输入python manage.py shell即可进入当前django的命令行 输入: >>> t=Template("hello {{ name }}") 创建模板语言 >>> c=Context({"name":"dashan"}) 创建上下文 >>> t.render(c) 渲染模板语言和上下文 'hello dashan'
4.1 一次模板创建,多次调用render()实现更高效的渲染
t = Template("hello, {{ name }}") for name in ('dashan','lisi','wangwu'): print t.render(Context({'name'}:name)) 在view中使用Template和Context需要引入,from django.template import Template,Context
4.2 深度变量的查找(万能的句点号".")
import datetime def index(req): s=[1,2,3,4] s2={"uname":"dashan","sex":23} s3=datetime.datetime.now() class Person: def __init__(self,name,age): self.name = name self.age = age s4=Person("dashan",18) return render(req,"index.html",{"list":s}) return render(req,"index.html",{"obj":s2}) return render(req,"index.html",{"time":s3}) return render(req,"index.html",{"P":s4})
Template
{{ list.2}} {{ obj.sex}} {{ time.year }} {{ time.month }} {{ P.age }} {{ P }}4.3 if和for循环
4.3.1 if,只支持布尔值True或者False,1(True)和(False)也可以 { % if True % }
hello world
{ % elif obj % }hello2
{ % endif % } 4.3.2 for # 用列表举例 { % for i in list % }{{ i }}
{{ forloop.counter }}:{{ i }}
{{ forloop.counter0 }}:{{ i }}
{{ forloop.revcounter }}:{{ i }}
{ % endfor % } # 用字典举例 { % for i in obj % }{{ forloop.counter }}:{{ i }}
{{ forloop.counter }}:{{ i.uname }}
{ % endfor % } # 字典的使用方法 {% for row in user_dict.keys %} {% for row in user_dict.values %} {% for row in user_dict.items %} 得到元组 {% for k,row in user_dict.items %} - {{k}}-{{row}}
{% endfor %}
4.4 过滤器filter
{{ ship_date|date:"Fj,Y"}}
ship_date变量传给date过滤器,date过滤器通过使用"Fj,Y"这几个参数来格式化日期数据,
"|"和unix的管道符类似
s = "hello"
s2 = 1
s3 = datetime.datetime.now()
s4 = []
s5 = "百度"
return render(req,"index.html",{"obj":s})
return render(req,"index.html",{"num":s2})
return render(req,"index.html",{"time":s3})
return render(req,"index.html",{"kong":s4})
return render(req,"index.html",{"a":s5})
{{ 对象|方法:参数}} - 格式
{{ obj }} - 打印结果"hello".
{{ obj|upper }} - 使用模板语言中的upper方法,将"hello"转为大写"HELLO".
{{ obj|lower }} - 小写
{{ obj|firest }} - 取出第一个字母
{{ obj|capfirest }} - 将第一个字母大写
{{ num|add:5 }} - num+5 ,结果为6
{{ 对象|cut: ' '}} - 去除空格
{{ time|date: 'Y-m-d'}} - 输出年月日,"-"也可以写为":"
{{ kong|default: '空的'}} - 当对象为空时,输出default指定的字符串,如果不为空则输出对象
{{ % a % }} - 会将超链接返回为一个字符串,因为浏览器会认为是不安全的
{ % autoescape off % } - 这样浏览器就能解析为html语言了,浏览器就认为是安全的
{{ % a % }}
{ % endautoescape % }
{{ a|safe }} - 这个和上面那个是一样的功能,会告诉浏览器这是安全的
{{ obj|filesizeformat }} - 打印对象的大小
{{ obj|length }} - 打印对象的长度
{{ obj|slice: ':-1' }} - 切片,从头切到最后一个,最后一个不要
{{ a|urlencode }}
values="hello I am shan"
{{ values|truncatechars:'6' }} 按字符截取
{{ values|truncatewords:'2' }} 按单词截取
注意:为什么要在前端转而不是后端,试想一下如果输入的是一个字典类型的数据,需要
for循环完后的数据输出为大写,如果你在后端做这个操作的话就会变得很繁琐,需要
循环完后赋予一个变量才能转给前端
4.5 中间件 csrf 跨站请求伪造
用于生成csrf_token的标签,用于防治跨站***验证。
用于验证form表单
注意:
同时如果你在views.py中返回页面时使用 render_to_response,需要这样写
from django.template import RequestContext,Template
return render_to_response("index.html",context_instent=RequestContext(request))
否则也会报错Forbidden,所以之前才不建议使用render_to_response
4.6 { % load % } - 加载标签库
4.7 { % url % } - 引用路由配置的地址
4.8 { % with % } - 用更简单的变量名替代复杂的变量名
{ % with total=fadsfsadfdsaffdsaf % } {{ total }} { % endwith % }
格式:{ % with 新变量名=旧变量名 % } {{ 新变量名 }} { % endwith % }
4.9 { % varbatim % } - 禁止render
{ % varbatim % } - name就不会渲染了,输出的就是字符串"{{ name }} "
{{ name }}
{ % endvarbatim % }
4.10 自定义 simple_tag
需求:比如后端传给了前端一个变量num=1,我想让这个变量在前端+10,
原本我可以在前端写为 {{ num|add:'10'}},但是我想使用自定义的方法
{{ num|add100 }},这就叫做自定义simple_tag(简单标签)
a. 在app目录下中创建templatetags模块
b. 创建任意.py文件,如文件名"my_tag.py"
#!/usr/bin/evn python
#coding:utf-8
from django import template
from django.utils.safestring import mark_safe
register = template.Library() # register是固定变量名,不能改变
@register.simple_tag # 装饰器
def my_add100(v1):
return v1 + 10 # 实现num+10
@register.simple_tag
def my_input(id,arg):
result = "" %(id.arg)
return mark_safe(result)
c. 在使用自定义simple_tag的html文件中引入之前创建的mytag.py文件名
{ % load my_tag % }
d. 使用simple_tag
{ % my_add100 1 % }
{ % my_input id1 cl1 % }
4.11 自定义filter
流程和自定义 simple_tag一样,就差在
@register.simple_tag了,自定义filter是这样写@register.filter
调用方式为
{{ num|my_add100 }}
如果自定义filter传入的是两个参数,最多也只能两个(自定义 simple_tag没有这个限制),
解决方法是传入一个列表
@register.filter # 装饰器
def my_add100(v1,v2):
return v1 + 10 + v2
{{ num|my_add100:2 }}
注意:模板的if语句可以加一个自定义filter,但是不能加自定义simple_tag
同时,使用自定义简单标签和自定义filter,必须在全局文件settings.py中的
INSTALLED_APPS [
'myapp',
]
区域添加你的app名