一,HyperlinkedIdentityField
1,先配置两个路由,
# 一个是请求访问时的路由 url(r'^books/$', views.Books.as_view()), # 一个是生成路径的路由,生成路径的路由必须重新命名(后边有使用) url(r'^publish/(?P<pk>\d+)', views.Publish.as_view(), name='tt'),
2,在视图函数中,当以两个类(与路由相对应)
# 请求访问时候的类,可以生成一个序列化对象(必须要传参数) class Books(APIView): def get(self, request, *args, **kwargs): ret = models.Book.objects.all() # 生成一个序列化对象,传参数(序列化多条要many=True) book_ser = BookSerializer(ret, many=True, context={'request': request}) return JsonResponse(book_ser.data, safe=False) # 生成路径的类可以先写一个空壳,后面再加后续内容 class Publish(APIView): def get(self, request, *args, **kwargs): return HttpResponse('ok')
3,在序列化的文件里面,定义一个有与视图层相对应的类
class BookSerializer(serializers.Serializer): name = serializers.CharField() # 想要在前端获取到拼接的出版社链接,先配置一个有名路由,HyperlinkedIdentityField字段的属性是固定的,后面至少添加三个属性名 # view_name表示路由的别名,lookup_field配置路由的Pk,lookup_url_kwarg:反向解析有名分组的名字 publish = serializers.HyperlinkedIdentityField(view_name='tt', lookup_field='publish_id', lookup_url_kwarg='pk')
二,序列化组件创建表数据和查看表数据
1,先配置一个路由(不带分组)
url(r'^books/$', views.Books.as_view()),
2,视图层
# 查看的时候,接收request以及字典或者是其他数据 def get(self, request, *args, **kwargs): ret = models.Book.objects.all() book_ser = BookSerializer() # 传过去是一个字典 return JsonResponse(ret,data, safe=False) # 新建的时候 def post(self, request, *args, **kwargs): response = {'status': 1, 'msg': None} # 从Body体里面取出数据,赋值给data ret = BookSer(data=request.data) # 从BookSer类里面控制输出的数据以及是否通过验证 if ret.is_valid(): # 通过验证是必须掉用save方法 ret.save() response['msg'] = '注册成功' return Response(ret.data) else: response['status'] = 0 response['msg'] = ret.errors return Response(response)
3,在序列化层面
注意:查看的时候,这里可以通过下面的逻辑字段控制输出的字段
class BookSer(serializers.ModelSerializer): class Meta: # 显示的表名 model = Book # 显示的数据 fields = '__all__' # 只取那几个字段 fields = ['nid','name'] # 去掉指定字段(和指定字段不能同时使用) exclude = ['publish','authors'] # 指定深度(关联表的个数显示),建议不要使用,对数据库的压力太大 depth = 2 # 显示关联表的深度 depth = 2 # 把name字段显示成xx,这样避免其他人对你数据库的攻击 xx = serializers.CharField(source='name') # 也可以返回一个模板层定义的方法 test = serializers.CharField(source='publish.test') # 先定义一个这样的字段(同样可以用source属性)[这样显示的是另一个字典] publish = serializers.SerializerMethodField() def get_publish(self, obj): # obj为当前的Book对象,可以随意起名字 dic = {'name': obj.publish.name, 'email': obj.publish.email} return dic # 也可以代替for循环显示出所有的作者 authors = serializers.SerializerMethodField() def get_authors(self,book): aus = book.authors.all() # 可以用序列化类来处理(把作者的全部信息全取出来),下面得重新定义一个类 auth_ser = AuthorSerilalizer(aus, many=True) return auth_ser.data
三,序列化组件之查看单个表和修改删除表数据时
1,先配置一个有名分组,不许要带id(或者是关键字段)
url(r'^books/(?P<pk>\d+)', views.BooksDetail.as_view()),
2,在视图层:
需要定义一个新的类(只接收request和pk值就可以)
class BooksDetail(APIView): def get(self, request, pk): response = {'status': 100, 'mag': None} ret = models.Book.objects.all().filter(pk=pk).first() if ret: # 如果是单条数据的话,必须把many改成False book_ser = BookSerializer(ret, many=False) # print(book_ser.data) response['data'] = book_ser.data else: response['status'] = 101 response['msg'] = '您查询的结果不存在' return JsonResponse(response, safe=True) def put(self, request, pk): response = {'status': 100, 'mag': None} ret = models.Book.objects.all().filter(pk=pk).first() if ret: # 修改和新建唯一的区别就是后面添加一个install属性,把检索出来的对象传值给它 ser = BookSerializer(data=request.data, instance=ret) if ser.is_valid(): ser.save() response['msg'] = '修改成功' else: response['status'] = 101 response['msg'] = ser.errors else: response['status'] = 102 response['mag'] = '修改的对象不存在' return JsonResponse(response, safe=True) def delete(self, request, pk): response = {'status': 1, 'msg': None} ret = models.Book.objects.filter(pk=pk).first() if ret: ser = ret.delete() response['msg'] = '删除成功' else: response['status'] = 0 response['msg'] = '您要删除的内容不存在' return JsonResponse(response, safe=True)
3,序列化层的代码是一样的
四,局部钩子和全局钩子函数
直接在定义的类下面定义局部钩子函数和全局钩子函数就好
1,局部钩子
# 定义函数的名字validate_局部钩子校验字段的名字 def validate_name(self, value): # value就是钩子对应的数据 if value.startswith('sb'): # 不能以sb开头 raise ValidationError('不能以sb开头') else: return value
2,全局钩子函数
def validate(self, value): # 数据全部都在value中,直接.get('')取值 name = value.get('name') price = value.get('price') if name and price: if str(name) == str(price): return value else: raise ValidationError('名字和价钱不一致') raise ValidationError('书名和密码不能为空')
- 补充
总结:
1 Python中没有基于 DCE 的,所以uuid2可以忽略
2 uuid4存在概率性重复,由无映射性
3 若在Global的分布式计算环境下,最好用uuid1
4 若有名字的唯一性要求,最好用uuid3或uuid5