DRF创建或更新时对字段的选择限制
使用Django restframework做api服务时,有个小需求,有个字段代表离开时间,这意味着创建时是不能给这个字段赋值的,哪怕传递了值都不会写入;而更新时,不管传了多少个字段,最后只会更新离开时间这个字段。这样能保证数据的合理性。
先说创建时。
在定义model的时候,这个字段是leave_time = models.DateTimeField(blank=True, null=True),允许为空。
不过一旦别人知晓整个请求体的格式,字段和值还是会传过来。于是在创建时需要忽略这个字段,不管传不传,都忽略掉。同时不能影响list数据时不展示这个字段。
serializers.py中还是直接定义所有字段
from .models import Record
from rest_framework import serializers
class RecordSerializer(serializers.ModelSerializer):
class Meta:
model = Record
fields = "__all__"
在views.py中,重写create方法即可。留意下面代码片段中的三行注释。这里把传递过来的request中的数据,移除leave_time,不管是否传递没有,最终的处理都不会带有leave_time的值。
from .models import Record
from .serializers import RecordSerializer
from rest_framework import generics
from rest_framework import status
from rest_framework.response import Response
class RecordList(generics.ListCreateAPIView):
queryset = Record.objects.all()
serializer_class = RecordSerializer
def create(self, request, *args, **kwargs):
mutable_data = request.data.copy() # here
mutable_data.pop("leave_time", None) # here
serializer = self.get_serializer(data=mutable_data) # here
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
而在真正离开的时候,需要更新leave_time这个字段,但是有的人又会传递全部字段,甚至把一些重要字段的值都给改了,所以在put和patch的时候需要只保留leave_time这个字段。
serializers.py中新增一个class,限定到leave_time这一个字段。
class RecordUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = Record
fields = ("leave_time",)
然后在views.py中,重写put和patch,将对应的serializer换成这一个。这样也不会影响某一个具体数据的字段展示。
class RecordDetail(generics.RetrieveUpdateAPIView):
queryset = Record.objects.all()
serializer_class = RecordSerializer
def put(self, request, *args, **kwargs):
self.serializer_class = RecordUpdateSerializer
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
self.serializer_class = RecordUpdateSerializer
return self.partial_update(request, *args, **kwargs)
上一篇:
python UV的一些命令集合