drf 自动生成路由、认证类编写

drf 自动生成路由 认证类编写

1、自动生成路由

1.1、自动生成路由 编写

自动生成路由写法

  1. 导入:from rest_framework.routers import SimpleRouter, DefaultRouter

  2. 实例化:router = SimpleRouter()

  3. 注册:router.register('user', views.UserView,'user')

  4. 加入到urlpatterns中(两种方式)

    urlpatterns += router.urls

    path('',include(router.urls))

from django.contrib import admin
from django.urls import path,include

from app01 import views
from rest_framework.routers import SimpleRouter,DefaultRouter

router = SimpleRouter()
router.register('user', views.UserView,'user')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views.BookViews.as_view()),
    path('publishs/', views.PublishViews.as_view()),
    path('book/<int:pk>/', views.BookView.as_view()),
    path('publish/<int:pk>/', views.PublishView.as_view()),
    path('',include(router.urls))  # 方法二:
]

#方法一
# urlpatterns += router.urls

自动生成路由映射关系其实定死了
as_view({'get': 'list', 'post': 'create'}))
as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}))
以后写的视图类不需要写action装饰器的话,视图类中必须要有
list,destroy,retrieve,create,update方法之一
其实必须是5个视图扩展类之一+GenericAPIView 9个视图子类,ModelViewSet

SimpleRouter 和 DefaultRouter
DefaultTouter比SimpleRouter多一个跟路径,显示所有注册过的路由

1.2、action 装饰器的使用

在视图函数中,会有一些其它名字的方法,必须要使用action装饰器做映射
methods: 支持请求方式,列表
detail: 默认是False 控制生成的路由时 /user/login/还是/user/pk/login/ 是不是带pk
url_path: 控制生成的/user/后的路径是什么,如果不写,默认以方法命名 /user/login/,一般跟函数名同名即可
url_name: 别名,用于反向解析

class UserView(ViewSet):
    @action(methods=['POST'],detail=False,url_path='login')
    def login(self,request):

2、登录接口编写

2.1、models.py

如何区分用户是否登录?
创建一个用户登录记录表,创建一个字段,如果存有值则代表登录,如果没有登录则为空
登录多次以最后一次为准

class Token(models.Model):
    token = models.CharField(max_length=64,null=True)
    user = models.OneToOneField(to='User',on_delete=models.CASCADE)

2.2、views.py

当用户登录成功,不同用户生成的tokrn是不一样的
可以用 uuid.uuid4()
在Token表中 如果 没有记录就是新增,如果有记录就是更新
update_or_create 数据存在则更新,数据不存在则新增

class UserView(ViewSet):
    authentication_classes = []
    @action(methods=['POST'],detail=False,url_path='login')
    def login(self,request):
        username = request.data.get('username')
        password = request.data.get('password')
        user = User.objects.filter(username=username,password=password).first()
        if user:
            # 生成随机字符串
            token=str(uuid.uuid4())
			# 更新或新增数据
            Token.objects.update_or_create(user=user,defaults={'token':token})
            return Response({'code':100,'msg':'登录成功','token':token})

        return Response({'code':101,'msg':'账号或密码错误'})

2.3、urls.py

from rest_framework.routers import SimpleRouter, DefaultRouter

router = SimpleRouter()

router.register('user',views.UserView,'user')

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

3、认证

访问接口,必须登录后才能访问

通过认证类完成,使用步骤

  1. 写一个认证类,继承BaseAuthentication

  2. 重写authenticate方法,在内部做认证

  3. 如果认证通过,返回2个值

  4. 认证不通过抛异常AuthenticationFailed

  5. 只要返回两个值,在后续的request.user 就是当前登录用户

  6. 如果想让某个视图,登录后才能访问

    方式一:

    class BookView(ModelviewSet):
        authentication_classes = [loginAuth]
    

    方式二: 全局配置

    REST_FRAMEWORK={
                'DEFAULT_AUTHENTICATION_CLASSES':['app01.auth.LoginAuth',]
            }
    

    局部禁用

    authentication_classes = []
    

3.1、认证类

from app01.models import Token

from rest_framework.authentication import BaseAuthentication

from rest_framework.exceptions import AuthenticationFailed

#需要继承 BaseAuthentication
class Login_Auth(BaseAuthentication):
    # 注意 是重写 authenticate 方法 所以名字 不可乱取
    def authenticate(self, request):
        token = request.GET.get('token')
        user_token = Token.objects.filter(token=token).first()
        if user_token:
            # 返回两个值,一个是当前登录用户,一个是token
            return user_token.user, token

        raise AuthenticationFailed('您还未登录,请先登录')

4、级联删除 字段

CASCADE: 默认的,级联删除

**SET_NULL: ** 设置ForeignKey 为 null; 这个只有设置了null 为 True的情况才能用

**SET_DEFAULT: ** 设置 ForeignKey 为默认值; 默认值必须预先设置

**SET(): ** 设置为某个方法返回的值

**PROTECT: ** 通过抛出django.db.models.ProtectedErrordjango.db.models.ProtectedError错误来阻止删除关联的对象

**DO_NOTHING: ** 什么都不做,如果数据库设置必须关联则会报IntegrityError错

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值