2017做电商做什么网站,如何设计制作企业网站,网奇seo培训官网,域名提供商今日回内容
视图层 响应对象 cbv和fbv 上传文件
模板层
视图层
一、响应对象
响应对象的本质都是 HttpResponse HttpResponse:字符串 render#xff1a; 将一个模板页面中的模板语法进行渲染#xff0c;最终渲染成一个html页面作为响应体。 redirect#xff1a;重定向 …今日回内容
视图层 响应对象 cbv和fbv 上传文件
模板层
视图层
一、响应对象
响应对象的本质都是 HttpResponse HttpResponse:字符串 render 将一个模板页面中的模板语法进行渲染最终渲染成一个html页面作为响应体。 redirect重定向 向前端返回一个json格式字符串
render() render(request, template_name[, context] 结合一个给定的模板和一个给定的上下文字典并返回一个渲染后的 HttpResponse 对象。 参数 request 用于生成响应的请求对象。 template_name要使用的模板的完整名称可选的参数 context添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的视图将在渲染模板之前调用它。 render方法就是将一个模板页面中的模板语法进行渲染最终渲染成一个html页面作为响应体。 redirect() 传递要重定向的一个硬编码的URL def my_view(request): ... return redirect(/some/url/) 也可以是一个完整的URL def my_view(request): ... return redirect(http://www.baidu.com/) 1301和302的区别。 301和302状态码都表示重定向就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址这个地址可以从响应的Location首部中获取 用户看到的效果就是他输入的地址A瞬间变成了另一个地址B——这是它们的共同点。 他们的不同在于。301表示旧地址A的资源已经被永久地移除了这个资源不可访问了搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址 302表示旧地址A的资源还在仍然可以访问这个重定向只是临时地从旧地址A跳转到地址B搜索引擎会抓取新的内容而保存旧的网址。 SEO302好于301 2重定向原因 1网站调整如改变网页目录结构 2网页被移到一个新地址 3网页扩展名改变(如应用需要把.php改成.Html或.shtml)。 这种情况下如果不做重定向则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息访问流量白白丧失再者某些注册了多个域名的 网站也需要通过重定向让访问这些域名的用户自动跳转到主站点等。 JsonResponse 向前端返回一个json格式字符串的两种方式 # 第一种方式 # import json # data{name:lqz,age:18} # data1[lqz,egon] # return HttpResponse(json.dumps(data1)) # 第二种方式 from django.http import JsonResponse # data {name: lqz, age: 18} data1 [lqz, egon] # return JsonResponse(data) return JsonResponse(data1,safeFalse) JsonResponse源码分析
return JsonResponse({name:lqz,age:19})
# 触发 JsonResponse的__init__---{name:lqz,age:19}给了data
def __init__(self, data, encoderDjangoJSONEncoder, safeTrue,json_dumps_paramsNone, **kwargs):# 如果传入的四字典# safe是True后面是False条件不符合内部就不会走if safe and not isinstance(data, dict):raise TypeError(In order to allow non-dict objects to be serialized set the safe parameter to False.)if json_dumps_params is None: # 条件符合json_dumps_params {}# kwargs是字典---》setdefault--》有则修改无则新增kwargs.setdefault(content_type, application/json)# 核心---》把字典转成json格式字符串赋值给datadata json.dumps(data, clsencoder, **json_dumps_params)# super().__init__ 调用父类的 __init__ 完成实例化---》HttpResponse的对象return HttpResponse(data,**kwargs)super().__init__(contentdata, **kwargs) 二、cbv和fbv
FBVfunction base views 基于函数的视图就是在视图里使用函数处理请求。
CBVclass base views 基于类的视图就是在视图里使用类处理请求。
CBV
cbv写法
from django.views import View
class UserView(View):# 写方法---》跟请求方式同名的方法def get(self,request,*args,**kwargs)必须返回四件套 路由配置
path(index/, 视图类名.as_view()) # as_view是类的绑定方法 执行流程
path(index/, index),---请求来了路由匹配成功会执行 index(request,)
path(index/, UserView.as_view()),
# 1 入口路由---》as_view来开始-请求来了路由匹配成功---》执行---》UserView.as_view()(request)-需要看as_view()执行结果是什么--》view--》代码如下def view(request, *args, **kwargs): # 方法可以加括号调用return self.dispatch(request, *args, **kwargs)-本质就是在执行 view(request)-本质在执行---》self.dispatch(request, *args, **kwargs)-去类UserViwe类中找找不到去父类View中找dispatch代码如下def dispatch(self, request, *args, **kwargs):# request当次请求的请求对象取出请求方式【假设是get请求】转成小写 get# http_method_names [get, post, put]# 条件成立执行if内部代码if request.method.lower() in self.http_method_names:#getattr反射---》通过字符串去对象中取属性或方法# self是谁的对象 是View这个类的对象这个是视图类UserView的对象# 取出来的handler 是 UserView这个类的get方法handler getattr(self, get)else:handler self.http_method_not_allowed# handler是 UserView这个类的get方法# get(request)---》触发UserView这个类的get方法---》真正执行原来视图函数的内容# 最终返回return handler(request, *args, **kwargs) 总结cbv只需要在视图类中写跟请求方式同名的方法即可--》不同请求方式就会执行不同的方法 1.1 关于self是谁的问题
class Animal:def run(self):# 这个self是谁调用就是谁print(type(self))print(self.name, 走路)class Person(Animal):def __init__(self, name):self.name nameclass Dog(Animal):def __init__(self, name,age):self.name nameself.ageage
p Person(lqz)
p.run() # lqz 走路
self 是谁调用。self就是谁不能只看是哪个类 以后看到self.方法的时候不要只从当前类或父类中找应该先确定当前self是谁然后从这个对象的类根上开始找
三、上传文件
## 关于模板查找路径是配置文件中
TEMPLATES ---DIRS: [os.path.join(BASE_DIR, templates)]## python
class FileView(View):def get(self,request):return render(request,file.html)def post(self,request):# 拿出文件对象my_filerequest.FILES.get(myfile)print(type(my_file)) #django.core.files.uploadedfile.InMemoryUploadedFile 跟之前用的文件对象不一样但是它应该继承了文件from django.core.files.uploadedfile import InMemoryUploadedFile# 1 保存 2 取出文件名字# my_file.save() #找了一顿没有所以不能使用快捷保存方式需要自己写保存print(my_file.name) # 3-回顾django.md# 自己写保存,放在项目根路径下with open(my_file.name,wb) as f:for line in my_file:f.write(line)return HttpResponse(上传成功)
# html
!DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/title/head
body
form action methodpost enctypemultipart/form-datainput typefile namemyfilebrinput typesubmit value提交
/form
/body
/html 模板层
介绍
模板在浏览器中是运行不了的因为它有模板语法浏览器解析不了模板语法 必须在后端渲染完成(替换完成)变成纯粹的htmlcssjs 这种在后端会被渲染的类python语法它叫 模板语法django中它又叫 dtldjango template language
模板语法
传值
第一种方法手动将所有内容放入字典内进行传递
from django.shortcuts import render
def index(request):dic {name:123}return render(index.html,dic)第二种方法将当前名称空间中所有的变量名与值全部传递
from django.shortcuts import render
def index(request):return render(index.html,local())区别第一种比第二种方法传值更精确没有资源浪费
过滤器
语法
{{obj|filter__name:param}} 变量名字|过滤器名称变量default
如果一个变量是false或者为空使用给定的默认值。否则使用变量的值。例如
{{ value|default:nothing}}length
返回值的长度。它对字符串和列表都起作用。例如
{{ value|length }}如果 value 是 [‘a’, ‘b’, ‘c’, ‘d’]那么输出是 4。
filesizeformat
将值格式化为一个 “人类可读的” 文件尺寸 例如 13 KB, 4.1 MB, 102 bytes, 等等。例如
{{ value|filesizeformat }}如果 value 是 123456789输出将会是 117.7 MB。
date
如果 valuedatetime.datetime.now()
{{ value|date:Y-m-d}}slice
如果 value”hello world”
{{ value|slice:2:-1}}truncatechars
如果字符串字符多于指定的字符数量那么会被截断。截断的字符串将以可翻译的省略号序列“…”结尾。
参数要截断的字符数
例如
{{ value|truncatechars:9}}safe
Django的模板中会对HTML标签和JS等语法标签进行自动转义原因显而易见这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义比如我们做一个内容管理系统后台添加的文章中是经过修饰的这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如
valuea href点击/a
{{ value|safe}}
标签
标签看起来像是这样的 {% tag %}
标签比变量更加复杂一些在输出中创建文本一些通过循环或逻辑来控制流程一些加载其后的变量将使用到的额外信息到模版中。
一些标签需要开始和结束标签 例如{% tag %} ...标签 内容 ... {% endtag %}for标签
遍历每一个元素
{% for person in person_list %}p{{ person.name }}/p
{% endfor %}#可以利用{% for obj in list reversed %}反向完成循环。遍历一个字典
{% for key,val in dic.items %}p{{ key }}:{{ val }}/p
{% endfor %}注循环序号可以通过forloop显示
forloop.counter The current iteration of the loop (1-indexed) 当前循环的索引值从1开始
forloop.counter0 The current iteration of the loop (0-indexed) 当前循环的索引值从0开始
forloop.revcounter The number of iterations from the end of the loop (1-indexed) 当前循环的倒序索引值从1开始
forloop.revcounter0 The number of iterations from the end of the loop (0-indexed) 当前循环的倒序索引值从0开始
forloop.first True if this is the first time through the loop 当前循环是不是第一次循环布尔值
forloop.last True if this is the last time through the loop 当前循环是不是最后一次循环布尔值
forloop.parentloop 本层循环的外层循环for … empty
# for 标签带有一个可选的{% empty %} 从句以便在给出的组是空的或者没有被找到时可以有所操作。
{% for person in person_list %}p{{ person.name }}/p{% empty %}psorry,no person here/p
{% endfor %}if 标签
# {% if %}会对一个变量求值如果它的值是True存在、不为空、且不是boolean类型的false值对应的内容块会输出。{% if num 100 or num 0 %}p无效/p
{% elif num 80 and num 100 %}p优秀/p
{% else %}p凑活吧/p
{% endif %}if语句支持 and 、or、、、、!、、、in、not in、is、is not判断。with
使用一个简单地名字缓存一个复杂的变量当你需要使用一个“昂贵的”方法比如访问数据库很多次的时候是非常有用的
例如
{% with totalbusiness.employees.count %}{{ total }} employee{{ total|pluralize }}
{% endwith %}
不要写成ascsrf_token
{% csrf_token%}这个标签用于跨站请求伪造保护 模板导入 写好一段前端代码块以后别的页面要用直接 {% include xxx.html %}
little.html 这个是以后要导入的代码块
divh1我是广告/h1p亚洲最大同性交友平台/pp名字是{{ name }}---诚信交友/p
/div
在index.html 或者 login.html中想用
!DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/title/head
bodydiv{% include little.html %} # 这个位置引入即可但是如果little中有模板语法需要如下
/div
hr
div我是div222
/div/body
/html
模板继承
模板继承类似于模板导入但不同的是继承分为母版、子版。
母版正常页面布局可以留出某块区域给子版进行使用
{% block 区域名称 %}
{% endblock %}子版可以完全继承与模板但是这就与导入无异了所以子版可以在母版预留出来的区域继续编辑自己的内容
{% extends home.html %} # 继承母版{% block 区域名称 %} # 在模板划分的区域内编写内容子版编写的内容{% endblock %}