目录css
经过此模块,若不设置参数,则会把中文转成二进制,因此就须要设置参数ensure_ascii了html
def index(request): user = {'username':'jason真帅 我好喜欢哦~','pwd':'123'} # json_str = json.dumps(user,ensure_ascii=False) # return HttpResponse(json_str) return JsonResponse(user,json_dumps_params={'ensure_ascii':False}) # l = [1,2,3,4,5,5,6] # return JsonResponse(l,safe=False) # JsonResponse默认只支持序列化字典 若是你想序列化其余类型(json可以支持的类型) 你须要将safe参数由默认的True改为False
须要注意的是转字典意外的其余格式,需设置safe参数!!!前端
额外赠品?python
额外赠品?django
额外赠品?json
import json from datetime import datetime """ TypeError: Object of type 'datetime' is not JSON serializable """ class MyJsonClass(json.JSONEncoder): def default(self, o): if isinstance(o,datetime): # 若是o不是json默认可以序列化 你就在该方法内给他处理成json可以转的类型 return o.strftime('%Y-%m-%d') else: super().default(self,o) d = {'ctime':datetime.today()} print(json.dumps(d,cls=MyJsonClass))
这里是用json模块来转json不支持的数据类型。。。将就着看吧闭包
若是直接上传,用post的方式不设置其余参数,则只会上传文件名字,解决方法就是,在前段form表单处设置属性enctype=“formdata”。函数
作到这里时你觉得成功了吗?oop
不,当你打印request.POST时发现连文件名都没了???源码分析
其实当设置了以后,文件就会以另外一种方式上传,打印request.FILES你就会看见它
def up(request): if request.method == 'POST': print(request.POST) print(request.FILES) # 获取文件对象 file_obj = request.FILES.get('myfile') print(file_obj.name) # 获取文件名 with open(file_obj.name,'wb') as f: # for line in file_obj: # file_obj你能够直接当作文件句柄f for chunk in file_obj.chunks(): # file_obj你能够直接当作文件句柄f(官方推荐下面这么写,其实没差异) f.write(chunk) return render(request,'up.html')
FBV(Function Based View) 基于函数的视图
CBV(Class Based View) 基于类的视图
CBV路由:
url(r'^reg/',views.MyReg.as_view())
思考一下?
你在类中写了两个方法 一个叫get一个叫post
为何前端get请求来就会触发get方法
post请求来就会触发post方法 如何实现的???
源码分析开始了!
源码分析开始了!
源码分析开始了!
@classonlymethod def as_view(cls, **initkwargs): def view(request, *args, **kwargs): self = cls(**initkwargs) # cls就是咱们本身的写的MyReg类 if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.request = request self.args = args self.kwargs = kwargs # 上面的一通操做 就是给咱们本身写的类的对象赋值 return self.dispatch(request, *args, **kwargs) # 对象在查找属性或方法的时候 顺序是什么? 先从本身找 再从产生对象的类中找 再去类的父类中找... """也就意味着你在看源码的时候 你必定要牢记上面的话""" return view
先看看这段源码,从as_view()按ctrl点进去。很明显这是个闭包函数,最终返回一个view对象,因此接下来看view方法,if后面4行这是在赋值相似于初始化,由于self = cls(**initkwargs)建了一个新的对象,cls则是咱们在视图中写的类,赋值后执行dispatch方法,很明显,接下来就是点进这个方法中看源码...
"""CBV最精髓的部分""" def dispatch(self, request, *args, **kwargs): if request.method.lower() in self.http_method_names: # 判断当前请求方式在不在默认的八个请求方式中 handler = getattr(self, request.method.lower(), self.http_method_not_allowed) # handler = getattr(本身写的类产生的对象,'小写的请求方法(get\post)','获取不到对应的方法就报错') # handler就是咱们本身定义的跟请求方法相对应的方法的函数内存地址 else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs) # 在调用获取到的方法
这个方法就是关键所在了,先判断方法是否符合规则,而后利用反射直接调用,简单粗暴-。-
后续补更ing...
传函数名的时候 会自动加括号调用函数 将函数的返回值展现在html页面上
1.django模板语法不支持函数传参
2.django模板语法在获取容器类型内部元素的值的时候 统一只采用 句点符(.)
过滤器 有点相似于小的方法
特色 会将|左边的当作过滤器的第一个参数 |右边的当前过滤器第二个参数
#add过滤器,结果是两个参数相加 <p>{{ n|add:100 }}</p> <p>{{ n|add:'abc' }}</p> <p>{{ s|add:'sasahhdasda' }}</p> #length过滤器,取长度 <p>{{ l|length }}</p> <p>{{ d|length }}</p> #filesizeformat过滤器取文件长度 <p>{{ file_size|filesizeformat }}</p> #truncatechars截取必定数量的字符 <p>截取10个字符 三个点也算{{ w1|truncatechars:10 }}</p> <p>截取10个字符 三个点也算{{ w|truncatechars:10 }}</p> #truncatewords截取指定限制条件和数量的字符 <p>按空格截取单词 三个点不算{{ w1|truncatewords:6 }}</p> <p>按空格截取单词 三个点不算{{ w|truncatewords:6 }}</p> <p>按空格截取单词 三个点不算{{ w2|truncatewords:6 }}</p> #slice切片 <p>{{ l|slice:'0:5' }}</p> <p>{{ l|slice:'0:5:2' }}</p> #date日期输出格式 <p>{{ ctime|date:'Y-m-d' }}</p> <p>{{ ctime|date:'Y年/m月' }}</p> #safe让标签变得能被解释 <p>{{ sss|safe }}</p> <p>{{ sss1|safe }}</p> <p>{{ res }}</p> #default无值则取默认值 <p>{{ xo|default:'' }} 有值就拿值 没值就用后面默认的 </p>
{% if xo %} <p>xo有值</p> {% else %} <p>xo没有值</p> {% endif %} {% if xo %} <p>xo有值</p> {% elif xo1 %} <p>xo1有值</p> {% else %} <p>去他大爷的</p> {% endif %}
{% for foo in l %} {% if forloop.first %} <p>这是个人第一次</p> {% elif forloop.last %} <p>这是最后一次了啊</p> {% else %} <p>嗨起来 大宝贝~</p> {% endif %} {% endfor %} {% for foo in xo %} <p>{{ forloop.counter }}:{{ foo }}</p> {% empty %}判断是否为空 <p>你给个人对象是个空的无法进行for循环</p> {% endfor %}
<p>{{ yyy.user_list.2.username.1 }}</p> {% with yyy.user_list.2.username.1 as dsb %} <p>{{ dsb }}</p> <p>{{ yyy.user_list.2.username.1 }}</p> {% endwith %}
步骤:
1.在应用名下面建立一个叫templatetags的文件夹
2.在该文件夹中任意建一个py文件
3.在py文件中先固定写两行代码
from django.tempalte import Library
register = Libyary()
自定义
@register.filter(name='myplus') def index(a,b): return a + b @register.simple_tag(name='mysm') def login(a,b,c,d): return '%s/%s/%s/%s'%(a,b,c,d) 区别 标签不能再if中使用 {% if 0|myplus:123 %} 能够用 <p>有值</p> {% endif %} {% if mysm 1 2 3 4 %} 不能用 <p>有值</p> {% endif %}
事先须要再模板中 经过block划定区域 {% block 区域名字 %} {% endblock %} 子板中如何使用 {% extends '模板的名字'%} {% block 区域名字 %} <h1>登陆页面</h1> {% endblock %} 一个页面上 block块越多 页面的扩展性越高 一般状况下 都应该有三片区域 {% block css %} {% endblock %} {% block content %} {% endblock %} {% block js %} {% endblock %} 子板中还能够经过 {{ block.super }} 来继续使用母版的内容
当你写了一个特别好看的form表单 你想再多个页面上都使用这个form表单 你就能够将你写的form表单看成模块的形式导入 导入过来以后 就能够直接展现 {% include 'good_page.html' %}