drf之路由组件
自动生成路由
# drf提供了两个路由类,只要继承了ViewSetMixin及其子类的视图类,就可以使用这两个路由类来自动生成路由
# 使用步骤如下:
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)),
# SimpleRouter和DefaultRouter
DefaultRouter比SimpleRouter多一个根路径,显示所有注册过的路由
action装饰器
# 在视图函数中,会有一些其它名字的方法,必须要使用action装饰器做映射
# methods:支持的请求方式,列表
# detail:默认是False 控制生成的路由是 /user/login/ 还是 /user/pk/login 如果值是True则带pk,反之则不带
# url_path: 控制生成的/user/后面的路径是什么,如果不写,默认以方法名命名 /user/login/,一般跟函数名同名即可
# url_name:别名,用于反向解析
@action(methods=['GET','POST'], detail=True, url_path='login')
def login(self, request,pk):
# 这样写了以后可以:自动生成路由
drf之认证组件
创建认证类
# 通过认证类完成用户登录认证,使用步骤如下:
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 = []
代码示例
from rest_framework.authentication import BaseAuthentication
from .models import BookToken
from rest_framework.exceptions import AuthenticationFailed
class LoginAuth(BaseAuthentication):
def authenticate(self, request):
token = request.GET.get('token')
book_token = BookToken.objects.filter(token=token).first()
if book_token:
return book_token.book, token
else:
raise AuthenticationFailed('您还没有进行认证,请认证后进行登录')
自主练习
登录接口编写
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')
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
]
models.py
from django.db import models
# Create your models here.
class User(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=32)
def __str__(self):
return self.username
class UserToken(models.Model):
user = models.OneToOneField(to='User', on_delete=models.CASCADE)
token = models.CharField(max_length=32, null=True)
views.py
from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
from .models import User, UserToken
import uuid
from rest_framework.response import Response
# Create your views here.
class UserView(ViewSet):
@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())
UserToken.objects.update_or_create(defaults={'token': token}, user=user)
return Response({'code': 100, 'msg': '登录成功', 'token': token})
else:
return Response({'code': 101, 'msg': '用户名或密码错误'})
验证
图书和出版社接口编写
urls.py
from django.contrib import admin
from django.urls import path, include
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('books/', views.BookView.as_view()),
path('books/<int:pk>', views.BookDetailView.as_view()),
path('publish/', views.PublishView.as_view()),
path('publish/<int:pk>', views.PublishDetailView.as_view()),
]
models.py
from django.db import models
class Book(models.Model):
"书籍表"
book_name = models.CharField(max_length=32)
book_price = models.CharField(max_length=32)
book_publish = models.CharField(max_length=32)
def __str__(self):
return self.book_name
class Publish(models.Model):
"出版社表"
publish_name = models.CharField(max_length=32)
publish_address = models.CharField(max_length=128)
book = models.ForeignKey(to='Book', on_delete=models.CASCADE)
def __str__(self):
return self.publish_name
class BookToken(models.Model):
book = models.ForeignKey(to='Book', on_delete=models.CASCADE)
token = models.CharField(max_length=32, null=True)
serializer.py
from rest_framework import serializers
from .models import Book, Publish
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
class PublishModelSerializer(serializers.ModelSerializer):
class Meta:
model = Publish
fields = '__all__'
views.py
from django.shortcuts import render
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
from .models import Book, Publish
from .serializer import BookModelSerializer, PublishModelSerializer
from rest_framework.viewsets import ViewSet
class BookView(ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
class BookDetailView(RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
class PublishView(ListCreateAPIView):
authentication_classes = []
queryset = Publish.objects.all()
serializer_class = PublishModelSerializer
class PublishDetailView(RetrieveUpdateDestroyAPIView):
authentication_classes = []
queryset = Publish.objects.all()
serializer_class = PublishModelSerializer
auth.py
from rest_framework.authentication import BaseAuthentication
from .models import BookToken
from rest_framework.exceptions import AuthenticationFailed
class LoginAuth(BaseAuthentication):
def authenticate(self, request):
token = request.GET.get('token')
book_token = BookToken.objects.filter(token=token).first()
if book_token:
return book_token.book, token
else:
raise AuthenticationFailed('您还没有进行认证,请认证后进行登录')
settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.auth.LoginAuth', ]
}
验证
级联删除的其他字段参数
1、models.CASCADE
级联操作,当主表中被连接的一条数据删除时,从表中所有与之关联的数据同时被删除
2、models.SET_NULL
当主表中的一行数据删除时,从表中所有与之关联的数据的相关字段设置为null,此时注意定义外键时,这个字段必须可以允许为空
3、models.PROTECT
当主表中的一行数据删除时,由于从表中相关字段是受保护的外键,所以都不允许删除
4、models.SET_DEFAULT
当主表中的一行数据删除时,从表中所有相关的数据的关联字段设置为默认值,此时注意定义外键时,这个外键字段应该有一个默认值
5、models.SET()
当主表中的一条数据删除时,从表中所有的关联数据字段设置为SET()中设置的值,与models.SET_DEFAULT相似,只不过此时从表中的相关字段不需要设置default参数
6、models.DO_NOTHING
什么都不做,一切都看数据库级别的约束,注数据库级别的默认约束为RESTRICT,这个约束与django中的models.PROTECT相似
标签:10,models,08,token,book,user,2022,import,class
From: https://www.cnblogs.com/dy12138/p/16770030.html