(资料图)
# django转换器 2.x以后 为了取代re_pathint path("books/")--->/books/1--->pk=1--->当参数传入视图类的方法中 str path("books/") path path("media/",serve,{"document_root":"路径"} ), slug uuid # django配置文件1.Django项目要运行 优先执行配置文件的内容 做一下配置加载工作 manage.py中 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "drf_day07.settings") ##Django项目配置文件的路径可以修改 配置文件名也可以修改 但一般不会去改 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "配置文件路径") 2.任何一个Django项目都有两套配置 一套是项目自己的 自己有哪个配置参数 优先用自己的 一套是内置的(Django内置的) 3.配置参数的作用 # 1 项目的根路径 BASE_DIR # 2 密钥---》djagno中涉及到加密的,大部分都会用这个密钥 SECRET_KEY # 3 是否开启调试模式 上线一定关闭 只要是调试模式,访问路径不存在时,会显示出所有能访问的路径,视图类出了异常,浏览器中能看到 DEBUG = True 默认是True # 4 项目是要部署在某个服务器上 这个列表写部署服务器的ip地址 *表示任何地址都可以 ALLOWED_HOSTS = ["*"] 默认是空的 # 5 内置 我们自己写的app INSTALLED_APPS = [ "django.contrib.admin", # 后台管理---》很多表不是它的,是别的app的 "django.contrib.auth", # auth 模块,UsrInfo表----》有6个表 "django.contrib.contenttypes", # 有个django_content_type表是,这个app的 "django.contrib.sessions", # session相关的 "django.contrib.messages", # 消息框架 "django.contrib.staticfiles", # 静态文件开启的app "app01.apps.App01Config", # app01 自己写的app要在这里注册 "rest_framework" # drf 浏览器访问需要在这里注册 ] # 6 中间件 MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", # session相关 "django.middleware.common.CommonMiddleware", # 公共 "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware",] # 7 根路由 ROOT_URLCONF = "drf_day07.urls" # 默认是urls 也可以改文件名 一般不改 # 8 模板文件所在路径 TEMPLATES = [ ... ] # 9 项目上线,运行application,后面再说 WSGI_APPLICATION = "drf_day07.wsgi.application" # 10 数据库配置 DATABASES = { ... } # 11 做国际化 LANGUAGE_CODE = "zh-hans" # 语言 TIME_ZONE = "Asia/Shanghai" # 时区 USE_I18N = True USE_L10N = True USE_TZ = True # 12 静态文件STATIC_URL = "/static/" # 13 表中,默认可以不写id,id主键自增,之前全是AutoField,长度很短 DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
登录功能表模型class UserInfo(models.Model): username = models.CharField(max_length=32) password = models.CharField(max_length=64)class UserToken(models.Model): token = models.CharField(max_length=64) user = models.OneToOneField(to=UserInfo,on_delete=models.CASCADE)
视图类class UserView(ViewSet): @action(methods=["POST"],detail=False) def login(self,request): username = request.data.get("username") password = request.data.get("password") user_obj = UserInfo.objects.filter(username=username,password=password).first() if user_obj: # 登录成功 # 1 生成一个随机字符串 token token = str(uuid.uuid4()) # 2 把token存到表中 UserToken表有值就更新 没有值就增加 UserToken.objects.update_or_create(user=user_obj,defaults={"token":token}) return Response({"code": 100, "msg": "登录成功", "token": token}) else: return Response({"code": 101, "msg": "用户名或密码错误"})
路由# 方式一:path("login/",views.UserView.as_view({"post":"login"})),# 路由如果这样写 是不需要使用action装饰器# 方式二:自动生成路由---》视图类中一定要用action装饰器from rest_framework.routers import SimpleRouterrouter = SimpleRouter()router.register("user",views.UserView,"user")urlpatterns = [ path("admin/", admin.site.urls), # path("",include(router.urls))]# http://127.0.0.1:8000/user/login/urlpatterns += router.urls
认证组件# APIView执行流程在视图类的方法之前 执行了三大认证# 认证:登录认证登录认证---》控制某个接口必须登录后才能访问 # 认证组件使用步骤(固定用法)1 写一个类 继承BaseAuthentication from rest_framework.authentication import BaseAuthentication 2 在类中重写authenticate方法 class LoginAuth(BaseAuthentication): def authenticate(self, request): # 父类中有 一定要重写 否则报错 # 校验用户是否登录---》请求中携带我给的token 就是登录了 # token在哪携带 是接口规定的 # 1.规定待在请求地址中---》讲这个 # 2.规定带在请求头中(这个多) # 3.规定待在请求体中 # 取出token META HTTP_TOKEN """方法一 从请求地址中取""" # token = request.query_params.get("token") """方法二 从请求头中取""" token = request.META.get("HTTP_TOKEN") # 去数据库中 根据token 校验有没有数据 user_token = UserToken.objects.filter(token=token).first() if user_token: # 如果有就是已经登录 # print(request.user) 认证没有结束之前不能打印request.user 否则会递归 user = user_token.user print(user_token.user) # UserInfo object (1) return user,token else: # 说明它带的token不对的 raise AuthenticationFailed("你没有登录,不能访问") 3 在方法中 完成登录认证 如果没有登录则抛异常 4 如果是登录的 返回登录用户和token 5 在视图类中 使用认证类(局部使用)class BookView(APIView): authentication_classes = [LoginAuth,] 6 全局使用: ### 重点:不要在配置文件中,导入莫名其妙的包 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": [ "app01.auth.LoginAuth" ], } 7 全局使用认证后 局部禁用 class UserView(ViewSet): authentication_classes = [] # 列表置为空就可以 8 认证类的使用顺序 优先用视图类配置的 其次用项目配置文件 最后用drf默认的配置 # 小重点:一旦通过认证 在request中就有当前登录用户 request.user为当前登录用户def get(self,request): print(request.user.username,"访问了接口")
权限组件# 大家都登录了,但有的功能(接口),只有超级管理员能做,有的功能所有登录用户都能做----》这就涉及到权限的设计了# 权限设计:比较复杂---》有acl,rbac,abac。。。# 咱们现在只是为了先讲明白,drf的权限组件如何用,咱们先以最简单的为例查询所有图书:所有登录用户都能访问(普通用户和超级管理员) 没有权限控制 删除图书 只有超级管理员能访问 给其他用户设置的权限 # 权限类的使用步骤1.写一个类 继承BasePermission from rest_framework.permissions import BasePermission 2.在类中写方法:has_permission 如果有权限 就返回True 如果没有权限 就返回False 错误信息是self.message="字符串" class AdminPermission(BasePermission): def has_permission(self, request, view): # 如果有权限 就是返回True 没有权限 返回False # 判断user_type是不是1 根据当前登录用户 # request.user # 就是当前登录用户 一旦来到这里,登录认证就通过了 if request.user.user_type == 1: return True else: # 错误信息 self.message = "你好:%s,你没有权限" % request.user.username return False 3.局部使用 class BookDetailView(APIView): permission_classer = [AdminPermission,] 4.全局使用 REST_FRAMEWORK = { "DEFAULT_PERMISSION_CLASSES": [ "app01.permission.AdminPermission" ], } 5.局部禁用 class BookView(APIView): permission_classer = []
频率组件# 限制访问频次比如某个接口 一分钟只能访问5次 超过了就得等 按ip地址 限制 按用户id 限制# 频率类的使用步骤1.写个类 继承:SimpleRateThrottle 2.重写某个方法:get_cache_key 可以返回ip或者用户id 返回什么就以什么做频率限制 3.写一个类属性 随意命名一个名字 scope = "lqz" 4.在配置文件中配置 "DEFAULT_THROTTLE_RATES": { "lqz": "3/m" # 一分钟访问3次 }, 5.全局用 "DEFAULT_THROTTLE_CLASSES": [ ], 6.局部用 class BookView(APIView): throttle_classes = [MyThrottle]
关键词: