写一个出版社的增删查改resful接口
from django.db import models class Book(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.CharField(max_length=32) publish_date = models.DateField() publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE) authors = models.ManyToManyField(to='Author') def __str__(self): return self.name class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() author_detail = models.OneToOneField(to='AuthorDetail', to_field='nid', unique=True, on_delete=models.CASCADE) class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) telephone = models.BigIntegerField() birthday = models.DateField() addr = models.CharField(max_length=64) class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField() def __str__(self): return self.name def test(self): return self.email
#url 路由层
from django.conf.urls import url, include from django.contrib import admin from app01 import views from rest_framework import routers # 生成一个router对象 router = routers.DefaultRouter() # 需要传两个参数,第一个参数就是匹配的路径,第二个参数,是视图类 router.register('publish', views.PublishView) urlpatterns = [ url(r'^admin/', admin.site.urls), # url(r'^publish/',views.PublishView.as_view() ), # url(r'^publish/(?P<pk>d+)',views.PublishDetailView.as_view() ), # url(r'^publish/$', views.PublishView.as_view({'get': 'list', 'post': 'create'})), # url(r'^publish/(?P<pk>d+)', views.PublishView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})), url(r'^test1/$', views.TestAll.as_view({'get': 'test'})), # url(r'^test2/$', views.TestAll.as_view({'get': 'test2'})), # url(r'^test3/$', views.TestAll.as_view({'get': 'test3'})), # 不会使用这种方法的 url('', include(router.urls)), ] 路由控制 三种: -一种基本路由:url(r'^publish/$', views.PublishView.as_view()), -半自动路径:views.PublishView.as_view({'get': 'list', 'post': 'create'})) -必须继承:ViewSetMixin -继承ViewSetMixin的先后顺序 -全自动路由:(基本不用) -from rest_framework import routers # 生成一个router对象 router=routers.DefaultRouter() # 需要传两个参数,第一个参数就是匹配的路径,第二个参数,是视图类 router.register('publish',views.PublishView) url('', include(router.urls)), #自动生成四个路由(PublishView必须继承ModelViewSet)
#MySer 序列化组件
from rest_framework import serializers from app01 import models class AuthorSerializers(serializers.Serializer): nid = serializers.CharField() name = serializers.CharField() age = serializers.CharField() class PublishSerializers(serializers.ModelSerializer): class Meta: model = models.Publish fields = '__all__'
基本视图
from django.shortcuts import render,HttpResponse from rest_framework.views import APIView from app01 import models from app01.MySer import AuthorSerializers, PublishSerializers from django.http import JsonResponse class PublishView(APIView): def get(self, request): publish_list = Publish.objects.all() bs = PublishSerializers(publish_list, many=True) return JsonResponse(bs.data,safe=False) def post(self, request): # 添加一条数据 print(request.data) bs = PublishSerializers(data=request.data) if bs.is_valid(): bs.save() # 生成记录 return JsonResponse(bs.data,safe=False) else: return JsonResponse(bs.errors,safe=False) class PublishDetailView(APIView): def get(self, request, pk): publish_obj = Publish.objects.filter(pk=pk).first() bs = PublishSerializers(publish_obj, many=False) return JsonResponse(bs.data,safe=False) def put(self, request, pk): publish_obj = Publish.objects.filter(pk=pk).first() bs = PublishSerializers(data=request.data, instance=publish_obj) if bs.is_valid(): bs.save() # update return JsonResponse(bs.data) else: return JsonResponse(bs.errors) def delete(self, request, pk): Publish.objects.filter(pk=pk).delete() return JsonResponse("")
第一种方案 class List: def list(self,request): queryset = self.queryset bs = self.serializers(queryset, many=True) return JsonResponse(bs.data,safe=False) class Create: def create(self,request): print(request.data) bs = PublishSerializers(data=request.data) if bs.is_valid(): bs.save() # 生成记录 return JsonResponse(bs.data,safe=False) else: return JsonResponse(bs.errors,safe=False) class PublishView(APIView,List,Create): queryset=Publish.objects.all() serializers=PublishSerializers def get(self, request): return self.list(request) def post(self, request): # 添加一条数据 return self.create(request) class BookView(APIView,List,Create): queryset=Book.objects.all() serializers=BookSerializer def get(self, request): return self.list(request) def post(self, request): return self.create(request)
第二种:ListCreateAPIView 继承了GenericAPIView, ListModelMixin, CreateModelMixin
第三种:路由:url(r'^publish/$', views.PublishView.as_view({'get': 'list', 'post': 'create'})),
url(r'^publish/(?P<pk>d+)', views.PublishView.as_view({'get': 'retrieve', 'put': 'update','delete':'destroy'})),
from rest_framework.generics import ListCreateAPIView, ListAPIView, RetrieveUpdateDestroyAPIView from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin from rest_framework.generics import GenericAPIView class PublishView(GenericAPIView, ListModelMixin, CreateModelMixin): class PublishView(ListCreateAPIView): queryset = Publish.objects.all() serializer_class = PublishSerializers class PublishDetailView(RetrieveUpdateDestroyAPIView): queryset = Publish.objects.all() serializer_class = PublishSerializers
from rest_framework.views import APIView from rest_framework.viewsets import ModelViewSet from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer class PublishView(ModelViewSet): # renderer_classes=[JSONRenderer,BrowsableAPIRenderer] queryset = Publish.objects.all() serializer_class = PublishSerializers
终极版本:
建议用魔法类ViewSetMixin
最终应该使用的方案:ViewSetMixin 它有什么作用?用了它之后,视图类中不需要写get,post,put方法了,自己定义方法就可以了
让请求方法对应到自己定义的方法上,然后再配置路由
快速写出5个接口:
-继承它ModelViewSet
-写一个视图类,视图类中定义两个变量
from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
-路由:(要写两条路由)
url(r'^publish', views.PublishView.as_view({'get': 'list', 'post': 'create'})),
url(r'^publish/(?P<pk>d+)', views.PublishView.as_view({'get': 'retrieve', 'put': 'update','delete':'destroy'})),
# from day100 import settings
# settings 就是项目的配置文件
from django.conf import settings
-第一种:最原始的那种
-第二种:继承ViewSetMixin,它放在前面(好处,跟某个功能相关的,可以写在第一起)
-可以自己封装一个View,继承ViewSetMixin,和APIView
from rest_framework.response import Response
# 建议用魔法类ViewSetMixin
rom rest_framework.viewsets import ViewSetMixin # 注意先后顺序,ViewSetMixin写在前面 class TestAll(ViewSetMixin,APIView): def test(self,request): print(settings.DEBUG) return HttpResponse('test') def test2(self, request): return HttpResponse('test2') def test3(self, request): return HttpResponse('test3')
配置文件查找顺序
先从视图类中查找--->项目配置文件(settings)----->drf默认的setting中取