框架Django原理及基础二

在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 %}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值