1. 程式人生 > 實用技巧 >Django REST framework 構建通用模型

Django REST framework 構建通用模型

  在使用drf過程中,發現要寫大量的serializers、view,在借鑑了各位大神的經驗後,簡化一下程式碼

#base/view.py:通用部分

from rest_framework.views import APIView
from rest_framework.response import Response

class GenericAPIView(APIView):
    queryset = None
    serializer_class = None

    def get(self, request, id=None):
        return self.retrieve(request, id)

    def patch(self, request, id=None):
        return self.update(request, id)

    def delete(self, request, id=None):
        return self.destroy(request, id)

    def get_queryset(self):
        return self.queryset.all()

    def get_serializer(self, *args, **kwargs):
        return self.serializer_class(*args, **kwargs)

    def retrieve(self, request, id):
        if not id:
            queryset = self.get_queryset()
            ser_obj = self.get_serializer(queryset, many=True)
        else:
            ser_obj = self.get_queryset().filter(id=id).first()
            if not ser_obj:
                return Response({'code':0,'msg':'資料不存在!'})
            ser_obj = self.get_serializer(ser_obj)
        return Response({'code':1,'data':ser_obj.data})

    def create(self, request,**kwargs):
        postdata=request.data.copy()#querydict先copy為可變物件
        [postdata.__setitem__(i,kwargs[i]) for i in kwargs]

        ser_obj = self.get_serializer(data=postdata)
        if ser_obj.is_valid():
            ser_obj.save()
            return Response({'code':1,'msg':'建立成功!','data':ser_obj.data})
        else:
            return Response({'code':0,'msg':'失敗!','data':ser_obj.errors})

    def update(self, request, id):
        ser_obj = self.get_queryset().filter(id=id).first()
        ser_obj = self.get_serializer(instance=ser_obj, data=request.data, partial=True)
        if ser_obj.is_valid():
            ser_obj.save()
            return Response({'code':1,'msg':'修改成功!'})
        else:
            return Response({'code':0,'msg':'提交失敗!','data':ser_obj.errors})

    def destroy(self, request, id):
        ser_obj = self.get_queryset().filter(id=id).first()
        if ser_obj:
            ser_obj.delete()
            return Response({'code':1,'msg':'刪除成功!'})
        else:
            return Response({'code':0,'msg':'刪除失敗,物件不存在!'})

  沒有寫post寫到view裡面,設定一些自定義欄位

#app/view.py

@method_decorator(csrf_exempt,name='post')
class projectView(GenericAPIView):
    queryset = project.objects.all()
    serializer_class = ProjectSerializer
    def post(self,request):
        return self.create(request,creater=request.user.id)

  

#serializer.py 按需寫就行

class ProjectSerializer(serializers.HyperlinkedModelSerializer):
    id=serializers.IntegerField(read_only=True)
    name=serializers.CharField(required=True,allow_blank=False,max_length=200)
    content=serializers.CharField(max_length=200,required=True,allow_blank=False,)
    img=serializers.URLField(required=False,)
    creater=serializers.PrimaryKeyRelatedField(queryset=member.objects.all(),required=False,allow_null=True )
    # creater=serializers.SerializerMethodField()
    class Meta:
        model=project
        fields=['id','name','content','img','creater']

  最後,只需要寫serializer和具體業務方法。當然在此基礎上還需要擴充套件,但是已經減少了很多程式碼了。以後會更新一些擴充套件示例。