这一篇接触的内容是先后端分离的。关于先后端分离与不分离的区别,我本身的了解是先后端分离的状况会使他们的耦合度更低,后端实现接口的部分,前端根据接口返回实现展现。而先后端不分离可能会用到一些 Django 的模版语言去识别和渲染。css
新建一个 html 文件用于展现本次页面,在 views 中定义要展现的数据。html
1 def test(request): 2 import datetime 3 cur_time = datetime.datetime.now() 4 age = 18 5 name = 'marry' 6 article_content = "朝鲜一哥金三胖,已经登上太阳,为了不太阳太热,选择晚上奔上太阳" 7 say = "今天吃饭的时候,碰到一个傻x,那个家伙实在是太213了,公然插队,吃完饭在马路上随地大小便,够sb的。" 8 navs = ["个人日记", "个人相册", '个人心情', '个人心情1', '个人心情2', '个人心情3'] 9 comment = "<h1 style='font-size:100px'>你好呀</h1>" 10 h1_str = '<p>哈哈哈</p>' 11 js_str="<script>alert('哈哈哈哈')</script>" 12 return render(request,'test.html',locals())#locals把当前全部局部变量返回
传过来的内容能够直接加上指定的内容,如对传过来的 age 加1:前端
{{ age|add:'1' }}
当 age 是字符串类型时,加上指定的字符串即表明两个字符串的拼接。python
若是对传过来的内容截取想要的范围,可使用 slice 这个方法,具体使用:{{ comment|slice:'0:20' }}。填的参数即角标,也是顾头不顾尾。数据库
这个用在文章的概览中,如一篇文章,不可能把全部内容都放在文章的列表中展现,此时可使用这个方法截取指定个数的字符: {{ comment|truncatechars:'40' }} django
若是截取的内容少于原来的内容,则截取的结果会用‘...’代替。json
如上定义的 navs 是一个 list,若是想把其内容拿出来展现,可使用 join 方法,举例: {{ navs|join:'===' }} 后端
使用方法:{{ navs|length }}安全
可用于字符串也可用于 list。前后端分离
{{ navs.0 }} 为取第一个元素,可是不能使用 ‘-1’,在上篇写分页的时候遇到了这个问题,如何自动拿到最后一页。思路:可使用 length 方法
所有大写:{{ name|upper }}
所有小写:{{ name|lower }}
另外,多个方法能够链接使用,如:{{ name|upper|add:'小仙女' }}
对某个要处理的字段增长默认值,拿不到的话显示默认值:{{ author|default:'焦丽妃' }}
指定时间的格式:{{ cur_time|date:'Y-m-d h-i-s' }}
须要注意的是,这里的分是用 i 表示的,不一样于以往接触到的用 m 表示。
这个知识点也牵扯到安全性方面的知识,当前端接收到的数据是带有 html 标签时该如何处理。
一般不作任何操做的话,前端会把标签看成普通字符串来处理,若是咱们想让它识别为标签,能够在后面加上‘safe’,表示是安全的。
{{ js_str|safe }}
当现有的功能没法知足咱们的需求,好比说对敏感词的替换。
添加自定义标签时,在建立的项目下添加一个 python package,名为“templatetags”
1 from django import template 2 3 register = template.Library() 4 5 # 自定义filter最多两个参数 6 @register.filter 7 def mingan(value,aim='金正恩'): 8 if '金三胖' in value: 9 value = value.replace('金三胖',aim) 10 return value
以上实现的是,若是包含上面定义的敏感词,能够替换为使用者自定义的替换词,替换词为空则使用默认值。
在 html 中的应用: {{ comment|mingan:'***' }}
也能够在 @register.filter(name='你想要的名字') 后面添加 name,这样以后在用的时候就把 mingan 替换为你定义的名字。
自定义标签仅支持输入两个参数,当参数过多时,可使用 simple_tag,用法以下(接上面的内容写在同一个文件中):
1 @register.simple_tag 2 def mingan3(value,*args): 3 for s in args: 4 if s in value: 5 value = value.replace(s,'**') 6 return value
这种方法能够接收多个参数,使用起来更方便灵活。
所谓 fvb,就是基于函数的视图;cvb 则是基于类的视图。
配置一个新的 URL,如 stu,目的是实现学生信息的增删改查,若是每一个功能都写一个URL的话,未免过于杂乱,能够用同一个URL,经过不一样的请求方式实现不一样的功能。
例如定义一个名为 StudentView 的类,里面包含了以上四种请求方式的实现。在URL的配置时,类视图不一样于函数视图。
path('stu',views2.StudentView.as_view())
补充: as_view() 方法里面实现了根据请求方式去找类里面对应的方法名,若是是 get 请求,它就去找 get 这个函数,找不到就是不支持 get 请求。
class StudentView(View): #urls中的配置不同 search_field = ['name','phone','addr','work_addr'] #存放支持搜索的字段 filter_field = ['name','phone','id'] def get(self, request): # request 必需要传 limit = request.GET.get('limit', 10) page = request.GET.get('page', 1) search = request.GET.get('search') # 过滤 filter_dict = {} # 用来过滤的字典 for field in self.filter_field: # 循环获取到有哪些过滤的字段 value = request.GET.get(field) if value: filter_dict[field] = value # 模糊查询 q_result = Q() if search: for field in self.search_field: d = {'%s__contains' % field: search} q_result = Q(**d) | q_result all_students = Student.objects.filter(**filter_dict).filter(q_result).values() page_obj = Paginator(all_students, limit) stus = list(page_obj.get_page(page)) data = {"error_code": 0, "msg": "操做成功", "count": page_obj.count, "stus": stus} return JsonResponse(data, json_dumps_params={'ensure_ascii': False}, encoder=NbJSONEncoder)
以上,request.GET 中包含了URL中填写的信息,是一个QuerySet,能够以字典的方式取值,当咱们在URL中传参时,须要用 request.GET.get('***') 来获取参数的具体内容。
模糊查询和过滤的功能,代码值得好好看。
def post(self,request): stu_form = StudentForm(request.POST) if stu_form.is_valid(): Student.objects.create(**stu_form.cleaned_data) data = {"error_code":0,"msg":"添加成功"} else: data = {"error_code":-1,"msg":stu_form.errors.get_json_data()} return JsonResponse(data,json_dumps_params={'ensure_ascii':False},encoder=NbJSONEncoder)
须要补充说明的是,原来使用 HttpResponse 返回数据,须要将数据转成 json 格式的(json_dumps),其实也能够直接用 JsonResponse 返回 json 数据,这个方法接收字典,返回 json。须要注意的是以后的参数定义也要用 json 格式的,如:json_dumps_params={'ensure_ascii':False}
修改数据存在一个问题,简单的实现时,一是不能实现局部修改,二是数据校验的部分如何拿到传过来的数据。已知能够用 request.GET 拿到写在URL中的参数,也能够经过 request.POST 拿到 post 请求的数据,可是没有一个 request.PUT 方法可供使用。
补充:request.META 能够拿到全部的请求数据
put_data,files = request.parse_file_upload(request.META,request)
使用以上方法能够解决获取数据的问题。
如下为解决部分修改和数据校验
put_data,files = request.parse_file_upload(request.META,request) stu_form = StudentForm(put_data) #它校验的是所有的字段 if stu_form.is_valid(): #经过校验 Student.objects.filter(id=id).update(**stu_form.cleaned_data) data = {"error_code": 0, "msg": "修改为功"} else: error_keys = set(stu_form.errors.get_json_data().keys()) put_keys = set(put_data.keys()) if error_keys & put_keys: #有交集说明有未校验经过的 data = {"error_code": -1, "msg": stu_form.errors.get_json_data()} else: #没有交集说明有未填字段,须要部分更新 for k in put_keys: #put_data给的字典value默认是list,须要处理一下 clean_data[k] = put_data.get(k) Student.objects.filter(id=id).update(**clean_data) data = {"error_code": 0, "msg": "修改为功"} return JsonResponse(data, json_dumps_params={'ensure_ascii': False})
put_data 为传过来的数据
stu_form 校验的是所有的字段,若是经过,说明修改的是所有字段,若是未经过,进一步判断。
校验未经过分为两种状况:
1. 所有字段有不符合要求的状况
2. 部分修改
先定义报错的信息,由于若是某个字段未经过校验,会把这个字段看成key,错误信息看成 value 存放在stu_form.errors.get_json_data()。因此,error_keys 存放报错的 key,put_keys 存在传过来的 key。
对第一种状况,就是 error_keys 和 put_keys 有交集,意思是传了值但没经过校验;对第二种状况,两个 keys 没有交集,说明传过来的都经过校验,没经过校验是由于没有传,对这部分字段不作修改,只修改 put_keys 传过来的,进而达到部分修改的目的。
def delete(self,request): id = request.GET.get('id',0) Student.objects.filter(id=id).delete() data = {"error_code":0,"msg":"删除成功"} return JsonResponse(data,json_dumps_params={'ensure_ascii':False},encoder=NbJSONEncoder)
除 get 请求,其余请求方式在测试时须要用 postman 来验证。
1 class StudentForm(forms.Form): #为student作数据校验 2 name = forms.CharField(min_length=2,max_length=10,required=True) #required=True表示必填,默认必填 3 phone = forms.CharField(min_length=11,max_length=11) 4 money = forms.FloatField(required=False) 5 # 自定义函数校验是否字段重复 6 def clean_phone(self): 7 '''钩子''' 8 phone = self.cleaned_data['phone'] 9 if models.Student.objects.filter(phone=phone): 10 return self.errors.add('手机号错误','手机号已经存在') 11 return phone 12 # def clean(self): 13 # '''多个字段校验''' 14 # pass
这是一种稍微麻烦点的数据校验的方法,是把要校验的数据本身定义了写在函数中。
另一种是直接继承 ModelForm,使用的校验方法是在数据库定义时的校验方法,以下:
class StudentForm(ModelForm): class Meta: model = Student # fields ='__all__' fields = ['name','phone'] exclude = ['money'] #排除哪一个字段
使用的方法为: stu_form = StudentForm(request.POST)
后面括号中传的是要校验的数据。上面也提到了,这个方法是校验全部的字段,若是某个字段未经过校验,会把这个字段看成key,错误信息看成 value 存放在stu_form.errors.get_json_data()。
。
o
O