在Django中使用静态文件js等时,首先需要配置setting文件
BASE_DIR1=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = '/abc/'
#以abc来代替static,此后html中关于static的均可以写为abc
#因为后端出现问题时,可能会对static进行改名,此时前端再不可对static进行引用,但是使用abc时,不论后端怎么变换,前端均可以用abc引用
#为了后端的更改不会影响前端的引入,避免造成前端大量修改
STATICFILES_DIRS=( # 配置js等静态文件
os.path.join(BASE_DIR1,"static"),
)
这时在和templates同目录下创建static目录,并将静态文件拖入。
Html文件引用时以以下格式 此时用abc代替static
<script src="/abc/js/jquery-2.1.4.min.js"></script>
<script>
$("h1").css("color","red")
</script>
Django URL (路由系统)
urlpatterns = [
url(正则表达式, views.视图函数,参数,别名),
]
无名分组
urlpatterns = [
url(r'^articles/2003/$', views.special_case),# 完全匹配,函数名为special_case 只可匹配URl:http://127.0.0.1:8090/articles/2003/ 若无$则可匹配2003再加后缀的
url(r'^articles/[0-9]{4}/$', views.year_archive),
# 若好几个同时匹配,返回最前的那个
url(r'^articles/([0-9]{4})/$', views.year_archive), # 加括号表示把括号里面的当做参数传给函数
url(r'^articles/([0-9]{4})/([0-9]+)/$', views.year_archive),# + 1到重复无穷次 传两个参数
]
def year_archive(req,x,y):
return HttpResponse("year"+x+y)
有名分组
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]+)/$', views.year_archive),# 有名分组,后续参数必须和其同名 year month
def year_archive(req,year,month):
return HttpResponse("year"+year+month)
参数三
url(r'^articles/(?P<name>[0-9]{4})/', views.year_archive,{"name":"zzz"}),# 当为两个name值时,在函数传参时,后面的字典值对其进行覆盖。
参数四
url(r'index/',views.index_f,name="zzz"),
def index_f(req):
if req.method=='POST':
name = req.POST.get("user",None)
paswd = req.POST.get("psw",None)
if name !=None and paswd !=None:
return HttpResponse("hhh")
return render(req,"in.html")
<body>
<!--<form action="/index/" method="post">原来的写法-->
<form action="{% url 'zzz' %}" method="post">
name参数实际上也是为了后端的改变不影响前端使用
事实上,render将其渲染为第一种形式后发送给浏览器
<input type="text" name="user">
<input type="password" name="psw">
<input type="submit" value="submit">
</form>
</body>
如果将所有的url分配都放在全局的urlpatterns下,会造成全局错误率高的问题,需要再次进行解耦。路由分发,全局只进行指派
首先在app01下建立urls.py文件 再在全局urls.py文件下指派
url(r'^app01/',include("app01.urls")),
在app下的urls.py文件中进行url分配
from django.contrib import admin
from django.conf.urls import url,include
from app01 import views
urlpatterns = [
url(r'story',views.introduce),
]
在app的views中写函数
def introduce(req):
return HttpResponse("ok")
访问url为 http://127.0.0.1:8090/app01/story
request即上文提到的req,有以下属性和方法
path: 请求页面的全路径,不包括域名
method:请求中使用的HTTP方法的字符串表示。全大写表示。例如
if req.method=="GET":
do_something()
elseif req.method=="POST":
do_something_else()
GET: 包含所有HTTP GET参数的类字典对象
POST: 包含所有HTTP POST参数的类字典对象
服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过HTTP POST方法提交请求,但是表单中可能没有数据。
因此不能使用if req.POST来判断是否使用了HTTP POST 方法;应该使用 if req.method=="POST"
COOKIES:包含所有cookies的标准Python字典对象;keys和values都是字符串。
FILES: 包含所有上传文件的类字典对象;FILES中的每一个Key都在<input type="file" name="" />标签中
name属性的值,FILES中的每一个value同时也是一个标准的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支持时该属性才可用。
方法
get_full_path()
比如:http://127.0.0.1:8000/index33/?name=123 ,req.get_full_path()得到的结果就是/index33/?name=123
req.path: 得到的结果为/index33
对于HttpRequest对象来说,是由django自动创建的,但是,HttpResponse对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse对象。HttpResponse类在django.http.HttpResponse中
在HttpResponse对象上扩展的常用方法:
页面渲染: render() render_to_response(),
页面跳转: redirect(“路径”)
locals(): 可以直接将函数中所有的变量传给模板
url(r'index',views.index_f)
def index_f(req):
if req.method=='POST':
name = req.POST.get("user",None)
paswd = req.POST.get("psw",None)
if name =="333" :
return redirect("http://www.baidu.com") # 重定向到百度
else:
return redirect("/app01/index") # 重定向至本页面index
a=1
b=2
c=3
# return HttpResponse("<h1>hhh</h1>")
# return render(req,"in.html",locals())
# 将本地变量全部传给html,使其可以在html中以{{a}}{{b}}{{c}}形式拿取
return render(req, "in.html")
<form action="/app01/index/" method="post">
<input type="text" name="user">
<input type="password" name="psw">
<input type="submit" value="submit">
</form>
redirect和render的区别
url设置
url(r'index',views.index_f),
url(r"info", views.story),
views
from django.shortcuts import render, HttpResponse, redirect
import datetime
def index_f(req):
if req.method == "POST":
name = req.POST.get("user",None)
if name == "zz":
return redirect("/app01/info") # 重定向到url info执行story函数 状态框url改变
else:
return render(req,"story.html") # 直接执行html文件,不渲染 不改变状态框url
return render(req, "in.html")
def story(req):
name = "zz"
return render(req,"story.html",{"name":name})
story.html
<h1>hello {{name}}</h1>
in.html
<form action="/app01/index/" method="post">
<input type="text" name="user">
<input type="password" name="psw">
<input type="submit" value="submit">
</form>
Template基础
将页面的设计和Python的代码分离开。设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。
组成:HTML代码+逻辑控制代码
Template和Context对象
"*.html"模板
{“key”:“value”,}上下文
python manage.py shell (进入该django项目的环境)
from django.template import Context, Template
t = Template('My name is {{ name }}.')
c = Context({'name': 'zz'})
t.render(c)
'My name is zz.'
渲染多个context
t = Template('Hello, {{ name }}')
for name in ('John', 'Julie', 'Pat'):
print(t.render(Context({'name': name})))
import datetime
from django.template import Template,Context
# def current_time(req):
# 原始的视图函数
# now=datetime.datetime.now()
# html="<html><body>现在时刻:<h1>%s.</h1></body></html>" %now 字符串格式化
# return HttpResponse(html)
# def current_time(req):
# django模板修改的视图函数
# now=datetime.datetime.now()
# t=Template('<html><body>现在时刻是:<h1 style="color:red">{{current_date}}</h1></body></html>')
#或t=get_template('current_datetime.html')
# c=Context({'current_date':now})
# html=t.render(c)
# return HttpResponse(html)
def current_time(req):
now=datetime.datetime.now()
return render(req, 'current_datetime.html', {'current_date':now})
深度变量的查找(万能的句点号)
函数传递参数
def index_f(req):
# s2=[1,2,3,4,5,9]
# return render(req, "info.html", {"list": s2})
# s3={"A":"a","B":"b"}
# return render(req, "info.html", {"obj": s3})
# s4=datetime.datetime.now()
# return render(req, "info.html",{"obj":s4})
class Person:
def __init__(self,name,age):
self.name=name
self.age=age
s5=Person("zz",22)
return render(req, "info.html",{"obj":s5})
模板使用参数
<body>
{{ list.2 }}
取list数据,从索引0开始
{{ obj.A }}
根据键取dic的值
{{ obj.year }}
{{ obj.month }}
用.取输入时间数据的属性
{{ obj.name }}
{{ obj.age }}
用.取自定义类的属性
</body>
for循环和if else语句
<body>
if语句 0 不满足 1 满足 返回hello2
{% if 0%}
<p>hello1</p>
{% elif 1 %}
<p>hello2</p>
{% endif %}
s2=[1,2,3,4,5,9]
列表i中存储值
{% for i in list %}
<p>{{ i }}</p>
{% endfor %}
若想拿到索引,从1开始
{% for i in list %}
<p>{{ forloop.counter }} {{ i }}</p>
{% endfor %}
若想拿到索引,从0开始
{% for i in list %}
<p>{{ forloop.counter0 }} {{ i }}</p>
{% endfor %}
s3={"A":"a","B":"b"}
字典拿键
{% for i in obj %}
<p>{{ forloop.counter0 }} {{ i }}</p>
{% endfor %}
</body>
filter过滤器
{{obj|filter:param}}
1 add : 给变量加上相应的值
2 addslashes : 给变量中的引号前加上斜线
3 capfirst : 首字母大写
4 cut : 从字符串中移除指定的字符
5 date : 格式化日期字符串
6 default : 如果值是False,就替换成设置的默认值,否则就是用本来的值
7 default_if_none: 如果值是None,就替换成设置的默认值,否则就使用本来的值
事例 变量前端传
<body>
{"obj": "helLo"}
将传递的字符串大写
{{ obj|upper }}
小写
{{ obj|lower }}
取第一个字母
{{ obj|first }}
首字母大写
{{ obj|capfirst }}
{"value2":value}
{{ value2|add:3 }}
value3='he llo wo r ld'
{{ value3|cut:' ' }}
value4=datetime.datetime.now()
{{ value4|date:'Y-m-d' }}<br>
value5=[]
{{ value5|default:'空' }}<br>
value6='<a href="#">跳转</a>'
{{ value6 }}只显示字符串,不进行渲染
{{ value6|safe }}渲染为链接 如果有html标签就渲染
{% autoescape off %}
{{ value6 }}渲染为链接
{% endautoescape %}
value7='1234'
{{ value7|filesizeformat }}
{{ value7|first }}1
{{ value7|length }}4
{{ value7|slice:":-1" }}123
</body>
{%csrf_token%}:csrf_token标签
MIDDLEWARE中的'django.middleware.csrf.CsrfViewMiddleware'
, 表单提交时出现forbidden页面
{%csrf_token%}可以防止出现这种情况 他会自行渲染一个input标签,用于防治跨站攻击验证
<form action="/app01/index/" method="post">
<input type="text" name="user">
<input type="password" name="psw">
<input type="submit" value="submit">
{%csrf_token%}
</form>
{% with %}:用更简单的变量名替代复杂的变量名
{% with total=fhjsaldfhjsdfhlasdfhljsdal %} {{ total }} {% endwith %}
{% verbatim %}: 禁止渲染 输出{{ hello }}
{% verbatim %}
{{ hello }}
{% endverbatim %}
自定义filter和simple_tag
在包app01中创建templatetags模块(必须的)
templatetags包中创建任意 .py 文件,如:my_tags.py
from django import template
from django.utils.safestring import mark_safe
register = template.Library() # register的名字是固定的,不可改变
@register.filter # 装饰器
def add100(v1):
return v1 +100
@register.filter
def filter_multi(v1,v2):
return v1 * v2
@register.simple_tag
def simple_tag_multi(v1,v2):
return v1 * v2
@register.simple_tag
def my_input(id,arg):
result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
return mark_safe(result)
在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py :{% load my_tags %}
在settings中的INSTALLED_APPS配置当前app–app01,不然django无法找到自定义的simple_tag.
{% load my_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ num|add100 }} 管道符调用 参数有限最多两个
{{ num|filter_multi:2 }}
{% simple_tag_multi num 5 %} 标签调用 参数不限
</body>
</html>
def index_f(req):
return render(req, "sss.html",{"num":100})
注意:
filter可以用在if等语句后,simple_tag不可
{% if num|filter_multi:30 > 100 %}
{{ num|filter_multi:30 }}
{% endif %}