Bob's Blog

Web开发、测试框架、自动化平台、APP开发、机器学习等

返回上页首页

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的一些命令集合

共有0条评论

添加评论

暂无评论