这一篇接触的内容是前后端分离的。关于前后端分离与不分离的区别,我自己的了解是前后端分离的情况会使他们的耦合度更低,后端实现接口的部分,前端根据接口返回实现展示。而前后端不分离可能会用到一些 Django 的模版语言去识别和渲染。
新建一个 html 文件用于展示本次页面,在 views 中定义要展示的数据。
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 是字符串类型时,加上指定的字符串即代表两个字符串的拼接。
如果对传过来的内容截取想要的范围,可以使用 slice 这个方法,具体使用:{{ comment|slice:‘0:20‘ }}。填的参数即角标,也是顾头不顾尾。
这个用在文章的概览中,如一篇文章,不可能把所有内容都放在文章的列表中展示,此时可以使用这个方法截取指定个数的字符: {{ comment|truncatechars:‘40‘ }}
如果截取的内容少于原来的内容,则截取的结果会用‘...’代替。
如上定义的 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
原文:https://www.cnblogs.com/april-aaa/p/11750236.html