Django基础012--接口开发

全局参数(get,post,put,delete)

接口:/api/parameter

GET:获取全局参数的所有数据

POST:创建全局参数

PUT:更新全局参数

DELETE:删除全局参数

1.创建app 

python manage.py startapp example

2.models.py

 1 from django.db import models
 2 
 3 
 4 # Create your models here.
 5 class BaseModel(models.Model):
 6     '''公共字段'''
 7     is_delete_choice = (
 8         (1, '删除'),
 9         (0, '正常')
10     )
11     is_delete = models.SmallIntegerField(choices=is_delete_choice, default=0, verbose_name='是否被删除')
12     create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)  # auto_now_add的意思,插入数据的时候,自动取当前时间
13     update_time = models.DateTimeField(verbose_name='修改时间', auto_now=True)  # 修改数据的时候,时间会自动变
14 
15     class Meta:
16         abstract = True  # 只是用来继承的,不会创建这个表
17 
18 
19 #全局参数model
20 class Parameter(BaseModel):
21     name = models.CharField(verbose_name='参数名',max_length=200,unique=True)
22     desc = models.CharField(verbose_name='描述', max_length=200)
23     value = models.CharField(verbose_name='参数值', max_length=200)
24 
25     def __str__(self):
26         return self.name
27 
28     class Meta:
29         db_table = 'parameter'
30         verbose_name = '全局参数信息表'
31         verbose_name_plural = verbose_name
32         #最后创建的在最上面
33         ordering = ['-id']#根据id降序排序

创建表,执行以下命令

python manage.py makemigrations example  --指定app生成表的初始化文件

python manage.py migrate example  --指定app创建表

3.example/urls.py

 1 from django.urls import path
 2 from .views import f_parameter,Parameter,SParameter
 3 
 4 urlpatterns = [
 5     # FBV
 6     path('parameter',f_parameter),
 7     #CBV
 8     path('c_parameter',Parameter.as_view()),
 9     #简化代码
10     path('s_parameter',SParameter.as_view()),

4.项目的urls.py

 1 from django.contrib import admin
 2 from django.urls import path,include
 3 #引入example中的urls
 4 from example import urls
 5 
 6 urlpatterns = [
 7     path('admin/', admin.site.urls),
 8     #include是引入其他app的urls,每个请求都要加上api/
 9     path('api/',include(urls)),
10 ]

5.views.py

5.1 FBV模式  func base view

 1 # FBV func base view
 2 #用函数实现的view
 3 def f_parameter(request):
 4     data = {'name':'zzl','age':18}
 5     if request.method == 'GET':
 6         page = request.GET.get('page')#获取前台返回的第几页数据
 7         qs = models.Parameter.objects.filter(is_delete=0)#查询出未删除的参数
 8         page_obj = Paginator(qs,5)
 9         page_data = page_obj.get_page(page)#获取分页的数据
10         data_list = []
11         for data in page_data:
12             #model_to_dict(data,exclude=['is_delete'])
13             # fields:包含哪些字段,
14             # exclude:排除哪些字段
15             # django自带model_to_dict 不处理时间,用自己重写的model_to_dict
16             data_list.append(model_to_dict(data,exclude=['is_delete']))#将qs转成dict并放入list中
17         return JsonResponse({'msg':0,'data':data_list})
18     elif request.method == 'POST':
19         form_obj = forms.ParameterForm(request.POST)
20         f = form_obj.is_valid()
21         if f:
22             models.Parameter.objects.create(**form_obj.cleaned_data)#插入数据
23             return JsonResponse({'code':200,'msg':'成功'})
24         else:
25             return JsonResponse({'code':500,'msg':form_obj.errors.get_json_data()})
26     elif request.method == 'PUT':
27         #django并没有处理PUT的数据 request.PUT
28         #实际put传过来的数据在request.body里
29         #request.body的数据不可用,要导入from django.http import QueryDict,来处理数据
30         #更新数据,需要告知,要更新哪条数据
31         put_data = QueryDict(request.body)
32         print('put_data',put_data)
33 
34         p_id = put_data.get('id')#获取前端传过来的数据的id
35         print('p_id',p_id)
36         p_data = models.Parameter.objects.get(id=p_id)
37 
38         #参数1是前端传过来的,参数2是数据库中获取的
39         form_obj = forms.ParameterForm(put_data,instance=p_data)
40 
41         if form_obj.is_valid():
42             form_obj.save()#如果数据校验通过,就通过form_obj.save方法来更新数据
43             return JsonResponse({'code': 200, 'msg': '成功'})
44         else:
45             return JsonResponse({'code': 500, 'msg': form_obj.errors.get_json_data()})
46     elif request.method == 'DELETE':
47         #删除要先确定是删除哪条数据,需要获取id
48         #删除有1,逻辑删除  2,物理删除
49         #1,逻辑删除:只是通过改变某个字段的状态,重要的数据,有可能在未来通过状态再改回来
50         #2,物理删除,数据不重要,直接delete掉
51         p_id = request.GET.get('id')
52         print(p_id)
53         #逻辑删除
54         #models.Parameter.objects.filter(id=p_id).update(is_delete = 1) #这种更新方式不会触发update_time更新
55         # p_obj = models.Parameter.objects.filter(id=p_id).first()
56         # print(p_obj)
57         # p_obj.is_delete = 1
58         # p_obj.save()#这种方式可以触发update_time更新
59 
60         #物理删除
61         models.Parameter.objects.filter(id=p_id).delete()#删除数据
62 
63         return JsonResponse({'msg':'delete'})
64     else:
65         return JsonResponse({'msg':'error'})

5.2 CBV模式  class base view

 1 #CBV  class base view
 2 #面向对象的语言,通过class,可以用到继承 多继承 面向对象
 3 class Parameter(View):
 4     def get(self,request):
 5         page = request.GET.get('page')  # 获取前台返回的第几页数据
 6         qs = models.Parameter.objects.filter(is_delete=0)  # 查询出未删除的参数
 7         page_obj = Paginator(qs, 5)
 8         page_data = page_obj.get_page(page)  # 获取分页的数据
 9         data_list = []
10         for data in page_data:
11             # model_to_dict(data,exclude=['is_delete'])
12             # fields:包含哪些字段,
13             # exclude:排除哪些字段
14             # django自带model_to_dict 不处理时间,用自己重写的model_to_dict
15             data_list.append(model_to_dict(data, exclude=['is_delete']))  # 将qs转成dict并放入list中
16         return JsonResponse({'msg': 0, 'data': data_list})
17 
18     def post(self,request):
19         form_obj = forms.ParameterForm(request.POST)
20         f = form_obj.is_valid()
21         if f:
22             models.Parameter.objects.create(**form_obj.cleaned_data)  # 插入数据
23             return JsonResponse({'code': 200, 'msg': '成功'})
24         else:
25             return JsonResponse({'code': 500, 'msg': form_obj.errors.get_json_data()})
26 
27     def put(self,request):
28         # django并没有处理PUT的数据 request.PUT
29         # 实际put传过来的数据在request.body里
30         # request.body的数据不可用,要导入from django.http import QueryDict,来处理数据
31         # 更新数据,需要告知,要更新哪条数据
32         put_data = QueryDict(request.body)
33         print('put_data', put_data)
34 
35         p_id = put_data.get('id')  # 获取前端传过来的数据的id
36         print('p_id', p_id)
37         p_data = models.Parameter.objects.get(id=p_id)
38 
39         # 参数1是前端传过来的,参数2是数据库中获取的
40         form_obj = forms.ParameterForm(put_data, instance=p_data)
41 
42         if form_obj.is_valid():
43             form_obj.save()  # 如果数据校验通过,就通过form_obj.save方法来更新数据
44             return JsonResponse({'code': 200, 'msg': '成功'})
45         else:
46             return JsonResponse({'code': 500, 'msg': form_obj.errors.get_json_data()})
47 
48     def delete(self,request):
49         # 删除要先确定是删除哪条数据,需要获取id
50         # 删除有1,逻辑删除  2,物理删除
51         # 1,逻辑删除:只是通过改变某个字段的状态,重要的数据,有可能在未来通过状态再改回来
52         # 2,物理删除,数据不重要,直接delete掉
53         p_id = request.GET.get('id')
54         print(p_id)
55         # 逻辑删除
56         # models.Parameter.objects.filter(id=p_id).update(is_delete = 1) #这种更新方式不会触发update_time更新
57         # p_obj = models.Parameter.objects.filter(id=p_id).first()
58         # print(p_obj)
59         # p_obj.is_delete = 1
60         # p_obj.save()#这种方式可以触发update_time更新
61 
62         # 物理删除
63         models.Parameter.objects.filter(id=p_id).delete()  # 删除数据
64 
65         return JsonResponse({'msg': 'delete'})

5.3 CBV模式  代码优化

5.3.1 custom_view.py
  1 #重写model_to_dict
  2 import datetime
  3 from itertools import chain
  4 
  5 from django.core.paginator import Paginator
  6 from django.db.models import Model, Q
  7 from django.forms import BaseForm
  8 from django.http import JsonResponse, QueryDict
  9 from django.views import View
 10 from .custom_response import NbResponse
 11 
 12 from example import models
 13 
 14 
 15 def model_to_dict(instance, fields=None, exclude=None):
 16     opts = instance._meta
 17     data = {}
 18     for f in chain(opts.concrete_fields, opts.private_fields, opts.many_to_many):
 19         if fields and f.name not in fields:
 20             continue
 21         if exclude and f.name in exclude:
 22             continue
 23         value = f.value_from_object(instance)
 24         if isinstance(value, datetime.datetime):
 25             value = value.strftime('%Y-%m-%d %H:%M:%S')
 26         if isinstance(value, datetime.date):
 27             value = value.strftime('%Y-%m-%d')
 28         data[f.name] = value
 29     return data
 30 
 31 class BaseView(View):
 32     search_fields = []#定义需要模糊搜素的字段
 33     filter_fields = []#定义需要搜索的字段
 34     model_class = None
 35     fields = [] #指定返回的字段
 36     exclude_fields = [] #指定返回时过滤的字段
 37     form_class = None
 38 
 39     @property#修饰方法,使方法可以像属性一样访问
 40     def model(self):
 41         #issubclass 参数1是否为参数2的子类
 42         if self.model_class and issubclass(self.model_class,Model):
 43             return self.model_class
 44         raise Exception('未定义model_class')
 45 
 46     @property  # 修饰方法,使方法可以像属性一样访问
 47     def form(self):
 48         # issubclass 参数1是否为参数2的子类
 49         if self.form_class and issubclass(self.form_class, BaseForm):
 50             return self.form_class
 51         raise Exception('未定义form_class')
 52 
 53     def get_filter_dict(self):
 54         filter_dict = {}
 55         for field in self.filter_fields:
 56             filter_value = self.request.GET.get(field)#获取前端传过来的值
 57             if filter_value:
 58                 filter_dict[field] = filter_value
 59         return filter_dict
 60 
 61     #只支持一个字段的模糊查询
 62     def get_search_dict(self):
 63         search_dict = {}
 64         value = self.request.GET.get('search')#获取前台传过来的字段
 65         if value:
 66             search_dict = {'%s__contains'%self.search_fields[0] : value}
 67         print(search_dict)
 68         return search_dict
 69 
 70     #支持多个字段的模糊查询
 71     def get_search_dict_or(self):
 72         value = self.request.GET.get('search')
 73         q = Q()
 74         if value:
 75             for field in self.search_fields:
 76                 d =  {'%s__contains'%field : value}
 77                 q = Q(**d) | q
 78         return q
 79 
 80 
 81 class GetView(BaseView):
 82     def get(self,request):
 83         page = request.GET.get('page')  # 获取前台返回的第几页数据
 84         filter_dict = self.get_filter_dict()#获取需要搜索的字典
 85         # search_dict = self.get_search_dict()#获取需要模糊查询的字典
 86         # qs = self.model.objects.filter(is_delete=0).filter(**filter_dict).filter(**search_dict)  # 查询出未删除的参数
 87         search_q = self.get_search_dict_or()#获取需要模糊查询的q
 88         qs = self.model.objects.filter(is_delete=0).filter(**filter_dict).filter(search_q)  # 查询出未删除的参数
 89         page_obj = Paginator(qs, 5)
 90         page_data = page_obj.get_page(page)  # 获取分页的数据
 91         data_list = []
 92         for data in page_data:
 93             # model_to_dict(data,exclude=['is_delete'])
 94             # fields:包含哪些字段,
 95             # exclude:排除哪些字段
 96             # django自带model_to_dict 不处理时间,用自己重写的model_to_dict
 97             data_list.append(model_to_dict(data, fields=self.fields,exclude=self.exclude_fields))  # 将qs转成dict并放入list中
 98         return NbResponse(data=data_list)
 99 
100 
101 class PostView(BaseView):
102     def post(self,request):
103         form_obj = self.form(request.POST)
104         f = form_obj.is_valid()
105         if f:
106             self.model.objects.create(**form_obj.cleaned_data)  # 插入数据
107             return NbResponse()
108         else:
109             # return JsonResponse({'code': 500, 'msg': form_obj.errors.get_json_data()})
110             return NbResponse(code=500,msg=form_obj.errors.get_json_data())
111 
112 
113 class PutView(BaseView):
114     def put(self,request):
115         # django并没有处理PUT的数据 request.PUT
116         # 实际put传过来的数据在request.body里
117         # request.body的数据不可用,要导入from django.http import QueryDict,来处理数据
118         # 更新数据,需要告知,要更新哪条数据
119 
120         p_id = request.PUT.get('id')  # 获取前端传过来的数据的id
121         print('p_id', p_id)
122         p_data = models.Parameter.objects.get(id=p_id)
123 
124         # 参数1是前端传过来的,参数2是数据库中获取的
125         form_obj = self.form(request.PUT, instance=p_data)
126 
127         if form_obj.is_valid():
128             form_obj.save()  # 如果数据校验通过,就通过form_obj.save方法来更新数据
129             return JsonResponse({'code': 200, 'msg': '成功'})
130         else:
131             return JsonResponse({'code': 500, 'msg': form_obj.errors.get_json_data()})
132 
133 
134 class DeleteView(BaseView):
135     def delete(self,request):
136         # 删除要先确定是删除哪条数据,需要获取id
137         # 删除有1,逻辑删除  2,物理删除
138         # 1,逻辑删除:只是通过改变某个字段的状态,重要的数据,有可能在未来通过状态再改回来
139         # 2,物理删除,数据不重要,直接delete掉
140         p_id = request.GET.get('id')
141         print(p_id)
142         # 逻辑删除
143         # models.Parameter.objects.filter(id=p_id).update(is_delete = 1) #这种更新方式不会触发update_time更新
144         # p_obj = models.Parameter.objects.filter(id=p_id).first()
145         # print(p_obj)
146         # p_obj.is_delete = 1
147         # p_obj.save()#这种方式可以触发update_time更新
148 
149         # 物理删除
150         self.model.objects.filter(id=p_id).delete()  # 删除数据
151 
152         return JsonResponse({'msg': 'delete'})
153 
154 
155 class NbView(GetView,PostView,PutView,DeleteView):
156     pass
5.3.2 views.py
1 #简化代码--全局参数
2 class SParameter(NbView):
3     # 抽象出不同的地方,让相同的地方复用
4     model_class = models.Parameter#重写了父类的变量
5     #fields = ['name']
6     exclude_fields = ['is_delete']
7     filter_fields = ['value'] #搜索字段
8     search_fields = ['name','desc']  #模糊查询字段
9     form_class = forms.ParameterForm

6.myMiddleWires.py

当请求方式为PUT时,参数是在request.body中获取,且是经过编码后的,获取参数不方便

可以在中间件请求拦截器中,识别请求方式为PUT时,将参数转为request.put

 1 from django.middleware.common import MiddlewareMixin
 2 from django.http import HttpResponse,QueryDict
 3 from sky.settings import DEBUG
 4 from example.custom_response import NbResponse
 5 
 6 class PutMethodMiddlerware(MiddlewareMixin):
 7     def process_request(self,request):
 8         if request.method == 'PUT':
 9             request.PUT = QueryDict(request.body)
10 
11 
12 #出现异常时抛出异常
13 class ExceptionMiddleware(MiddlewareMixin):
14     def process_exception(self,request,exception):
15         if not DEBUG:#上线之后,直接将错误返回,未上线不做拦截,控制台可看
16             #拦截异常的
17             return NbResponse(code=500,msg='系统开小差了,请联系管理员...%s'%exception)

7.custom_response.py

JsonResponse返回json字符串时,如果每次需要返回固定的字段,可以重写JsonResponse里的方法

1 from django.http import JsonResponse
2 
3 
4 class NbResponse(JsonResponse):
5     def __init__(self,code=200,msg='操作成功',**kwargs):
6         data = {'code':code,'msg':msg}
7         data.update(kwargs)
8         super().__init__(data=data,json_dumps_params={"ensure_ascii": False})

 

posted @ 2020-09-06 20:44  cjxxl1213  阅读(254)  评论(0编辑  收藏  举报