drf之路由组件
自动生成路由
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) ) ,
DefaultRouter比SimpleRouter多一个根路径,显示所有注册过的路由
action装饰器
@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
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
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相似
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)