版本一
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\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
自己写的,还是觉得自己写的比较好用
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 这是通用的
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.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
# url(r'^api/students', StudentAPIView.as_view()), # get post请求
# url(r'^api/student/(?P\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\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\d+)', BooksAPIView.as_view({"get": "retrieve", "patch": "update", "delete": "destroy"})),
#自己写的测试版
url(r'^api/student$', StudentView.as_view()),
url(r'^api/student/(?P\d+)', StudentView.as_view()),
]