路由层

自动生成路由

 1.路由类导入

from rest_framework.routers import SimpleRouter, DefaultRouter

 2.实例化

router = SimpleRouter()

 3.注册

router.register('login', BookView, 'login')

 4.将自动生成的路由添加到urlpatterns中(两种方式结果一样)

方式一:urlpatterns += router.urls
方式二:path('', include(router.urls))

 5.自动生成的路由

5.1 使用路由类SimpleRouter 
    router = SimpleRouter()
5.2 使用路由类DefaultRouter
    router = DefaultRouter()

 注:继承ViewSetMixin的类及其子类的类可以使用自动生成路由

视图层

action装饰器的使用

 1.装饰器导入:from rest_framework.decorators import action
 2.action装饰器的参数
  2.1 methods:请求类型 可多个
  2.2 detail:控制生成的网址
   默认False:注册路由 router.register('user', BookView, 'user')
user/login
   True: user/pk/login
  2.3 url_path:控制生成的路由user/后面的路径 默认是方法名
  2.4 url_name:起别名 用于反向解析

class UserView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    @action(methods=['GET', ], detail=False)
    def login(self, request):
        return Response('登录成功')

编写登录接口

路由层

1.导入路由类:SimpleRouter
2.实例化:router = SimpleRouter()
3.注册
4.将自动生成的路由添加至urlpatterns 
from django.urls import path, include(路由分发)
from rest_framework.routers import SimpleRouter
from app01.views import UserView

router = SimpleRouter()
router.register('user', UserView, 'user')
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls))
]

视图层

1.继承ViewSet==ViewSetMixin, views.APIView 类中的方法可以写任意方法名
2.
from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
from rest_framework.response import Response
from app01.models import User, UserToken
from uuid import uuid4

class UserView(ViewSet):
    @action(methods=['POST', ], detail=False)
    def login(self, request):
        name = request.data.get('name')
        password = request.data.get('password')
        user = User.objects.filter(name=name, password=password).first()   
        if user:
            token = str(uuid4())
            UserToken.objects.update_or_create(defaults={'token': token}, user=user)
            return Response({'code': 100, 'mag': '登录成功'})
        else:
            return Response({'code': 101, 'msg': '用户名或密码错误'})

认证

1.写认证类继承BaseAuthentication
2.重写父类BaseAuthentication中的authenticate方法
3.获取网址中携带的随机字符串 # 类似于cookie与session操作
4.获取数据库数据判断是否一致 存在可以访问 返回 user_token.user(后续可以使用), token
5.否则直接抛异常AuthenticationFailed
6.全局配置认证类:在配置文件中配置

REST_FRAMEWORK={'DEFAULT_AUTHENTICATION_CLASSES':['app01.auth.LoginAuth',]}
  局部配置:类中authentication_classes = [auth.LoginAuth,]
  局部禁用:类中authentication_classes = []
from rest_framework.authentication import BaseAuthentication
from app01.models import UserToken
from rest_framework.exceptions import AuthenticationFailed

class LoginAuth(BaseAuthentication):
    def authenticate(self, request):
        token = request.GET.get('token')  # 获取网址中携带的随机字符串
        user_token = UserToken.objects.filter(token=token).first()
        if not user_token:
            raise AuthenticationFailed('你没有登录')
        return user_token.user, token

扩展

 1.1 登录接口,图书5个接口,出版社5个接口(关联的关系),,使用9个视图子类,5个视图扩展类写

1.5个视图扩展类写图书与出版社5个接口
  路由层:
  urlpatterns = [
      path('books/', BookView.as_view()),
      path('books/<int:pk>/', BookDetailView.as_view()),
      path('publish/', PublishView.as_view()),
      path('publish/<int:pk>/', PublishDetailView.as_view())
  ]
序列化类:
  from rest_framework import serializers
  from app01.models import Book, Publish

  class BookSerializer(serializers.ModelSerializer):
      class Meta:
          model = Book
          fields = '__all__'

      publish = serializers.SerializerMethodField()

      def get_publish(self, obj):
          return {'name': obj.publish.name, 'address': obj.publish.address}

  class PublishSerializer(serializers.ModelSerializer):
      class Meta:
          model = Publish
          fields = '__all__'
 视图层:
    1.图书查所有、增加
    class BookView(ListModelMixin, CreateModelMixin, GenericAPIView):
        queryset = models.Book.objects.all()
        serializer_class = BookSerializer

        def get(self, request,  *args, **kwargs):
            return self.list(request,  *args, **kwargs)

        def post(self, request, *args, **kwargs):
            return self.create(request, *args, **kwargs)
2.图书查单条、修改单条、删除单条
    class BookDetailView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView):

        queryset = models.Book.objects.all()
        serializer_class = BookSerializer

        def get(self, request, pk):
            return self.retrieve(request)

        def put(self, request, pk):
            return self.update(request)

        def delete(self, request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)
3.出版社查所有、增加
    class PublishView(ListModelMixin, CreateModelMixin, GenericAPIView):

        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializer

        def get(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)

        def post(self, request, *args, **kwargs):
            return self.create(request, *args, **kwargs)

4.出版社查单条、修改单条、删除单条
    class PublishDetailView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView):

        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializer

        def get(self, request, pk):
            return self.retrieve(request)

        def put(self, request, *args, **kwargs):
            return self.update(request, *args, **kwargs)

        def delete(self, request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)
 2.使用9个视图子类写图书与出版社5个接口
  图书:
    1.图书查询所有
    class BookView1(ListAPIView):
        queryset = models.Book.objects.all()
        serializer_class = BookSerializer
    2.图书新增
    class BookView2(CreateAPIView):
        queryset = models.Book.objects.all()
        serializer_class = BookSerializer

    3.图书查询所有及新增
    class BookView3(ListCreateAPIView):
        queryset = models.Book.objects.all()
        serializer_class = BookSerializer

    4.图书查询单条
    class BookDetailView1(RetrieveAPIView):
        queryset = models.Book.objects.all()
        serializer_class = BookSerializer

    5.图书修改单条
    class BookDetailView2(UpdateAPIView):
        queryset = models.Book.objects.all()
        serializer_class = BookSerializer

    6.图书删除单条
    class BookDetailView3(DestroyAPIView):
        queryset = models.Book.objects.all()
        serializer_class = BookSerializer

    7.图书查询单条、修改单条
    class BookDetailView4(RetrieveUpdateAPIView):
        queryset = models.Book.objects.all()
        serializer_class = BookSerializer

    8.图书查询单条、删除单条
    class BookDetailView5(RetrieveDestroyAPIView):
        queryset = models.Book.objects.all()
        serializer_class = BookSerializer

    9.图书查询单条、修改单条、删除单条
    class BookDetailView6(RetrieveUpdateDestroyAPIView):
        queryset = models.Book.objects.all()
        serializer_class = BookSerializer
  出版社:
    1.出版社查询所有
    class PublishView1(ListAPIView):
        authentication_classes = []
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializer

    2.出版社新增
    class PublishView2(CreateAPIView):
        authentication_classes = []
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializer

    3.出版社查询所有及新增
    class PublishView3(ListCreateAPIView):
        authentication_classes = []
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializer

    4.出版社查询单条
    class PublishDetailView1(RetrieveAPIView):
        authentication_classes = []
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializer

    5.出版社修改单条
    class PublishDetailView2(UpdateAPIView):
        authentication_classes = []
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializer

    6.出版社删除单条
    class PublishDetailView3(DestroyAPIView):
        authentication_classes = []
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializer

    7.出版社查询单条、修改单条
    class PublishDetailView4(RetrieveUpdateAPIView):
        authentication_classes = []
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializer

    8.出版社查询单条、删除单条
    class PublishDetailView5(RetrieveDestroyAPIView):
        authentication_classes = []
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializer

    9.出版社查询单条、修改单条、删除单条
    class PublishDetailView6(RetrieveUpdateDestroyAPIView):
        authentication_classes = []
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializer

 2 图书的必须登录后才能方法,出版社的不登录就能访问

1.认证类
from rest_framework.authentication import BaseAuthentication
from app01.models import UserToken
from rest_framework.exceptions import AuthenticationFailed

class LoginAuth(BaseAuthentication):
    def authenticate(self, request):
        token = request.GET.get('token')  # 获取网址中携带的随机字符串
        user_token = UserToken.objects.filter(token=token).first()
        if not user_token:
            raise AuthenticationFailed('你没有登录')
        return user_token.user, token
 2.全局配置:所有视图类都需登录才可以访问
  在配置文件中配置:
    REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['app01.auth.LoginAuth', ]}
 3.图书的必须登录后才能方法
class BookView(ListModelMixin, CreateModelMixin, GenericAPIView):
    queryset = models.Book.objects.all()
    serializer_class = BookSerializer

    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 BookDetailView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView):

    queryset = models.Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request, pk):
        return self.retrieve(request)

    def put(self, request, pk):
        return self.update(request)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
   4.出版社的不登录就能访问;局部禁用 authentication_classes = []
class PublishView(ListModelMixin, CreateModelMixin, GenericAPIView):
    authentication_classes = []
    queryset = models.Publish.objects.all()
    serializer_class = PublishSerializer

    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 PublishDetailView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView):

    authentication_classes = []

    queryset = models.Publish.objects.all()
    serializer_class = PublishSerializer

    def get(self, request, pk):
        return self.retrieve(request)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

 3.级联删除中的参数(on_delete中的参数中的值)

1.on_delete=models.None:删除关联表中的数据时,当前表与其关联的field的行为
2.on_delete=models.CASCADE:级联删除,删除关联关系,与之关联也删除
3.on-delete=models.DO_NOTHING:删除管来呢数据,什么也不做
4.on_delete=models.PRPTECT:保护模式,删除关联数据,引发错误protectedError
5.on_delete=models.SET_NULL:置空模式,删除的时候,外键字段被设置为空,前提就是blank=True, null=True,定义该字段的时候,允许为空。当Manufacturer对象删除时,它对应的Car对象的manufacturer字段会置空,前提是null=True
6.on_delete=models.SET_DEFAULT:删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理)置默认值,删除的时候,外键字段设置为默认值,所以定义外键的时候注意加上一个默认值。
7.on_delete=models.SET:删除关联数据,自定义一个值,该值当然只能是对应的实体了
  7.1 与之关联的值设置为指定值,设置:models.SET(值)
  7.2 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
 posted on 2022-10-08 19:38  拾荒菇凉  阅读(69)  评论(0)    收藏  举报