Django开发笔记(十二)DRF PUT更新部分数据 字段校验
一、查看单条数据
定义访问路径:
(Django3.0版本,前面版本的查询条件不是这样)
path('retrieve/<int:id>',BookEditView.as_view())
views.py:
class BookEditView(APIView):
# 查询单条数据
def get(self,request,id):
book = Book.objects.filter(id=id).first()
ret = BookSerializers(book) # 拿到结果进行序列化
return Response(ret.data)
二、更新数据(PUT请求,更新部分字段)
这里有个疑问哈,可能我学得还是有点囫囵了,有些东西基础不牢地动山摇
class BookEditView(APIView):
# 查询单条数据
def get(self,request,id):
book = Book.objects.filter(id=id).first()
ret = BookSerializers(book) # 拿到结果进行序列化
return Response(ret.data)
# 更新数据 这里我没搞明白,是put自动走update那个方法,post自动走create吗?
def put(self,request,id):
book = Book.objects.filter(id=id).first()
# 第一个参数instance是实例化对象也就是book,
# 第二个参数书data携带我们要更新的数据,第三个参数是partial=True意思是允许部分更新
serializer = BookSerializers(book,data=request.data,partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.validated_data)
else:
return Response(serializer.errors)
三、DRF校验
需求1:对个别字段进行更个性化的校验
需求2:对字段进行联合校验
两种方法:(都是在serializer文件下写校验方法的)
serializer.py文件:validate_字段名 对单个字段进行校验;validate进行联合校验
DRF提供校验器,自定义校验器进行校验(要在字段上加上参数validators=[] 如:title = serializers.CharField(max_length=32,validators=[my_validate])
from rest_framework import serializers
from .models import Book
class PublisherSerializer(serializers.Serializer):
id = serializers.IntegerField()
title = serializers.CharField(max_length=32)
class AuthorSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField(max_length=32)
# 方法2:实际上,DRF也给我们提供了一个自己定义的验证器,而且这个校验器权重更高,比在类里设置的validate_字段 权重要高
def my_validate(value):
if "敏感信息" in value.lower():
raise serializers.ValidationError("不能含有敏感信息")
return value
class BookSerializers(serializers.Serializer):
id = serializers.IntegerField(required=False) # required = false就是不需要校验,那么在反序列化的时候就可以不传
title = serializers.CharField(max_length=32,validators=[my_validate]) # 这个validators参数就是我们定义好的校验器
CHOICES = ((1, 'Python'), (2, 'Go'), (3, 'Linux'))
# 这里和模型类定义有所不用了,多了一个source
# read_only = True 就是说我只在序列化的时候用,前端展示的时候用,反序列化的时候用的是另一个w_category
category = serializers.ChoiceField(choices=CHOICES, source="get_category_display", read_only=True)
# write_only=True 意思是只反序列化的时候用,也就是说序列化的时候根本不会动这个字段,那前端传数据的时候就要约定传的是这个W_category了
w_category = serializers.ChoiceField(choices=CHOICES, write_only=True)
pub_time = serializers.DateField()
# 外键的反序列化 和上面的category处理方法一样
publisher = PublisherSerializer(read_only=True)
publisher_id = serializers.IntegerField(write_only=True)
author = AuthorSerializer(many=True, read_only=True) # 这个many参数不要忘了
author_list = serializers.ListField(write_only=True)
def create(self, validate_data):
book = Book.objects.create(title=validate_data["title"],
category=validate_data["w_category"],
pub_time=validate_data["pub_time"],
publisher_id=validate_data["publisher_id"])
book.author.add(*validate_data["author_list"]) # 对前端传的author列表进行解包
return book
def update(self,instance,validate_data):
instance.title = validate_data.get("title",instance.title) # 取title,如果取不到,就用instance.title
instance.category = validate_data.get("category", instance.category)
instance.pub_time = validate_data.get("pub_time", instance.pub_time)
instance.publisher_id = validate_data.get("publisher_id", instance.publisher_id)
# many to many 字段我们要判断一下
if validate_data.get("author_list"):
instance.author.set(validate_data["author_list"])
instance.save()
return instance
# 校验方法1:
# DRF提供的对单独字段的校验
# 方法名是 validate_字段 参数value是字段传过来的值
def validate_title(self,value):
if "python" not in value.lower():
# 抛异常,异常信息自定义
raise serializers.ValidationError("标题必须含有python")
return value
# 对多个字段进行联合校验 全局性的
def validate(self, attrs):
if attrs["w_category"]==1 and attrs["publisher_id"]==1:
return attrs
else:
raise serializers.ValidationError("不满足我们的全局校验条件")
浙公网安备 33010602011771号