国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

DRF JWT認(rèn)證進(jìn)階

這篇具有很好參考價值的文章主要介紹了DRF JWT認(rèn)證進(jìn)階。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

JWT認(rèn)證進(jìn)階

【0】準(zhǔn)備工作

(1)模型準(zhǔn)備

  • 模型準(zhǔn)備(繼承djangoauth_user表)
from django.db import models
from django.contrib.auth.models import AbstractUser

class UserInfo(AbstractUser):
    mobile = models.CharField(max_length=11, verbose_name='手機(jī)號碼')

  • 添加配置文件,修改用戶模型表為自定義表
AUTH_USER_MODEL = 'app名稱.UserInfo'

(2)知識點綁定方法

  • 詳情請見:Python 面向?qū)ο笾壎ê头墙壎ǚ椒╛python 綁定方法-CSDN博客
  • 實例方法
    • 當(dāng)對象調(diào)用實例方法時(對象.實例方法()),自動將對象當(dāng)作第一個參數(shù)傳入
    • 當(dāng)類調(diào)用實例方法時(類.實例方法(類())),需要手動傳入一個實例
  • 類方法
    • 當(dāng)類調(diào)用類方法時(類.類方法()),自動將類當(dāng)作第一個參數(shù)傳入
    • 當(dāng)對象調(diào)用類方法時(對象.類方法()),自動將對象的類當(dāng)作第一個參數(shù)傳入
  • 簡單示例
class A:
    def __init__(self, name):
        self.name = name

    @classmethod
    def hi(cls):
        print(f"{cls.__name__} say hi")

    def hello(self):
        print(f"{self.name} say hello")


a = A('bruce')
# 實例調(diào)用類方法,自定將類傳入
a.hi()
# 類調(diào)用實例方法,需要手動將實例對象傳入
A.hello(a)

(3)保存信息顯示中文

  • 在配置文件中注冊app就可以
INSTALLED_APPS = [
    'rest_framework_simplejwt',
]

【1】jwt配置文件

(1)整體查看

  • 這些內(nèi)容都在from rest_framework_simplejwt import settings可以自己去查看
DEFAULTS = {
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=5),# 訪問令牌的有效期。這里設(shè)置為5分鐘。
    "REFRESH_TOKEN_LIFETIME": timedelta(days=1),# 刷新令牌的有效期。這里設(shè)置為1天。
    "ROTATE_REFRESH_TOKENS": False,# 是否每次使用刷新令牌時都生成新的刷新令牌。這里設(shè)置為False。
    "BLACKLIST_AFTER_ROTATION": False,# 刷新令牌在旋轉(zhuǎn)后是否應(yīng)該被加入黑名單。這里設(shè)置為False。
    "UPDATE_LAST_LOGIN": False,# 是否在每次驗證令牌時更新用戶的最后登錄時間。這里設(shè)置為False。
    "ALGORITHM": "HS256",# 用于簽名的算法。這里使用的是HS256。
    "SIGNING_KEY": settings.SECRET_KEY,# 用于簽名的密鑰。這里使用的是Django的SECRET_KEY。
    "VERIFYING_KEY": "",# 用于驗證令牌的密鑰。這里沒有設(shè)置。
    "AUDIENCE": None,# JWT的接收者。這里沒有設(shè)置。
    "ISSUER": None,# JWT的簽發(fā)者。這里沒有設(shè)置。
    "JSON_ENCODER": None,# 用于序列化JWT負(fù)載的JSON編碼器。這里沒有設(shè)置。
    "JWK_URL": None,# JSON Web Key Set的URL,用于公鑰檢索。這里沒有設(shè)置。
    "LEEWAY": 0,# 在驗證JWT的時間戳?xí)r允許的時間誤差(秒)。這里設(shè)置為0。
    "AUTH_HEADER_TYPES": ("Bearer",),# 認(rèn)證頭中可以接受的令牌類型。這里設(shè)置為只接受"Bearer"類型。
    "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION",# 認(rèn)證頭的名稱。這里設(shè)置
    "USER_ID_FIELD": "id",# 用戶的ID字段名。這里設(shè)置為"id"。
    "USER_ID_CLAIM": "user_id",# JWT中用戶ID的聲明名稱。這里設(shè)置為"user_id"。
    "USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule",# 用于驗證用戶的規(guī)則。這里使用的是默認(rèn)規(guī)則。
    "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),# l令牌類。這里設(shè)置為只使用訪問令牌。
    "TOKEN_TYPE_CLAIM": "token_type",# 用于表示用戶的模型類。這里使用的是默認(rèn)模型。
    "JTI_CLAIM": "jti",#  JWT的JTI(JWT ID)聲明名稱。這里設(shè)置為"jti"。
    "TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser",# 用于表示用戶的模型類。這里使用的是默認(rèn)模型。
    "SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp",# 滑動刷新令牌中的過期聲明名稱。這里設(shè)置為"refresh_exp"。
    "SLIDING_TOKEN_LIFETIME": timedelta(minutes=5),# 滑動訪問令牌的有效期。這里設(shè)置為5分鐘。
    "SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1),# 滑動刷新令牌的有效期。這里設(shè)置為1天。
    "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer",# 用于獲取令牌的序列化器。這里使用默認(rèn)的序列化器。
    "TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer",# 用于刷新令牌的序列化器。這里使用默認(rèn)的序列化器。
    "TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer",# 用于驗證令牌的序列化器。這里使用默認(rèn)的序列化器。
    "TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer",# 用于黑名單令牌的序列化器。這里使用默認(rèn)的序列化器。
    "SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer",# 用于獲取滑動令牌的序列化器。這里使用默認(rèn)的序列化器。
    "SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer",# 用于刷新滑動令牌的序列化器。這里使用默認(rèn)的序列化器。
    "CHECK_REVOKE_TOKEN": False,# 是否檢查令牌是否已被撤銷。這里設(shè)置為False。
    "REVOKE_TOKEN_CLAIM": "hash_password",# 用于撤銷令牌的聲明名稱。這里設(shè)置為"hash_password"。
}

(2)常用的配置

  • ACCESS_TOKEN_LIFETIME: 訪問令牌的有效期。這里設(shè)置為5分鐘。

  • REFRESH_TOKEN_LIFETIME: 刷新令牌的有效期。這里設(shè)置為1天。

  • TOKEN_OBTAIN_SERIALIZER:可自定義登錄的序列化器

【2】定制登錄返回格式

(1)定制整體返回格式

  • jwt默認(rèn)返回格式是一個字典,包含兩個鍵值對
    • 一個是刷新相關(guān)的token,另一個是登錄相關(guān)的token
  • 我們期望的格式是一個大字典,包含返回自定義狀態(tài)碼code、描述信息msg、用戶名username和默認(rèn)的兩個token
    • 所以需要我們自定義,這里的方法是替換默認(rèn)的登錄序列化類,自定義序列化類以實現(xiàn)自定義的返回整體格式
  • 通過默認(rèn)配置:
    • "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer"
    • 可知道這個類是負(fù)責(zé)登錄序列化的,為了方便,繼承它,重寫它的方法,添加自定義的屬性
    • 通過簡單觀察源碼發(fā)現(xiàn),返回的內(nèi)容就是validate里面的data,所以只需要在這個data中添加修改一下字段就可以

DRF JWT認(rèn)證進(jìn)階,Django RESTFrameWork,sqlite,數(shù)據(jù)庫,python,django

  • 代碼
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

class JWTTokenPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        data = super().validate(attrs)
        new_data = {
            "code": 100,
            "msg": '登錄驗證成功',
            "username": self.user.username,
            "refresh": data.get("refresh"),
            "access": data.get("access"),
        }
        return new_data
# 配置文件替換默認(rèn)的序列化類
SIMPLE_JWT ={
    'TOKEN_OBTAIN_SERIALIZER':'自定義序列化類的位置.JWTTokenPairSerializer'
}

# 使用默認(rèn)的JWT登錄
from django.urls import path
from rest_framework_simplejwt.views import token_obtain_pair
urlpatterns = [
    path('v0/login/', token_obtain_pair),
]

DRF JWT認(rèn)證進(jìn)階,Django RESTFrameWork,sqlite,數(shù)據(jù)庫,python,django

(2)定制payload載荷

  • 默認(rèn)載荷部分包含了

    • token_type表示這是一個訪問令牌(access token)
    • exp是令牌的過期時間(UNIX時間戳)
    • iat是令牌的簽發(fā)時間
    • jti是令牌的唯一標(biāo)識符
    • user_id是用戶ID
  • 現(xiàn)在思考如何添加自定義字段,比如用戶的用戶名

    • 還是通過一步一步的找token,最終找到了載荷payload,是一個字典所以可以嘗試,像普通字典一樣添加新的信息
    • 注意:這里面雖然有類方法,但是無論是self還是super都是實例對象,可以直接調(diào)用類方法

DRF JWT認(rèn)證進(jìn)階,Django RESTFrameWork,sqlite,數(shù)據(jù)庫,python,django

  • 代碼:還是修改序列化類
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

class JWTTokenPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        token['username'] = user.username
        return token
  • 檢查,添加成功
import base64

s = 'token第二段==='
res = base64.b64decode(s.encode('utf8'))
# b'{"token_type":"access","exp":1713528635,"iat":1713528335,"jti":"cc57595cd70f4938baa4673a6f1538ad","user_id":1}
# b'{"token_type":"access","exp":1713530348,"iat":1713530048,"jti":"6807d0722efb41bba01742a44767c18d","user_id":1,"username":"admin"}'

【3】多方式登錄

(1)簡介

  • 實際的案例中,登錄的方式有很多種,既可以是用戶名,還可以是手機(jī)號,還可以是郵箱等,并且他們的登錄輸入入口都是一個,所以這里將實現(xiàn)這種接口

DRF JWT認(rèn)證進(jìn)階,Django RESTFrameWork,sqlite,數(shù)據(jù)庫,python,django

(2)登錄視圖函數(shù)和路由

  • 序列化類有檢驗功能,所以重心不在這里
# 路由層
from django.urls import path, include
from rest_framework.routers import SimpleRouter
from .views import JWTLoginAPIView

router = SimpleRouter()
router.register('', JWTLoginAPIView, basename='login')
urlpatterns = [
    path('v1/', include(router.urls)),
]
# 視圖層
from rest_framework.viewsets import GenericViewSet
from .serializer import JWTTokenSerializer
from rest_framework.response import Response
from rest_framework.decorators import action


class JWTLoginAPIView(GenericViewSet):
    serializer_class = JWTTokenSerializer

    @action(methods=['post'], detail=False)
    def login(self, request, *args, **kwargs):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            refresh = ser.context.get('refresh')
            access = ser.context.get('access')
            return Response({"code": 100, "msg": "登錄驗證成功", "refresh": refresh, "access": access})
        return Response({"code": 100, "msg": ser.erros})

(3)序列化類

  • 序列化類的檢驗分為三個過程,首先是字段參數(shù)(包括validators),然后是局部鉤子,最后是全局鉤子
  • 由于需要校驗用戶輸入字段和密碼字段,所以使用全局鉤子
  • 整體邏輯
    • 使用不同方法區(qū)分傳入的值是電話,還是郵箱,還是手機(jī)號
    • 由于使用的是django的用戶表,所以要用相應(yīng)的加密方法判斷密碼
    • 在定制載荷payload中,知道了RefreshToken處理token,所以要調(diào)用這個類的類方法for_user處理
import re

from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework_simplejwt.tokens import RefreshToken
from .models import UserInfo


class JWTTokenSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

    def validate(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        if re.match(r'^1[3-9][0-9]{9}$', username):
            user = UserInfo.objects.filter(username=username).first()
        elif re.match(r"/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/", username):
            user = UserInfo.objects.filter(username=username).first()
        else:
            user = UserInfo.objects.filter(username=username).first()
        # 使用的是django的表,需要使用響應(yīng)的方法進(jìn)行密碼檢驗
        if user and user.check_password(password):
            # 獲取token
            token = RefreshToken.for_user(user)
            self.context['refresh'] = str(token)
            self.context['access'] = str(token.access_token)
            return attrs
        raise ValidationError("用戶名或者密碼錯誤")

DRF JWT認(rèn)證進(jìn)階,Django RESTFrameWork,sqlite,數(shù)據(jù)庫,python,django

【4】自定義用戶表、手動簽發(fā)和認(rèn)證

(1)模型表

  • 用戶表用普通的表
  • 創(chuàng)建一個數(shù)據(jù)表用于側(cè)式認(rèn)證功能
from django.db import models

class UserNormal(models.Model):
    username = models.CharField(max_length=64, verbose_name='用戶名')
    password = models.CharField(max_length=64, verbose_name='密碼')

class Book(models.Model):
    name = models.CharField(max_length=64, verbose_name="書名")
    price = models.CharField(max_length=64, verbose_name="價格")
    publish = models.CharField(max_length=64, verbose_name="出版社")

(2)路由層

  • 自動路由
from django.urls import path, include
from rest_framework.routers import SimpleRouter
from .views import JWTLoginAPIView, BookAPIView

router = SimpleRouter()
router.register('', JWTLoginAPIView, basename='login')
router.register('book', BookAPIView, basename='book')
urlpatterns = [
    path('v1/', include(router.urls)),
]

(3)視圖層

  • 和之前沒有區(qū)別,多創(chuàng)一個視圖類用于測試
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from .serializer import JWTTokenSerializer, BookModelSerializer
from rest_framework.response import Response
from rest_framework.decorators import action
from .models import Book
from .authentication import JWTAuth

class BookAPIView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer
    authentication_classes = [JWTAuth]
    
class JWTLoginAPIView(GenericViewSet):
    serializer_class = JWTTokenSerializer

    @action(methods=['post'], detail=False)
    def login(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            refresh = ser.context.get('refresh')
            access = ser.context.get('access')
            return Response({"code": 100, "msg": "登錄驗證成功", "refresh": refresh, "access": access})
        return Response({"code": 100, "msg": ser.errors})

(4)序列化

import re

from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework_simplejwt.tokens import RefreshToken
from .models import UserInfo, Book, UserNormal


class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = "__all__"


class JWTTokenSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

    def validate(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        user = UserNormal.objects.filter(username=username, password=password).first()
        if user:
            # 獲取token
            token = RefreshToken.for_user(user)
            self.context['access'] = str(token.access_token)
            self.context['refresh'] = str(token)

            return attrs
        raise ValidationError("用戶名或者密碼錯誤")

(5)認(rèn)證類

from rest_framework_simplejwt.authentication import JWTAuthentication
from .models import UserNormal
from rest_framework.exceptions import AuthenticationFailed


class JWTAuth(JWTAuthentication):
    def authenticate(self, request):
        token = request.META.get("HTTP_AUTHORIZATION")

        if token:
            # 調(diào)用父類的方法驗證token,內(nèi)部會自動驗證拋出異常
            validated_token = super().get_validated_token(token)
            # 放入的默認(rèn)信息是user_id
            user_id = validated_token.get('user_id')
            user = UserNormal.objects.filter(pk=user_id)
            return user, token
        else:
            raise AuthenticationFailed("登錄認(rèn)證信息認(rèn)證失敗")

(6)測試

  • 注意:上面調(diào)用的方法,不可以在token的前面帶任何參數(shù)

DRF JWT認(rèn)證進(jìn)階,Django RESTFrameWork,sqlite,數(shù)據(jù)庫,python,django

  • 解決辦法:
    • 使用父類的獲取原生token方法,這樣仍將攜帶配置文件中的要求(Bearer,也可以自定義其他的)
header = self.get_header(request)
token = self.get_raw_token(header)

DRF JWT認(rèn)證進(jìn)階,Django RESTFrameWork,sqlite,數(shù)據(jù)庫,python,django文章來源地址http://www.zghlxwxcb.cn/news/detail-859764.html

到了這里,關(guān)于DRF JWT認(rèn)證進(jìn)階的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Django進(jìn)階:DRF(Django REST framework)

    Django進(jìn)階:DRF(Django REST framework)

    DRF 即 Django REST framework 的縮寫,官網(wǎng)上說: Django REST framework 是一個強(qiáng)大而靈活的工具包,用于 構(gòu)建Web API 。 簡單來說:通過DRF創(chuàng)建API后,就可以通過HTTP請求來獲取、創(chuàng)建、更新或刪除數(shù)據(jù)(CRUD)。 那么為什么要構(gòu)建API呢? 在Django中,我們通過 model-view-template 實現(xiàn)了 后端和前

    2024年02月11日
    瀏覽(29)
  • Django REST Framework完整教程-認(rèn)證與權(quán)限-JWT的使用

    Django REST Framework完整教程-認(rèn)證與權(quán)限-JWT的使用

    閱讀本文之前,請讀者先閱讀: https://plugin.blog.csdn.net/article/details/133853377,如果已經(jīng)知曉Django REST Framework的基礎(chǔ),可以繼續(xù)閱讀本文內(nèi)容。 認(rèn)證(Authentication)與權(quán)限(Permission)不是一回事。認(rèn)證是通過用戶提供的用戶ID/密碼組合或者Token來驗證用戶的身份。權(quán)限(Permission)的校驗

    2024年02月07日
    瀏覽(15)
  • django如何連接sqlite數(shù)據(jù)庫?

    django如何連接sqlite數(shù)據(jù)庫?

    目錄 一、SQLite數(shù)據(jù)庫簡介 二、Django連接SQLite數(shù)據(jù)庫 1、配置數(shù)據(jù)庫 2、創(chuàng)建數(shù)據(jù)庫表 三、使用Django ORM操作SQLite數(shù)據(jù)庫 1、定義模型 2、創(chuàng)建對象 3、查詢對象 總結(jié) 本文將深入探討如何在Django框架中連接和使用SQLite數(shù)據(jù)庫。我們將介紹SQLite數(shù)據(jù)庫的特點,Django的數(shù)據(jù)庫配置,以

    2024年02月06日
    瀏覽(34)
  • Android 進(jìn)階 1、sqlite數(shù)據(jù)庫

    Android 進(jìn)階 1、sqlite數(shù)據(jù)庫

    在我們學(xué)會了Android的基本使用之后就需要往高處發(fā)展了,畢竟水往高處流,很多時候我們學(xué)習(xí)一門技術(shù)感覺沒有收獲都是因為還沒到那個層次,當(dāng)你一步步往上走的時候就會漸漸發(fā)現(xiàn)自己收獲的越來越多,進(jìn)步也就會越來越快了,廢話不多說,回到正題; 1、認(rèn)識數(shù)據(jù)庫 安卓

    2024年02月10日
    瀏覽(20)
  • 【Django】讓SQLite數(shù)據(jù)庫中表名支持重命名的方法

    【Django】讓SQLite數(shù)據(jù)庫中表名支持重命名的方法

    修改了數(shù)據(jù)庫表名之后,更新數(shù)據(jù)庫時跳錯: 意思就是 SQLite 數(shù)據(jù)庫不支持重命名的操作,添加atomic = False即可: Migration 在 py36Libsite-packagesdjangodbmigrationsmigration.py 的位置 將 atomic = True 改成 atomic = False

    2024年02月10日
    瀏覽(43)
  • drf——jwt

    drf——jwt

    2024年02月06日
    瀏覽(22)
  • 基于Qt數(shù)據(jù)庫項目實現(xiàn)(Sqlite3為例)|考查數(shù)據(jù)庫、表格(QTableView 顯示)(進(jìn)階)

    01?數(shù)據(jù)庫表格(QTableView 顯示) 本小節(jié)設(shè)計一個生活中的例子,使用數(shù)據(jù)庫修改/查詢員工的編號、姓名、年齡、性別與照片信息。 本例將數(shù)據(jù)庫的內(nèi)容顯示到?QTableView?上。如果只是簡單的顯示數(shù)據(jù)庫的內(nèi)容到QTableView?上,可以使用下面的方法,此方法?QTableView?上可以看到

    2024年02月20日
    瀏覽(24)
  • 基于Qt數(shù)據(jù)庫項目實現(xiàn)(Sqlite3為例)|考查數(shù)據(jù)庫、繪制(畫家)、事件等知識點(進(jìn)階)

    堅持最初的夢想,揚帆起航,乘風(fēng)破浪,永不言敗。 01 數(shù)據(jù)庫 數(shù)據(jù)庫是什么?簡易言之,就是保存數(shù)據(jù)的文件。可以存儲大量數(shù)據(jù),包括插入數(shù)據(jù)、更新數(shù)據(jù)、截取數(shù)據(jù)等。用專業(yè)術(shù)語來說,數(shù)據(jù)庫是“按照數(shù)據(jù)結(jié)構(gòu)來組織、存儲和管理數(shù)據(jù)的倉庫”。是一個長期存儲在計

    2024年02月19日
    瀏覽(21)
  • drf——全局處理異常、接口文檔、jwt介紹、based64編碼與解碼
  • Django創(chuàng)建應(yīng)用、ORM的進(jìn)階使用及模型類數(shù)據(jù)庫遷移

    Django創(chuàng)建應(yīng)用、ORM的進(jìn)階使用及模型類數(shù)據(jù)庫遷移

    Django 項目就是基于 Django 框架開發(fā)的 Web 應(yīng)用,它包含了一組配置和多個應(yīng)用,我們把應(yīng)用稱之為 App,在前文中對它也做了相應(yīng)的介紹,比如 auth、admin,它們都屬于 APP。 一個 App 就是一個 Python 包,通常一個 App 可以包含模型、視圖、模板和 URL 配置文件,可以被應(yīng)用到多個

    2024年02月09日
    瀏覽(94)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包