14 路由Routers

# 只要是继承ViewSetMixin的视图类,路由写法都变了:as_view({字典})
# 重点;以后视图类中可以写任意的方法,只需要继承ViewSetMixin后,使用路由做映射即可


# 路由使用的第一种方式:
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet,ViewSet,ViewSetMixin,GenericViewSet
class PublishView(ModelViewSet):
    queryset = models.Publish.objects.all()
    serializer_class = Publishserializer

from rest_framework.viewsets import ViewSet     #ViewSet继承了ViewSetMixin,APIView
# class BookView(ViewSetMixin,APIView):
#     def login(self,request):
#         return Response("登录成功")

#class BookView(ViewSetMixin,GenericAPIView):     #GenericViewSet继承了ViewSetMixin,GenericAPIView
class BookView(GenericViewSet):
    queryset=None
    serializer_class=None   #注意要加上这2句

    def login(self,request):
        return Response("登录成功")

path('publish/', views.PublishView.as_view(actions={'get': 'list','post':'create'}))


# 自动生成路由
# 在urls.py中
# 第一步导入路由的类
from rest_framework.routers import SimpleRouter,DefaultRouter
SimpleRouter,DefaultRouter的区别  SimpleRouter将路由做了汇总
# 第二步:类实例化得到对象(不用传参数)
router=SimpleRouter()
# 第三步:注册视图类,
router.register('publish',views.PublishView,'publish')
# router.register('book',views.BookView)

# 第四步:加入到总路由中(两种方式)

urlpatterns = [
    # 第四步:加入到总路由中方式二
    path('api/v1/', include(router.urls)),
]
# 第四步:加入到总路由中:方式一
urlpatterns+=router.urls



###action装饰器的作用:给视图函数中自定义的方法做路径的映射


###总结:
    -第一种:path('publish/', views.PublishView.as_view(actions={'get': 'list','post':'create'}))
    -第二种:自动生成 (SimpleRouter,DefaultRouter)
    -action有什么用
    -5个方法:create,list,destory。。,不需要使用action映射
        -如果继承的是 ViewSetMixin, views.APIView +5个视图扩展类之一或者9个视图子类,这种不需要使用action装饰器

1 在urls.py中配置

path('books4/', views.Book4View.as_view()),
re_path('books4/(?P<pk>\d+)', views.Book4DetailView.as_view()),

2 一旦视图类,继承了ViewSetMixin

path('books5/', views.Book5View.as_view(actions={'get':'list','post':'create'})), #当路径匹配,又是get请求,会执行Book5View的list方法
re_path('books5/(?P<pk>\d+)', views.Book5View.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})),

3 继承自视图类,ModelViewSet的路由写法(自动生成路由)

# 3 继承自视图类,ModelViewSet的路由写法(自动生成路由)
    -urls.py
        # 第一步:导入routers模块
        from rest_framework import routers
        # 第二步:有两个类,实例化得到对象
        # routers.DefaultRouter 生成的路由更多
        # routers.SimpleRouter
        router=routers.DefaultRouter()
        # 第三步:注册
        # router.register('前缀','继承自ModelViewSet视图类','别名')
        router.register('books',views.BookViewSet) # 不要加斜杠了

        # 第四步
        # router.urls # 自动生成的路由,加入到原路由中
        # print(router.urls)
        # urlpatterns+=router.urls
        '''
    -views.py
        from rest_framework.viewsets import ModelViewSet
        from app01.models import Book
        from app01.ser import BookSerializer
        class BookViewSet(ModelViewSet):
            queryset =Book.objects
            serializer_class = BookSerializer

4 action的使用

get_1不在自动生成的路由中,所以要用action

# action干什么用?为了给继承自ModelViewSet的视图类中定义的函数也添加路由
# 使用
from rest_framework.decorators import action
class BookViewSet(ModelViewSet):
    queryset =Book.objects.all()
    serializer_class = BookSerializer
    # methods第一个参数,传一个列表,列表中放请求方式,
    # ^books/get_1/$ [name='book-get-1'] 当向这个地址发送get请求,会执行下面的函数
    # detail:布尔类型 如果是True
    #^books/(?P<pk>[^/.]+)/get_1/$ [name='book-get-1']
    @action(methods=['GET','POST'],detail=True)
    def get_1(self,request,pk):
        print(pk)
        book=self.get_queryset()[:2]  # 从0开始截取2条
        ser=self.get_serializer(book,many=True)
        return Response(ser.data)

# 装饰器,放在被装饰的函数上方,method:请求方式,detail:是否带pk

 

 

 

 

 

 

 

 

 

 

 

 

 

 登录的5个接口

#models.py
class User(models.Model):
    username=models.CharField(max_length=32)
    password=models.CharField(max_length=32)


class UserToken(models.Model):
    token=models.CharField(max_length=32) #只要用户登录,生成一个随机字符串,存到这,再次登录,更新
    user=models.OneToOneField(to="User",on_delete=models.CASCADE)



#views.py

from rest_framework.viewsets import ViewSetMixin, ViewSet
from rest_framework.decorators import action
from .models import User,UserToken
import uuid # 生成一个永不(相对的)重复的随机字符串
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from .seriazlizer import BookSerializer
from .models import Book
# 127.0.0.1:8080/user/login ---->post请求
class UserView(ViewSet):
    authentication_classes = []
# class UserView(ViewSetMixin,APIView,):
    @action(methods=['POST'], detail=False)
    def login(self, request):
      # post请求提交的数据都在request.data中
        username = request.data.get('username')
        password = request.data.get('password')
        user=User.objects.all().filter(username=username,password=password).first()
        if user:
          # 登录成功,返回数据格式为 {code:100,msg:登录成功,token:'asdfasdf'}
            token=str(uuid.uuid4())
          # 存库(直接存),判断如果有了数据,就修改token,如果没有是新增
          # user_token=UserToken.objects.create(token=token,user=user)
          # user=user,通过这个去查,如果能查到,使用defaults更新,如果查不到,使用所有新增
            UserToken.objects.update_or_create(defaults={'token':token},user=user)
            return Response({'msg':'登录成功','code':100,'token':token})
       else:
            return Response({'msg': '用户名或密码错误', 'code': 101})


#urls.py
from django.contrib import admin
from django.urls import path,include
from app01 import views

from rest_framework.routers import SimpleRouter
router=SimpleRouter()
router.register("user",views.UserView,'user')
#router.register("book",views.BookView,'book')

urlpatterns = [
path('admin/', admin.site.urls),
path(r"",include(router.urls))
]
 

 

posted @ 2021-12-23 22:24  甜甜de微笑  阅读(146)  评论(0编辑  收藏  举报