今日内容
rest_framework序列化
首先序列化需要对写一个类继承serializers.Serializer
方式一:在models的publish写一个__str__方法返回出版社名字
publish = serializers.CharField()
方式二:可以用source指定一个models中的方法
publish = serializers.CharField(source='publish.test')
方式三:直接用publish.他的字段名
publish = serializers.CharField(source='publish.name')
''' class author_serializers(serializers.Serializer): name = serializers.CharField() age = serializers.CharField() class Books_serializers(serializers.Serializer): xxx = serializers.CharField(source='name') yyy = serializers.CharField(source='price') # 方式一:在models的publish写一个__str__方法返回出版社名字 # publish = serializers.CharField() # 方式二: 可以用source指定一个models中的方法 # publish = serializers.CharField(source='publish.test') # 方式三:直接用publish.他的字段名 # publish = serializers.CharField(source='publish.name') # SerializerMethodField可以指定一个方法,该方法需要时get_该字段名 publish = serializers.SerializerMethodField() def get_publish(self, obj): dic = {'name': obj.publish.name, 'price': obj.publish.email} return dic # 可以继续使用序列化 authors = serializers.SerializerMethodField() # def get_authors(self, obj): author = obj.authors.all() pub = author_serializers(author, many=True) return pub.data ''' class author_serializers(serializers.Serializer): name = serializers.CharField() age = serializers.CharField() class Books_serializers(serializers.ModelSerializer): class Meta: model = models.Book # 查询所有字段 # fields = '__all__' # 查询列表中的字段 fields = ['nid','name'] # 除了这几个字段不要,查询其余字段 # exclude = ['publish', 'authors'] # 指定查询深度 # depth = 1 # publish = serializers.CharField(source='publish.name') # authors = serializers.SerializerMethodField() # def get_authors(self, obj): # authors = obj.authors.all() # Authors = author_serializers(authors, many=True) # return Authors.data
视图函数:
class Books(APIView): def get(self, request): db_books = models.Book.objects.all() BOOKS = books(db_books, many=True) return JsonResponse(BOOKS.data, safe=False) def delete(self, request): id = request.query_params.get('id') models.Book.objects.filter(pk=id).delete() dic = {'status': 100, 'msg': '删除成功'} return JsonResponse(dic) def put(self, request): id = request.query_params.get('id') name = request.data.get('name') price = request.data.get('price') models.Book.objects.filter(pk=id).update(name=name, price=price) dic = {'status': 100, 'msg': '修改成功'} return JsonResponse(dic, safe=False) def post(self, request): p_name = request.data.get('name') p_price = request.data.get('price') p_publish = request.data.get('publish') p_authors = request.data.get('authors') book = models.Book.objects.create(name=p_name, price=p_price, publish_id=p_publish) p_authors = p_authors.split(',') for p_author in p_authors: author = models.Author.objects.filter(pk=p_author).first() print(author) book.authors.add(author) print(book) ret = books(book, many=False) return JsonResponse(ret.data, safe=False)
HyperlinkedIdentityField(用的很少)
-1 publish = serializers.HyperlinkedIdentityField(view_name='ttt',lookup_field='publish_id',lookup_url_kwarg='pky')
-2 view_name:路由的别名,lookup_field:根据表的哪个字段,来拼路径,lookup_url_kwarg:反向解析有名分组的名字
-3 写路由:url(r'^publish/(?P<pky>d+)', views.Publish.as_view(),name='ttt'),
-4 实例化序列化类的时候,需要把request对象传过去
book_ser=BookSerializer(ret,many=True,context={'request': request})
设置: class book_serializers(serializers.ModelSerializer): class Meta: model = models.Book fields = '__all__' url = serializers.HyperlinkedIdentityField(source='name', view_name='book', lookup_field='nid', lookup_url_kwarg='pk') # 该设置与form校验类似,都可设置一些参数(max_length,error_messages) name = serializers.CharField(max_length=20, error_messages={'required': '必填', 'max_length': '太长'}) authors = serializers.CharField(required=False) 视图函数使用: class BOOK(APIView): def get(self, request, *args, **kwargs): books = models.Book.objects.all() bs = SER.book_serializers(books, many=True, context={'request': request}) return JsonResponse(bs.data, safe=False)
序列化组件的数据校验
-类比forms组件
-字段是否必填,通过required,来控制 authors=serializers.CharField(required=False)
-数据校验,生成一个序列化类的对象
-对象.is_valid()
-新增数据:
-对象.save()
-修改数据:
-在生成对象的时候,需要传instanse=查询出来的对象
-对象.save()
视图函数中使用:
设置时:
校验中的局部、全局钩子
def validate_name(self, value): user = models.UserInfo.objects.filter(name=value).first() if user: raise ValidationError('用户名存在') else: return value def validate(self, attrs): name = attrs.get('name') pwd = attrs.get('pwd') if name and pwd: if name == pwd: raise ValidationError('用户密码不能相同') else: return attrs return attrs