版本一python
from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from .models import Student from .serializers import StudentSerializer from rest_framework.viewsets import ViewSetMixin, ModelViewSet # Create your views here. class GenericAPIView(APIView): queryset = None serializer_class = None def get_queryset(self): return self.queryset.all() def get_serializer(self, *args, **kwargs): return self.serializer_class(*args, **kwargs) class ListModelMixin(object): def list(self, request): queryset = self.get_queryset() ser_obj = self.get_serializer(queryset, many=True) return Response(ser_obj.data) class CreateModelMixin(object): def create(self, request): ser_obj = self.get_serializer(data=request.data) if ser_obj.is_valid(): print(ser_obj.validated_data) ser_obj.save() return Response(ser_obj.validated_data) else: return Response(ser_obj.errors) class All(GenericAPIView, ListModelMixin, CreateModelMixin): pass class RetrieveModelMixin(object): def retrieve(self, request, id): student_obj = self.get_queryset().filter(id=id).first() ser_obj = self.get_serializer(student_obj) return Response(ser_obj.data) class UpdateModelMixin(object): def update(self, request, id): student_obj = self.get_queryset().filter(id=id).first() ser_obj = self.get_serializer(instance=student_obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.validated_data) else: return Response(ser_obj.errors) class DestroyModelMixin(object): def destroy(self, request, id): student_obj = self.get_queryset().filter(id=id).first() if student_obj: student_obj.delete() return Response("") else: return Response("刪除對象不存在") class EditAll(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): pass class StudentAPIView(All): queryset = Student.objects.all() serializer_class = StudentSerializer def get(self, request): return self.list(request) def post(self, request): return self.create(request) class StudentEditView(EditAll): queryset = Student.objects.all() serializer_class = StudentSerializer def get(self, request, id): # 不知道爲何這裏的形參id的名字必須與url(?P<id>\d+)中傳遞參數的名字同樣,可能這裏傳的是關鍵字參數吧 return self.retrieve(request, id) def patch(self, request, id): return self.update(request, id) def delete(self, request, id): return self.destroy(request, id) # class ModelViewSet(ViewSetMixin, All, EditAll): # 打開註釋用的是本身寫的ModelViewSet,不打開用的是rest_framework封裝好的ModelViewSet # pass class BooksAPIView(ModelViewSet): queryset = Student.objects.all() serializer_class = StudentSerializer
本身寫的,仍是以爲本身寫的比較好用django
from rest_framework.views import APIView from rest_framework.response import Response from .models import Student from .serializers import StudentSerializer class GenericAPIView(APIView): queryset = None serializer_class = None 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: student_obj = self.get_queryset().filter(id=id).first() ser_obj = self.get_serializer(student_obj) return Response(ser_obj.data) def create(self, request): ser_obj = self.get_serializer(data=request.data) if ser_obj.is_valid(): print(ser_obj.validated_data) ser_obj.save() return Response(ser_obj.validated_data) else: return Response(ser_obj.errors) def update(self, request, id): student_obj = self.get_queryset().filter(id=id).first() ser_obj = self.get_serializer(instance=student_obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.validated_data) else: return Response(ser_obj.errors) def destroy(self, request, id): student_obj = self.get_queryset().filter(id=id).first() if student_obj: student_obj.delete() return Response("") else: return Response("刪除對象不存在") class StudentView(GenericAPIView): queryset = Student.objects.all() serializer_class = StudentSerializer def get(self, request, id=None): return self.retrieve(request, id) def post(self, request,id=None): return self.create(request) def patch(self, request, id=None): return self.update(request, id) def delete(self, request, id=None): return self.destroy(request, id)
serializers.py 這是通用的api
from rest_framework import serializers from .models import Student class ClassesSerializer(serializers.Serializer): id = serializers.IntegerField() name = serializers.CharField(max_length=32) class CourseSerializer(serializers.Serializer): id = serializers.IntegerField() name = serializers.CharField(max_length=32) class StudentSerializer(serializers.ModelSerializer): classes_info = serializers.SerializerMethodField(read_only=True) course_info = serializers.SerializerMethodField(read_only=True) def get_classes_info(self, obj): ret = { "id": obj.classes.id, "name": obj.classes.name } return ret def get_course_info(self, obj): courses = obj.courses.all() ret = [] for course in courses: ret.append({ "id": course.id, 'name': course.name }) return ret class Meta: model = Student fields = "__all__" # fields = ["id", "name", "classes_info","course_info"] extra_kwargs = { "classes": {"write_only": True}, "courses": {'write_only': True}, }
urls.pyapp
urlpatterns = [ url(r'^admin/', admin.site.urls), # url(r'^api/students', StudentAPIView.as_view()), # get post請求 # url(r'^api/student/(?P<id>\d+)', StudentEditView.as_view()), #帶有id的get patch delete請求 # 使用咱們本身寫的ModelViewSet,繼承ViewSetMixin進行請求的分發 # url(r'^api/students', BooksAPIView.as_view({"get": "list", "post": "create"})), # url(r'^api/student/(?P<id>\d+)', BooksAPIView.as_view({"get": "retrieve", "patch": "update", "delete": "destroy"})), # 使用rest_framework自帶的ModelViewSet進行請求的分發,這裏要注意url攜帶的命名參數,名字應該是pk # url(r'^api/students', BooksAPIView.as_view({"get": "list", "post": "create"})), # url(r'^api/student/(?P<pk>\d+)', BooksAPIView.as_view({"get": "retrieve", "patch": "update", "delete": "destroy"})), #本身寫的測試版 url(r'^api/student$', StudentView.as_view()), url(r'^api/student/(?P<id>\d+)', StudentView.as_view()), ]