rest framework-视图和路由-长期维护
############### 三种视图 ###############
# 第一种方法:使用mixins # class AuthorView(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView): # # GenericAPIView这个继承了APIview, # # 必须要继承这三个类, # queryset=Author.objects.all() # serializer_class = AuthorModelSerializers # # def get(self, request, *args, **kwargs): # return self.list(request, *args, **kwargs) # # def post(self, request, *args, **kwargs): # return self.create(request, *args, **kwargs) # # # class AuthorDetailView(mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,generics.GenericAPIView): # # RetrieveModelMixin,这是查看单条数据 # queryset=Author.objects.all() # serializer_class = AuthorModelSerializers # # def get(self, request, *args, **kwargs): # return self.retrieve(request, *args, **kwargs) # # def delete(self, request, *args, **kwargs): # return self.destroy(request, *args, **kwargs) # # def put(self, request, *args, **kwargs): # return self.update(request, *args, **kwargs) # 第二种方法 # 经过这么封装之后,下面你只需要改表名就可以了,就更加的方便了, # class AuthorView(generics.ListCreateAPIView,generics.GenericAPIView): # # ListCreateAPIView,一个顶两个,又封装了一层, # queryset=Author.objects.all() # serializer_class = AuthorModelSerializers # # # class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView,generics.GenericAPIView): # # RetrieveUpdateDestroyAPIView,一个顶三个, # queryset=Author.objects.all() # serializer_class = AuthorModelSerializers # 第三种方法 # 这种方法就要动到URL了, # 这种方式不够灵活,如果你想要丰富一个方法,可以重写某一个方法,比如def list() class AuthorModelView(viewsets.ModelViewSet): # permission_classes = [SVIPPermission] # throttle_classes = [VisitRateThrottle] queryset = Author.objects.all() serializer_class = AuthorModelSerializers pagination_class = MyPageNumberPagination
############### 对应的路由配置 ###############
from django.conf.urls import url,include from django.contrib import admin from rest_framework import routers from app01.views import views # 但是现在有一个问题,以后是不是只要多一个表,就需要两个url了? # 这样有十张表就要写十次了,所以你封装了视图类了,你也需要封装一下路由, # 怎么封装? from rest_framework import routers routers=routers.DefaultRouter() routers.register("authors",views.AuthorModelView) # 再有一张表,就只需要注册就可以了, routers.register("books",views.BookModelView) urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^publishes/$', views.PublishView.as_view(),name="publish"), # View:view(request)=====APIView:dispatch() url(r'^publishes/(?P<pk>\d+)/$', views.PublishDetailView.as_view(),name="detailpublish"), # View:view(request)=====APIView:dispatch() # url(r'^books/$', views.BookView.as_view(),name="books"), # url(r'^books/(\d+)/$', views.BookDetailView.as_view(),name="detailbook"), # 下面两行,自己写视图,第一种视图,第二种视图都是可以适用的, # url(r'^authors/$', views.AuthorView.as_view(), name="author"), # url(r'^authors/(?P<pk>\d+)/$', views.AuthorDetailView.as_view(), name="detailauthor"), # 下面两行url的配置用来配合第三种视图模式:传递字典参数的写法内部使用到了反射, # url(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}), name="author"), # url(r'^authors/(?P<pk>\d+)/$', views.AuthorModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}), name="detailauthor"), # 下面一行路由配置,配合第三种视图,更加的简洁 url(r'',include(routers.urls)), url(r'^login/$', views.LoginModelView.as_view(), name="login"), url(r'^app01/(?P<version>\w+)/', include('app01.urls')), ]
############### 对应的序列化类 ###############
from rest_framework import serializers from app01.models import * # 为queryset,model对象做序列化 class PublishSerializers(serializers.Serializer): name = serializers.CharField() email = serializers.CharField() class PublishModelSerializers(serializers.ModelSerializer): class Meta: model=Publish fields="__all__" class BookSerializers(serializers.Serializer): title = serializers.CharField(max_length=32) price = serializers.IntegerField() pub_date = serializers.DateField() publish=serializers.CharField(source="publish.name") # 这是一对多的字段,需要特殊处理,就使用source就可以了 #authors=serializers.CharField(source="authors.all") # 这是多对多的字段,需要特殊处理,但是展示的样式不好, authors = serializers.SerializerMethodField() # 这是多对多字段更好的实现方法,一定要实现一个对应的方法,格式就是get_字段的名字, def get_authors(self,obj): temp=[] for obj in obj.authors.all(): temp.append(obj.name) return temp ''' 序列化BookSerializers(book_list,many=True)过程: temp=[] for obj in book_list: temp.append({ "title":obj.title, "price":obj.price, "pub_date":obj.pub_date, "publish":str(obj.publish), # obj.publish.name #"authors":obj.authors.all, "authors": get_authors(obj) }) ''' class BookModelSerializers(serializers.ModelSerializer): # 这个Serializer就类似form,这个ModelSerializer就类似于modelform, class Meta: model = Book fields = "__all__" # 这里面实现了一对多和多对多,一对多是展示的id,多对多是展示的一个id列表, #publish=serializers.CharField(source="publish.pk") # 如果你不写单个的字段就是用ModelSerializer的,如果你自己写了就用你自己的, # publish=serializers.HyperlinkedIdentityField( # 超链接 # view_name="detailpublish", #detailpublish 这是publisher的链接,detailpublish这是路由的地方写的别名,链接地址, # lookup_field="publish_id", # lookup_url_kwarg="pk" # ) # authors=serializers.CharField(source="authors.all") # authors = serializers.SerializerMethodField() # def get_authors(self,obj): # temp=[] # for obj in obj.authors.all(): # temp.append(obj.name) # return temp # def create(self, validated_data): # 如果你自定义了一对多的字段,是不支持source写法的,你需要重写create方法, # print("validated_data",validated_data) # book=Book.objects.create(title=validated_data["title"],price=validated_data["price"],pub_date=validated_data["pub_date"],publish_id=validated_data["publish"]["pk"]) # book.authors.add(*validated_data["authors"]) # 这种写法你要记住, # # return book class AuthorModelSerializers(serializers.ModelSerializer): class Meta: model=Author fields="__all__"
############### 总结 ###############
总结一下,也没有多少东西 1,三种视图的使用 2,第三种视图需要配合url 的配置, 3,但是一般还是自己写视图,不使用这三种视图,因为不够灵活,
############### 总结 ###############
############### 总结 ###############
技术改变命运