首页 > 其他分享 >drf:django restframework(一)

drf:django restframework(一)

时间:2025-01-16 18:31:21浏览次数:3  
标签:self request django token restframework user import data drf

1. 快速上手

安装:

pip install djangorestframework

配置,在settings.py中添加配置(这个drf是有默认app的,就是rest_framework。),后面的drf相关配置是在REST_FRAMEWORK 里面配置。

INSTALLED_APPS = [
    ...
    # 注册rest_framework(drf)
    'rest_framework',
]

# drf相关配置以后编写在这里 
REST_FRAMEWORK = {
   
}

url和视图绑定:

# urls.py

from django.urls import path
from app01 import views

urlpatterns = [
    path('users/', views.UserView.as_view()),
]
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response


class UserView(APIView):
    def get(self, request, *args, **kwargs):
        return Response({"code": 1000, "data": "xxx"})

    def post(self, request, *args, **kwargs):
        return Response({"code": 1000, "data": "xxx"})

运行结果:

drf中重写了 as_viewdispatch方法,其实就是在原来django的功能基础上添加了一些功能,例如:

1.as_view,免除了csrf 验证,一般前后端分离不会使用csrf token认证(后期会使用jwt认证)。

2.dispatch,内部添加了 版本处理、认证、权限、访问频率限制等诸多功能(后期逐一讲解)。

2. 请求数据的封装

以前我们通过django开发项目时,视图中的request是 django.core.handlers.wsgi.WSGIRequest 类的对象,其中包含了请求相关的所有数据。

#views.py
# Django FBV
def index(request):
	request.method
	request.POST
	request.GET
	request.body

# Django CBV
from django.views import View
class UserView(View):
	def get(self,request):
        request.method
        request.POST
        request.GET
        request.body

而在使用drf框架时,视图中的request是rest_framework.request.Request类的对象,其是又对django的request进行了一次封装,包含了除django原request对象以外,还包含其他后期会使用的其他对象。

#views.py
from rest_framework.views import APIView
from rest_framework.response import Response


class UserView(APIView):
    def get(self, request, *args, **kwargs):
        # request,不再是django中的request,而是又被封装了一层,内部包含:django的request、认证、解析器等。
        return Response({"code": 1000, "data": "xxx"})

    def post(self, request, *args, **kwargs):
        return Response({"code": 1000, "data": "xxx"})

变成:对象 = (request, 其他数据)

自从UserView继承了APIView后,request已经不是之前django的request了,就把它重新封装到了request里面了并且添加了其它数据,def get(self, request, *args, **kwargs):。

所以,在使用drf框架开发时,视图中的request对象与原来的有些不同,例如:

from rest_framework.views import APIView
from rest_framework.response import Response
from django.views import View
from rest_framework.request import Request


class UserView(APIView):
    def get(self, request, *args, **kwargs):
        
        # 通过对象的嵌套直接找到原request,读取相关值
        request._request.method
        request._request.GET
        request._request.POST
        request._request.body
        
        # 举例:
        	content-type: url-form-encoded
        	v1=123&v2=456&v3=999
            django一旦读取到这个请求头之后,就会按照 {"v1":123,"v2":456,"v3":999}
            
            content-type: application/json
            {"v1":123,"v2":456}
            request._request.POST
            request._request.body
        
        # 直接读取新request对象中的值,一般此处会对原始的数据进行一些处理,方便开发者在视图中使用。
        request.query_params  # 内部本质上就是 request._request.GET
        request.data # 内部读取请求体中的数据,并进行处理,例如:请求者发来JSON格式,他的内部会对json字符串进行反序列化。
        
        # 通过 __getattr__ 去访问 request._request 中的值
        request.method
        
        

        可以通过对象的嵌套直接找到原request,读取相关值
        request._request.method
        request._request.GET
        request._request.POST
        request._request.body

request.query_params  # 内部本质上就是 request._request.GET

request.data在request._request.POST和request._request.body基础上做了补丁。

request.data # 内部读取请求体中的数据,并进行处理,例如:请求者发来JSON格式,他的内部会对json字符串进行反序列化。

如果是读取get方式就可以使用request.query_params,如果是读取post请求或者其它请求的话,就可以使用request.data

如果是想获取request.method的话,也是可以直接使用,因为它内部做了调整,也就是说request.method=self._request.method

# 通过 __getattr__ 去访问 request._request 中的值

Request 源码:

# rest_framework.request.Request 类

class Request:
    """
    Wrapper allowing to enhance a standard `HttpRequest` instance.
    Kwargs:
        - request(HttpRequest). The original request instance. (django中的request)
        - parsers(list/tuple). The parsers to use for parsing the
          request content.
        - authenticators(list/tuple). The authenticators used to try
          authenticating the request's user.
    """

    def __init__(self, request, parsers=None, authenticators=None,negotiator=None, parser_context=None):
    	self._request = request
        self.parsers = parsers or ()
        self.authenticators = authenticators or ()
        ...
	
    @property
    def query_params(self):
        """
        More semantically correct name for request.GET.
        """
        return self._request.GET

    @property
    def data(self):
        if not _hasattr(self, '_full_data'):
            self._load_data_and_files()
        return self._full_data
    
	def __getattr__(self, attr):
        try:
            return getattr(self._request, attr) # self._request.method
        except AttributeError:
            return self.__getattribute__(attr)

3. 版本管理

在restful规范中要去,后端的API中需要体现版本。

drf框架中支持5种版本的设置。

3.1 URL的GET参数传递(*)

现在应该有种疑问,如果直接把导航栏version更改的话,就列如vs=v2这样子可以吗,那肯定是不行的,因为version是固定的。

我们可以通过更改配置来更改version,那么就要在settings.py里面更改配置

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import QueryParameterVersioning,URLPathVersioning
from rest_framework.exceptions import AuthenticationFailed
from app1 import models

class UserView(APIView):
    versioning_class = QueryParameterVersioning

    def get(self, request, *args, **kwargs):
        print(request.version)
        return Response({"code": 1000, "data": "xxx"})
    
    def post(self, request, *args, **kwargs):
        
        
        return Response({"code":1000,"data":"xxx"})


有三种配置:

我们可以直接在源码中查找:

第一步:

第二步:

第三步:

红圈这三个(DEFAULT_VERSION,ALLOWED_VERSIONS,VERSION_PARAM)


一:操作展示:(在配置文件中添加该VERSION_PARAM)

这样子就意味着上面的version更改为了v4(这样子以后只能写v4,不能再写version):

二:操作展示:(在配置文件中添加该DEFAULT_VERSION)

如果我们不在导航栏输入version(版本)的话,就会显示None:

DEFAULT_VERSION这个就是代表默认值,


三:操作展示:(在配置文件中添加该ALLOWED_VERSIONS)

ALLOWED_VERSIONS可以在定义的列表里面的版本,

如果超过该列表的版本值的话,那么就会报错:

如果觉得在每个视图类里面都得放入QueryParameterVersioning觉得麻烦,我们可以在配置文件里面配置全局:

 "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.QueryParameterVersioning",  # 处理版本的类的路径

此后视图 类就不用再使用。

3.2 URL路径传递(*)

3.3 请求头传递

3.4 二级域名传递

3.5 路由的namespace传递

全局配置

上述示例中,如果想要应用某种 版本 的形式,需要在每个视图类中定义类变量:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import QueryParameterVersioning


class UserView(APIView):
    versioning_class = QueryParameterVersioning
    ...

如果你项目比较大,需要些很多的视图类,在每一个类中都写一遍会比较麻烦,所有drf中也支持了全局配置。

# settings.py

REST_FRAMEWORK = {
    "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.QueryParameterVersioning",  # 处理版本的类的路径
    "VERSION_PARAM": "version",  # URL参数传参时的key,例如:xxxx?version=v1
    "ALLOWED_VERSIONS": ["v1", "v2", "v3"],  # 限制支持的版本,None表示无限制
    "DEFAULT_VERSION": "v1",  # 默认版本
}

反向生成URL

在每个版本处理的类中还定义了reverse方法,他是用来反向生成URL并携带相关的的版本信息用的

4. 认证

对于认证组件,我们可以定义一个类继承BaseAuthentication,不一定要放到views.py文件里面

如果认证成功就执行上面的authenticate

认证失败就执行下面的authenticate_header就是说认证类的方法是放到函数里面。

那么我们怎么把认证类和我们的视图绑定起来认证?

在视图类里面,要通过authentication_classes来判断,如果认证成功就会执行下面的,如果认证失败就返回认证类里面的错误

views.py代码:

因为post请求,不用认证也可以访问,所以就不用认证类

import uuid
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import BaseAuthentication, TokenAuthentication
from rest_framework.exceptions import AuthenticationFailed
from project.app1 import models


class UserView(APIView):

    def post(self, request, *args, **kwargs):
        print(request.data)
        username = request.data.get('username')
        password = request.data.get('password')

        user_object = models.User.objects.get(username=username, password=password).first()

        if not user_object:
            return Response({'code': 1000, "data": "用户名或密码错误"})

        token = str(uuid.uuid4())
        user_object.token = token
        user_object.save()

        return Response({"code": 0, "data": {'token': token, 'name': username}})


class TokenAuthentication(BaseAuthentication):
    def authenticate(self, request):
        token = request.query_params.get('token')
        if not token:
            raise AuthenticationFailed({"code":1002,"data":"认证失败"})
        user_object = models.User.objects.filter(token=token).first()
        if not user_object:
            raise AuthenticationFailed({"token":1002,"data":"认证失败"})

        #如果认证成功后,request.user就是user_object;request.auth就是token。
        return user_object,token

    def authenticate_header(self, request):
        return 'Beare realm="API"'


class OrderView(APIView):
    authentication_classes = [TokenAuthentication, ]

    def get(self, request, *args, **kwargs):
        #读取用户请求传过来的token
        print(request.user)  #用户对象
        print(request.auth)  #token
        return Response({'code': 0, "data": {'user': None, 'list': [1, 2, 3]}})


class PayView(APIView):
    authentication_classes = [TokenAuthentication, ]

    def get(self, request, *args, **kwargs):
        print(request.user)
        print(request.auth)
        return Response({'code': 0, "data": "数据..."})

在视图类中设置类变量 authentication_classes的值为 认证类 MyAuthentication,表示此视图在执行内部功能之前需要先经过 认证。

认证类的内部就是去执行:authenticate方法,根据返回值来表示认证结果。

  • 抛出异常AuthenticationFailed,表示认证失败。内部还会执行 authenticate_header将返回值设置给响应头 WWW-Authenticate

  • 返回含有两个元素的元组,表示认证成功,并且会将元素的第1个元素赋值给 request.user、第2个值赋值给request.auth

第1个值,一般是用户对象。
第2个值,一般是token

返回None,表示继续调用 后续的认证类 进行认证(上述案例未涉及)

关于 ”返回None“

接下来说说 “返回None” 是咋回事。

在视图类的 authentication_classes 中定义认证类时,传入的是一个列表,支持定义多个认证类。

当出现多个认证类时,drf内部会按照列表的顺序,逐一执行认证类的 authenticate 方法,如果 返回元组 或 抛出异常 则会终止后续认证类的执行;如果返回None,则意味着继续执行后续的认证类。

如果所有的认证类authenticate都返回了None,则默认 request.user="AnonymousUser" 和 request.auth=None,也可以通过修改配置文件来修改默认值。

REST_FRAMEWORK = {
 "UNAUTHENTICATED_USER": lambda: None,
 "UNAUTHENTICATED_TOKEN": lambda: None,
}

”返回None“的应用场景:

当某个API,已认证 和 未认证 的用户都可以方法时,比如:

  • 已认证用户,访问API返回该用户的视频播放记录列表。

  • 未认证用户,访问API返回最新的的视频列表。

注意:不同于之前的案例,之前案例是:必须认证成功后才能访问,而此案例则是已认证和未认证均可访问。

这种认证的作用意思是,比如一个人匿名进入这个网站,不登录该网站,它看到数据和已登录用户的数据不同。

import uuid
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import BaseAuthentication, TokenAuthentication
from rest_framework.exceptions import AuthenticationFailed
from project.app1 import models


class UserView(APIView):

    def post(self, request, *args, **kwargs):
        print(request.data)
        username = request.data.get('username')
        password = request.data.get('password')

        user_object = models.User.objects.get(username=username, password=password).first()

        if not user_object:
            return Response({'code': 1000, "data": "用户名或密码错误"})

        token = str(uuid.uuid4())
        user_object.token = token
        user_object.save()

        return Response({"code": 0, "data": {'token': token, 'name': username}})


class TokenAuthentication(BaseAuthentication):
    def authenticate(self, request):
        token = request.query_params.get('token')
        if not token:
            return None

        #如果认证成功后,request.user就是user_object;request.auth就是token。
        user_object  = models.UserInfo.object.filter(token=token).first()
        if not user_object:
            return AuthenticationFailed({"code":1002,"data":"认证失败"})

        return user_object,token

    def authenticate_header(self, request):
        return 'Beare realm="API"'


class OrderView(APIView):
    authentication_classes = [TokenAuthentication, ]

    def get(self, request, *args, **kwargs):
        #读取用户请求传过来的token
        print(request.user)  #用户对象
        print(request.auth)  #token
        if not request.user:
            return Response({"code":0,"data":[11,22,33]})
        return Response({'code': 0, "data": {'user': None, 'list': [1, 2, 3]}})


class PayView(APIView):
    authentication_classes = [TokenAuthentication, ]

    def get(self, request, *args, **kwargs):
        print(request.user)
        print(request.auth)
        return Response({'code': 0, "data": "数据..."})

关于多个认证类

一般情况下,编写一个认证类足矣。

当项目中可能存在多种认证方式时,就可以写多个认证类。例如,项目认证支持:

  • 在请求中传递token进行验证。

  • 请求携带cookie进行验证。

  • 请求携带jwt进行验证(后期讲)。

  • 请求携带的加密的数据,需用特定算法解密(一般为app开发的接口都是有加密算法)

  • ...

此时,就可以编写多个认证类,并按照需要应用在相应的视图中,例如:

注意:此示例后续在视图中读取的 request.user 的值为None时,表示未认证成功;不为None时,则表示认证成功。

就是一个authentication_classes = [TokenAuthentication, cookiexxxxxxxx,]里面有两个认证类,如果第一个返回None的话,可以丢给后面的一个继续认证,但是最后一个认证类必须要有返回值。

全局配置

在每个视图类的类变量 authentication_classes 中可以定义,其实在配置文件中也可以进行全局配置,例如:

REST_FRAMEWORK = {
    "UNAUTHENTICATED_USER": lambda: None,
    "UNAUTHENTICATED_TOKEN": lambda: None,
    "DEFAULT_AUTHENTICATION_CLASSES":["authentication_classes ","xxxx.xxxx.xx.类名","xxxx.xxxx.xx.类名",]
}

这个全局配置跟我们之前的版本是一样的。那么在视图类前面可以不用加了,如果不想给其它加上的话可以这样子:

给个空列表。或者是不想用全局的,可以重新指定或者覆盖原先的。

5. 权限

认证,根据用户携带的 token/其他 获取当前用户信息。

权限,读取认证中获取的用户信息,判断当前用户是否有权限访问,例如:普通用户、管理员、超级用户,不同用户具有不同的权限。

class UserInfo(models.Model):
    
    role_choices = ((1, "普通用户"), (2, "管理员"), (3, "超级管理员"),)
    role = models.IntegerField(verbose_name="角色", choices=role_choices, default=1)
    
    username = models.CharField(verbose_name="用户名", max_length=32)
    password = models.CharField(verbose_name="密码", max_length=64)
    token = models.CharField(verbose_name="TOKEN", max_length=64, null=True, blank=True)
import uuid
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission
from rest_framework.exceptions import AuthenticationFailed

from app01 import models


class AuthView(APIView):
    """ 用户登录认证 """
    authentication_classes = []
    permission_classes = []

    def post(self, request, *args, **kwargs):
        print(request.data)  # {"username": "wupeiqi", "password": "123"}
        username = request.data.get('username')
        password = request.data.get('password')

        user_object = models.UserInfo.objects.filter(username=username, password=password).first()
        if not user_object:
            return Response({"code": 1000, "data": "用户名或密码错误"})

        token = str(uuid.uuid4())

        user_object.token = token
        user_object.save()

        return Response({"code": 0, "data": {"token": token, "name": username}})


class TokenAuthentication(BaseAuthentication):
    def authenticate(self, request):
        token = request.query_params.get("token")
        if not token:
            raise AuthenticationFailed({"code": 1002, "data": "认证失败"})
        user_object = models.UserInfo.objects.filter(token=token).first()
        if not user_object:
            raise AuthenticationFailed({"code": 1002, "data": "认证失败"})
        return user_object, token

    def authenticate_header(self, request):
        return 'Bearer realm="API"'


class PermissionA(BasePermission):
    message = {"code": 1003, 'data': "无权访问"}

    def has_permission(self, request, view):
        if request.user.role == 2:
            return True
        return False
	
    # 暂时先这么写
    def has_object_permission(self, request, view, obj):
        return True


class OrderView(APIView):
    authentication_classes = [TokenAuthentication, ]

    permission_classes = [PermissionA,]

    def get(self, request, *args, **kwargs):
        print(request.user)
        return Response({"code": 0, "data": {"user": None, 'list': [1, 2, 3]}})


class PayView(APIView):
    authentication_classes = [TokenAuthentication, ]
    permission_classes = [PermissionA, ]

    def get(self, request, *args, **kwargs):
        print(request.user)
        return Response({"code": 0, "data": "数据..."})

上述PermissionA为权限类,继承BasePermission,

有两个方法has_permission和has_object_permission是固定的。

那么该怎么和视图类绑定权限类呢?

通过该permission_classes = [PermissionA,]来绑定

到达这个视图类,首先进行认证类,认证成功后再执行权限类成功后,才能执行get......

class PermissionA(BasePermission):
    message = {"code": 1003, 'data': "无权访问"}

    def has_permission(self, request, view):
        if request.user.role == 2:
            return True
        return False
	
    # 暂时先这么写
    def has_object_permission(self, request, view, obj):
        return True

上面的message,如果返回False的话,就会返回message信息,下面的has_object_permission后面再讲。

关于多个权限类

当开发过程中需要用户同时具备多个权限(缺一不可)时,可以用多个权限类来实现。

权限组件内部处理机制:按照列表的顺序逐一执行 has_permission 方法,如果返回True,则继续执行后续的权限类;如果返回None或False,则抛出权限异常并停止后续权限类的执行。

也就是说,小红这个用户不仅要通过普通用户这个权限认证还要通过管理员这个权限认证。

一身兼多职位。

# models.py

from django.db import models


class Role(models.Model):
    """ 角色表 """
    title = models.CharField(verbose_name="名称", max_length=32)


class UserInfo(models.Model):
    """ 用户表 """
    username = models.CharField(verbose_name="用户名", max_length=32)
    password = models.CharField(verbose_name="密码", max_length=64)
    token = models.CharField(verbose_name="TOKEN", max_length=64, null=True, blank=True)

    roles = models.ManyToManyField(verbose_name="角色", to="Role")

# urls.py

from django.urls import path, re_path, include
from app01 import views

urlpatterns = [
    path('api/auth/', views.AuthView.as_view()),
    path('api/order/', views.OrderView.as_view()),
]

# views.py

import uuid
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission
from rest_framework.exceptions import AuthenticationFailed

from app01 import models


class AuthView(APIView):
    """ 用户登录认证 """

    def post(self, request, *args, **kwargs):
        print(request.data)  # {"username": "wupeiqi", "password": "123"}
        username = request.data.get('username')
        password = request.data.get('password')

        user_object = models.UserInfo.objects.filter(username=username, password=password).first()
        if not user_object:
            return Response({"code": 1000, "data": "用户名或密码错误"})

        token = str(uuid.uuid4())

        user_object.token = token
        user_object.save()

        return Response({"code": 0, "data": {"token": token, "name": username}})


class TokenAuthentication(BaseAuthentication):
    def authenticate(self, request):
        token = request.query_params.get("token")
        if not token:
            raise AuthenticationFailed({"code": 1002, "data": "认证失败"})
        user_object = models.UserInfo.objects.filter(token=token).first()
        if not user_object:
            raise AuthenticationFailed({"code": 1002, "data": "认证失败"})
        return user_object, token

    def authenticate_header(self, request):
        return 'Bearer realm="API"'


class PermissionA(BasePermission):
    message = {"code": 1003, 'data': "无权访问"}

    def has_permission(self, request, view):
        exists = request.user.roles.filter(title="员工").exists()
        if exists:
            return True
        return False

    def has_object_permission(self, request, view, obj):
        return True


class PermissionB(BasePermission):
    message = {"code": 1003, 'data': "无权访问"}

    def has_permission(self, request, view):
        exists = request.user.roles.filter(title="主管").exists()
        if exists:
            return True
        return False

    def has_object_permission(self, request, view, obj):
        return True

class OrderView(APIView):
    authentication_classes = [TokenAuthentication, ]
    permission_classes = [PermissionA, PermissionA]

    def get(self, request, *args, **kwargs):
        return Response({"code": 0, "data": {"user": None, 'list': [1, 2, 3]}})


class PayView(APIView):
    authentication_classes = [TokenAuthentication, ]
    permission_classes = [PermissionA, ]

    def get(self, request, *args, **kwargs):
        return Response({"code": 0, "data": "数据..."})

关于 has_object_permission【欠】

当我们使用drf来编写 视图类时,如果是继承 APIView,则 has_object_permission不会被执行(没用),例如:

from rest_framework.views import APIView

class PayView(APIView):
    authentication_classes = [TokenAuthentication, ]
    permission_classes = [PermissionA, ]

    def get(self, request, *args, **kwargs):
        return Response({"code": 0, "data": "数据..."})

但是,当我们后期学习了 视图类的各种骚操作之后,发现视图也可以继承 GenericAPIView,此时 有可能 会执行 has_object_permission 用于判断是否有权限访问某个特定ID的对象(学完视图后,再细讲)。

调用 self.get_object 方法时,会按照 permission_classes中权限组件的顺序,依次执行他们的 has_object_permission 方法。

self.get_object其实就根据用户传入的 pk,搜索并获取某个对象的过程。

全局配置

REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES":["xxxx.xxxx.xx.类名","xxxx.xxxx.xx.类名",]
}

小结

  • 请求的封装

  • 版本的处理

    • 过程:选择版本处理类,获取用户传入的版本信息

    • 结果:在 request.version = 版本request.versioning_scheme=版本处理类的对象

  • 认证组件,在视图执行之前判断用户是否认证成功。

    • 过程:执行所有的认证类中的 authenticate 方法

      • 返回None,继续执行后续的认证类(都未认证成功,request.user 和 auth有默认值,也可以全局配置)

      • 返回2个元素的元组,中断

      • 抛出 AuthenticationFailed,中断

    • 结果:在 request.userrequest.auth 赋值(后续代码可以使用)

  • 权限

    • 过程:执行所有的权限类的has_permission方法,只有所有都返回True时,才表示具有权限

    • 结果:有权限则可以执行后续的视图,无权限则直接返回 自定义的错误信息

标签:self,request,django,token,restframework,user,import,data,drf
From: https://blog.csdn.net/2301_80678122/article/details/145077812

相关文章

  • drf:django restframework(二)
    限流限流,限制用户访问频率,例如:用户1分钟最多访问100次或者短信验证码一天每天可以发送50次,防止盗刷。对于匿名用户,使用用户IP作为唯一标识。对于登录用户,使用用户ID或名称作为唯一标识。原理:    内部处理机制是,最后的一个时间和前面的用户标识时间做比较,就如下......
  • django民宿预定管理系统-毕业设计源码60197
    目录摘要1绪论1.1选题背景与意义1.2国内外研究现状1.3论文结构与章节安排2系统分析2.1可行性分析2.1.1经济可行性分析2.1.2技术可行性分析2.1.3操作可行性分析2.2系统流程分析2.2.1系统开发流程2.2.2用户登录流程2.2.3系统操作流程2.2.4......
  • Python+Django的框架药品购买系统(Pycharm Flask Django Vue mysql)
    收藏关注不迷路,防止下次找不到!文章末尾有惊喜项目介绍Python+Django的框架药品购买系统(PycharmFlaskDjangoVuemysql)项目展示详细视频演示请联系我获取更详细的演示视频,相识就是缘分,欢迎合作!!!所用技术栈前端vue.js框架支持:django数据库:mysql......
  • Python+Django的智能宾馆预定系统(Pycharm Flask Django Vue mysql)
    收藏关注不迷路,防止下次找不到!文章末尾有惊喜项目介绍Python+Django的智能宾馆预定系统(PycharmFlaskDjangoVuemysql)项目展示详细视频演示请联系我获取更详细的演示视频,相识就是缘分,欢迎合作!!!所用技术栈前端vue.js框架支持:django数据库:mysql5.7数......
  • python+django/flask的大学生心理咨询平台java+nodejs+php-计算机毕业设计
    目录技术介绍具体实现截图微信开发者工具HBuilderXuniapp系统设计java类核心代码部分展示登录的业务流程的顺序是:可行性论证详细视频演示技术可行性系统测试系统安全性数据完整性实现思路系统实现源码获取技术介绍如今微信小程序有以下发展优势(1)无须下载,无须注......
  • python+django/flask的影视观享系统(影视评论与评分系统)java+nodejs+php-计算机毕业设
    目录技术栈和环境说明具体实现截图预期达到的目标系统设计详细视频演示技术路线解决的思路性能/安全/负载方面可行性分析论证python-flask核心代码部分展示python-django核心代码部分展示研究方法感恩大学老师和同学源码获取技术栈和环境说明本系统以Python开发语言......
  • python+django/flask的OA管理系统java+nodejs+php-计算机毕业设计
    目录技术栈和环境说明具体实现截图预期达到的目标系统设计详细视频演示技术路线解决的思路性能/安全/负载方面可行性分析论证python-flask核心代码部分展示python-django核心代码部分展示研究方法感恩大学老师和同学源码获取技术栈和环境说明本系统以Python开发语言......
  • 基于Python+Django的校园爱心帮扶平台
    作者简介:Java领域优质创作者、CSDN博客专家、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验,被多个学校常年聘为校外企业导师,指导学生毕业设计并参与学生毕业答辩指导,有较为丰富的相关经验。期待与各位高校教师、企......
  • Django 网页开发快速上手——实现一个博客应用
    目录0前言博客定位成果展示环境配置1创建project2创建app3Django三大元素——MVT4创建你的第一个view5创建你的第一个template6migration与admin端7创建你的第一个model8连通view,template和model9实现注册/登录/登出功能10模版继承11用css文件美化页......
  • Django Admin 自定义操作封装
    1.为什么需要封装?在Django开发中,我们经常需要在Admin界面添加自定义操作按钮,以便管理员执行特定的任务。通过封装,我们可以:减少重复代码统一管理自定义操作的逻辑提高代码的可维护性和可扩展性©ivwdcwso(ID:u012172506)2.CustomActionMixin的实现让我们看看C......