【django】django RESTFramework前后端分离框架快速入门

目录

一、搭建项目开发环境

1.1 pycharm创建项目

1.2 修改配置settings.py 

1.3 新增 static与staticfiles文件夹

1.4 生成数据表

1.5 创建超级用户

1.6 启动项目

 二、安装REST_Framework

2.1 安装

2.2 配置settings

2.3 重新执行生成数据库脚本

三、修改路由

 四、studyApp应用开发

4.1 修改apps.py

 4.2 创建models.py

4.3 修改admin.py

4.4 生成数据表

4.5 添加库表数据

五、使用ModelSerializer序列化 模型类

5.1 创建serializers文件

5.2 序列化models表中的Course

5.3 带URL的HyperlinkedModelSerializer(非必须)

 六、DRF视图开发RESful API接口

6.1 使用django原生编写API接口(可跳过,不推荐)

6.1.1 django函数式编程Function Based View(不推荐)

6.1.2 django原生类视图Class Based View(不推荐)

6.2 DRF函数式编程Function Based View

6.2.1 编码代码-----》(查询列表+新增)

6.2.2 添加路由

 6.2.3 访问验证

6.2.4 测试新增

6.2.5 查询列表

 6.2.6 编写代码 ----》(修改、删除,查询单个)

6.2.7  添加路由

6.2.8 查询单个

6.2.9 修改单个

6.2.10 删除单个 

6.3 DRF类视图Class Based View

6.3.1 代码

 6.3.2 更新url

6.3.3 测试

6.4 通用类视图Generic Classed Based View

6.4.1 代码

6.3.2 添加路由

6.3.3 测试

6.5 DRF的视图集viewsets

6.5.1 代码

6.5.2 路由urls---》 这个写法与之前路由不一样

6.5.3 测试

 七、DRF的认证(了解即可)

7.1 BasicAuthenrication用户名密码认证

7.2 SessionAuthenrication认证

7.3 TokenAuthenrication认证

7.3.1 使用django manage.py 生成token(测试使用)

7.3.2 通过django的信号机制生成token

7.3.2.1 在视图写函数实现

7.3.2.2 项目urls配置路由

7.3.2.3 后台创建一个用户

 7.3.2.4 调用接口生成token

 7.3.2.5 其他接口使用token

 7.3.2.6 每个方法设置不同认证

八、DRF的权限

8.1 常用的权限类

8.2 设置权限策略

8.3 如何自定义对象级别权限

8.3.1 新建permissons.py文件

8.3.2 导入到视图views.py应用

8.3.3 测试

九、如何使用drf的接口文档 

9.1 如何生成接口文档

9.1.1 安装库

9.1.2 settings配置

 9.1.3 urls配置

9.1.4 访问

9.2 接口文档的使用方法

9.2.1 修改settings

9.2.2 修改urls

 9.2.3 访问

9.2.4 使用


前言:django RESTFramework基础学习整理

一、搭建项目开发环境

1.1 pycharm创建项目

1.2 修改配置settings.py 

ALLOWED_HOSTS = ['*']

.
.
.

# LANGUAGE_CODE = 'en-us'
# TIME_ZONE = 'UTC'
# USE_TZ = True
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False
USE_I18N = True
.
.
.
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'staticfiles')]

1.3 新增 static与staticfiles文件夹

1.4 生成数据表

这里使用默认的数据库 

python manage.py makemigrations

python manage.py migrate


1.5 创建超级用户

# 创建超级用户
python manage.py createsuperuser

1、输入邮箱,随便
2、输入密码
3、再次数据密码 
4、 如果密码太简单会提示, 忽略就点Y

1.6 启动项目

python manage.py runserver

http://127.0.0.1:8000/admin/
输入刚才设置的用户  root  123456,能登录成功就说明用户创建成功

 二、安装REST_Framework

2.1 安装


pip install djangorestframework

pip install coreapi # 第九章使用

pip install pyyaml   # 第九章使用

2.2 配置settings

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'studyApp.apps.StudyappConfig',
    'rest_framework', #rest-framework API
    'rest_framework.authtoken' # DRF 自带的token认证
]
.
.
.


#DRF的全局配置
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10,
    'DATETIME_FORMAT': '%Y-%m-%d %H:%M:%S',
    'DEFAULT_RENDER_CLASSES': [# 渲染response ,可以不写
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renders.BrowsableAPIRender',
    ],
    'DEFAULT_PARSER_CLASSES': [  # 解析request.data
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
        'rest_framework.parsers.MultiPartParser',
    ],
    'DEFAULT_PERMISSION_CLASSES': [  # 权限
        'rest_framework.permissions.IsAuthenticatedOrReadOnly',
    ],
    'DERAULT_AUTHENTICATION_CLASSES': [  # 认证
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ]
}

2.3 重新执行生成数据库脚本

python manage.py makemigrations

python manage.py migrate

三、修改路由


from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('studyApp/',include('studyApp.urls')),
    path('api-auth/', include('rest_framework.urls')), # DRF登录退出接口,可点击进去看看
]
登录
http://127.0.0.1:8000/api-auth/login/

 四、studyApp应用开发

4.1 修改apps.py

from django.apps import AppConfig


class StudyappConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'studyApp'
    verbose_name = '学习APP'

 4.2 创建models.py

from django.db import models
from django.conf import settings



class Course(models.Model):
    name = models.CharField(max_length=255, unique=True, help_text='课程名称', verbose_name='课程名称')
    introduction = models.TextField(help_text='课程介绍', verbose_name='课程介绍')
    teacher = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
                                help_text='课程讲师', verbose_name='课程讲师')
    price = models.DecimalField(max_digits=6,decimal_places=2, help_text='价格', verbose_name='价格')
    created_at = models.DateTimeField(auto_now_add=True, help_text='创建时间', verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, help_text='更新时间', verbose_name='更新时间')

    class Meta:
        verbose_name = '课程信息',
        verbose_name_plural = verbose_name
        ordering = ['price',]
    def __str__(self):
        return self.name

4.3 修改admin.py

将model.py创建的Course字段添加到后台系统,方面后期添加数据

from django.contrib import admin
from .models import Course

# Register your models here.
@admin.register(Course)
class CourseAdmin(admin.ModelAdmin):
    list_display = ('name', 'introduction','teacher','price')
    serch_fields = list_display
    list_filter = list_display

4.4 生成数据表

python manage.py makemigrations

python manage.py migrate


4.5 添加库表数据

http://127.0.0.1:8000/admin

五、使用ModelSerializer序列化 模型类

5.1 创建serializers文件

5.2 序列化models表中的Course

注意:teacher是外键,复用了django的用户表,外键序列化还可以使用遍历深度

在Meta当中设置depth=1 , 数字越大,深度越大,

# -*- coding: utf-8 -*-
# @Time    : 2024/11/1 9:30
# @Author  : super
# @File    : serializers.py
# @Software: PyCharm
# @Describe:
from rest_framework import serializers
from .models import Course
from django.contrib.auth.models import User  # 导入用户模型


"""
    用户序列化器
"""
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'


class CourseSerializer(serializers.ModelSerializer):
    teacher = serializers.ReadOnlyField(source='teacher.username')  # 外键显示名称
    
    class Meta:
        model = Course
        fields = '__all__'
        # fields = ('id', 'name', 'teacher', 'price', 'introduction', 'created_at', 'updated_at')

5.3 带URL的HyperlinkedModelSerializer(非必须)

这里是讲解,后面例子没有使用到,可注解掉

# -*- coding: utf-8 -*-
# @Time    : 2024/11/1 9:30
# @Author  : super
# @File    : serializers.py
# @Software: PyCharm
# @Describe:
from rest_framework import serializers
from .models import Course
from django.contrib.auth.models import User  # 导入用户模型


"""
    用户序列化器
"""
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'



class CourseSerializer(serializers.HyperlinkedModelSerializer):
    teacher = serializers.ReadOnlyField(source='teacher.username')  # 外键显示名称

    class Meta:
        model = Course       
        # url 是默认值,可在settings.py设置URL_FIELD_NAME使全局生效
        fields = ('id', 'url', 'teacher', 'price', 'introduction', 'created_at', 'updated_at')

如果要更url,这样设置,(不建议)

 六、DRF视图开发RESful API接口

6.1 使用django原生编写API接口(可跳过,不推荐)

6.1.1 django函数式编程Function Based View(不推荐)

使用django原生的函数式编写api接口

from django.shortcuts import render
import json
from django.http import JsonResponse, HttpResponse
from django.views.decorators.csrf import csrf_exempt   # 用于免除csrf验证
# Create your views here.
coures_dict = {  
    "name": "python",  
    "introduction": "python基础入门",  
    "price": 100  
}


@csrf_exempt
def course_list(request):
    '''
    django原生的fbv式编写API接口
    :param request:
    :return:
    '''
    if request.method == 'Get':
        return JsonResponse(coures_dict)
        # return HttpResponse(json.dumps(coures_dict), content_type='application/json')  # 这个与上面JsonResponse作用一样
    
    if request.method == 'POST':
        course_data = json.loads(request.body.decode('utf-8'))
        # return JsonResponse(course_data, safe=False) # 这个与下面的JsonResponse作用一样
        return HttpResponse(json.dumps(course_data), content_type='application/json')

6.1.2 django原生类视图Class Based View(不推荐)

使用django原生的类编写api接口

import json
from django.http import JsonResponse, HttpResponse
from django.views.decorators.csrf import csrf_exempt   # 用于免除csrf验证
from django.utils.decorators import method_decorator  # 用于方法免除csrf验证
from django.views import View

@method_decorator(csrf_exempt, name='dispatch')
class CourseView(View):
    '''
    django原生的cbv式编写API接口
    '''
    def get(self, request):
        return JsonResponse(coures_dict)

    def post(self, request):
        course_data = json.loads(request.body.decode('utf-8'))
        return JsonResponse(course_data, safe=False)

6.2 DRF函数式编程Function Based View

6.2.1 编码代码-----》(查询列表+新增)

from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .models import Course
from .serializers import CourseSerializer


"""
 一、 函数式编程 FBV
"""
@api_view(['GET', 'POST'])
def coures_list(request):
    '''
    获取课程列表或新增一个课程
    :param request:
    :return:
    '''
    if request.method == 'GET':
        courses = CourseSerializer(instance=Course.objects.all(), many=True)
        return Response(data=courses.data,status=status.HTTP_200_OK)
    elif request.method == 'POST':
        serializer = CourseSerializer(data=request.data) # partial=True 只验证部分字段,适用于非必填字段
        if serializer.is_valid():
            serializer.save(teacher=request.user) # teacher 字段为外键,获取登录用户id,因为复用了django的用户模型,有认证功能
            return Response(data=serializer.data, status=status.HTTP_201_CREATED)
        return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)

6.2.2 添加路由

在应用新增urls文件,输入内容

# -*- coding: utf-8 -*-
# @Time    : 2024/11/1 10:27
# @Author  : super
# @File    : urls.py
# @Software: PyCharm
# @Describe:
from django.urls import path,include
from studyApp import views

urlpatterns = [
 path('fbv/list/', views.coures_list, name='fbv-list'), # 函数视图FBV

]

 6.2.3 访问验证

http://127.0.0.1:8000/studyApp/fbv/list/

因为这里设置了全局的身份认证,需要登录

6.2.4 测试新增

json

{
	"name": "python",
	"introduction": "python基础入门",
	"price": 100
}

6.2.5 查询列表

 

 6.2.6 编写代码 ----》(修改、删除,查询单个)

from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .models import Course
from .serializers import CourseSerializer


"""
 一、 函数式编程 FBV
"""
@api_view(['GET', 'POST'])
def coures_list(request):
    '''
    获取课程列表或新增一个课程
    :param request:
    :return:
    '''
    if request.method == 'GET':
        courses = CourseSerializer(instance=Course.objects.all(), many=True)
        return Response(data=courses.data,status=status.HTTP_200_OK)
    elif request.method == 'POST':
        serializer = CourseSerializer(data=request.data) # partial=True 只验证部分字段,适用于非必填字段
        if serializer.is_valid():
            serializer.save(teacher=request.user) # teacher 字段为外键,获取登录用户id,因为复用了django的用户模型,有认证功能
            return Response(data=serializer.data, status=status.HTTP_201_CREATED)
        return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
def course_detail(request, pk):
    '''
    获取单个课程详情,更新或删除一个课程
    :param request:
    :param pk:
    :return:
    '''''
    try:
        course = Course.objects.get(pk=pk)
    except Course.DoesNotExist:
        return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
    if request.method == 'GET':
        serializer = CourseSerializer(course)
        return Response(data=serializer.data, status=status.HTTP_200_OK)
    elif request.method == 'PUT':
        serializer = CourseSerializer(instance=course, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    elif request.method == 'DELETE':
        course.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
    else:
        return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)

6.2.7  添加路由

from django.urls import path,include
from studyApp import views

urlpatterns = [
 path('fbv/list/', views.coures_list, name='fbv-list'), # 函数视图FBV
 path('fbv/detail/<int:pk>/', views.course_detail, name='fbv-detail'),

]

6.2.8 查询单个

http://127.0.0.1:8000/studyApp/fbv/detail/2/

6.2.9 修改单个

请求体

{
	"name": "菠菜的野蛮生长",
	"introduction": "编码人生",
	"price": 100
}

 

6.2.10 删除单个 

知识点:使用postman测试的话注意这个地方

另外一种设置方式:

 继承

  

6.3 DRF类视图Class Based View

6.3.1 代码

from django.shortcuts import render
from rest_framework.decorators import api_view  # fbv
from rest_framework.views import APIView  #cbv
from rest_framework.response import Response
from rest_framework import status
from .models import Course
from .serializers import CourseSerializer


"""
 一、 函数式编程 FBV
"""
@api_view(['GET', 'POST'])
def coures_list(request):
    '''
    获取课程列表或新增一个课程
    :param request:
    :return:
    '''
    if request.method == 'GET':
        courses = CourseSerializer(instance=Course.objects.all(), many=True)
        return Response(data=courses.data,status=status.HTTP_200_OK)
    elif request.method == 'POST':
        serializer = CourseSerializer(data=request.data) # partial=True 只验证部分字段,适用于非必填字段
        if serializer.is_valid():
            serializer.save(teacher=request.user) # teacher 字段为外键,获取登录用户id,因为复用了django的用户模型,有认证功能
            return Response(data=serializer.data, status=status.HTTP_201_CREATED)
        return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
def course_detail(request, pk):
    '''
    获取单个课程详情,更新或删除一个课程
    :param request:
    :param pk:
    :return:
    '''''
    try:
        course = Course.objects.get(pk=pk)
    except Course.DoesNotExist:
        return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
    if request.method == 'GET':
        serializer = CourseSerializer(course)
        return Response(data=serializer.data, status=status.HTTP_200_OK)
    elif request.method == 'PUT':
        serializer = CourseSerializer(instance=course, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    elif request.method == 'DELETE':
        course.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
    else:
        return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)

"""
 二、 函数式编程 CBV
"""
class CourseList(APIView):
    """
    获取课程列表或新增一个课程
    """
    def get(self, request):
        queryset = Course.objects.all()
        serializer = CourseSerializer(instance=queryset, many=True)
        return Response(data=serializer.data, status=status.HTTP_200_OK)

    def post(self, request):
        serializer = CourseSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(teacher=self.request.user)
            return Response(data=serializer.data, status=status.HTTP_201_CREATED)
        return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class CourseDetail(APIView):
    """
    获取单个课程详情,更新或删除一个课程
    """

    @staticmethod
    def get_object(pk):
        '''
        获取课程对象
        :param self:
        :param pk:
        :return:
        '''
        try:
            return Course.objects.get(pk=pk)
        except Course.DoesNotExist:
            return


    def get(self, request, pk):
        obj = self.get_object(pk=pk)
        if obj is None:
            return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = CourseSerializer(obj)
        return Response(data=serializer.data, status=status.HTTP_200_OK)
    def put(self, request, pk):
        '''
        更新课程
        :param request:
        :param pk:
        :return:
        '''
        obj = self.get_object(pk=pk)
        if obj is None:
            return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = CourseSerializer(instance=obj, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    def delete(self, request, pk):
        '''
        删除课程
        :param request:
        :param pk:
        :return:
        '''
        obj = self.get_object(pk=pk)
        if obj is None:
            return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
        obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

 6.3.2 更新url

# -*- coding: utf-8 -*-
# @Time    : 2024/11/1 10:27
# @Author  : super
# @File    : urls.py
# @Software: PyCharm
# @Describe:
from django.urls import path,include
from studyApp import views

urlpatterns = [
 path('fbv/list/', views.coures_list, name='fbv-list'), # 函数视图FBV
 path('fbv/detail/<int:pk>/', views.course_detail, name='fbv-detail'), # 函数视图FBV
 path('cbv/list/', views.CourseList.as_view(), name='cbv-list'), # 类视图CBV
 path('cbv/detail/<int:pk>/', views.CourseDetail.as_view(), name='cbv-detail'), # 类视图CBV

]

6.3.3 测试

查询全部

新增 

修改

删除

6.4 通用类视图Generic Classed Based View

6.4.1 代码

如果没有那个teacher ,那个方法重写可以不需要

from django.shortcuts import render
from rest_framework.decorators import api_view  # fbv
from rest_framework.views import APIView  #cbv
from rest_framework import generics # gcb通用视图类
from rest_framework.response import Response
from rest_framework import status
from .models import Course
from .serializers import CourseSerializer


"""
 一、 函数式编程 FBV
"""
@api_view(['GET', 'POST'])
def coures_list(request):
    '''
    获取课程列表或新增一个课程
    :param request:
    :return:
    '''
    if request.method == 'GET':
        courses = CourseSerializer(instance=Course.objects.all(), many=True)
        return Response(data=courses.data,status=status.HTTP_200_OK)
    elif request.method == 'POST':
        serializer = CourseSerializer(data=request.data) # partial=True 只验证部分字段,适用于非必填字段
        if serializer.is_valid():
            serializer.save(teacher=request.user) # teacher 字段为外键,获取登录用户id,因为复用了django的用户模型,有认证功能
            return Response(data=serializer.data, status=status.HTTP_201_CREATED)
        return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
def course_detail(request, pk):
    '''
    获取单个课程详情,更新或删除一个课程
    :param request:
    :param pk:
    :return:
    '''''
    try:
        course = Course.objects.get(pk=pk)
    except Course.DoesNotExist:
        return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
    if request.method == 'GET':
        serializer = CourseSerializer(course)
        return Response(data=serializer.data, status=status.HTTP_200_OK)
    elif request.method == 'PUT':
        serializer = CourseSerializer(instance=course, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    elif request.method == 'DELETE':
        course.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
    else:
        return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)

"""
 二、 函数式编程 CBV
"""
class CourseList(APIView):
    """
    获取课程列表或新增一个课程
    """
    def get(self, request):
        queryset = Course.objects.all()
        serializer = CourseSerializer(instance=queryset, many=True)
        return Response(data=serializer.data, status=status.HTTP_200_OK)

    def post(self, request):
        serializer = CourseSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(teacher=self.request.user)
            return Response(data=serializer.data, status=status.HTTP_201_CREATED)
        return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class CourseDetail(APIView):
    """
    获取单个课程详情,更新或删除一个课程
    """

    @staticmethod
    def get_object(pk):
        '''
        获取课程对象
        :param self:
        :param pk:
        :return:
        '''
        try:
            return Course.objects.get(pk=pk)
        except Course.DoesNotExist:
            return


    def get(self, request, pk):
        obj = self.get_object(pk=pk)
        if obj is None:
            return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = CourseSerializer(obj)
        return Response(data=serializer.data, status=status.HTTP_200_OK)
    def put(self, request, pk):
        '''
        更新课程
        :param request:
        :param pk:
        :return:
        '''
        obj = self.get_object(pk=pk)
        if obj is None:
            return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = CourseSerializer(instance=obj, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    def delete(self, request, pk):
        '''
        删除课程
        :param request:
        :param pk:
        :return:
        '''
        obj = self.get_object(pk=pk)
        if obj is None:
            return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
        obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


'''
 三、 通用视图类
'''

class CourseGenericAPIView(generics.ListCreateAPIView):
    '''
    获取课程列表或新增一个课程
    '''
    queryset = Course.objects.all()
    serializer_class = CourseSerializer

    def perform_create(self, serializer):   # 重写perform_create方法,在保存之前添加teacher字段
        serializer.save(teacher=self.request.user)
        

class CourseGenericDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
    '''
    获取单个课程详情,更新或删除一个课程
    '''
    queryset = Course.objects.all()
    serializer_class = CourseSerializer

6.3.2 添加路由

# -*- coding: utf-8 -*-
# @Time    : 2024/11/1 10:27
# @Author  : super
# @File    : urls.py
# @Software: PyCharm
# @Describe:
from django.urls import path,include
from studyApp import views

urlpatterns = [
 path('fbv/list/', views.coures_list, name='fbv-list'), # 函数视图FBV
 path('fbv/detail/<int:pk>/', views.course_detail, name='fbv-detail'), # 函数视图FBV
 path('cbv/list/', views.CourseList.as_view(), name='cbv-list'), # 类视图CBV
 path('cbv/detail/<int:pk>/', views.CourseDetail.as_view(), name='cbv-detail'), # 类视图CBV
 path('gcbv/list/', views.CourseGenericAPIView.as_view(),name='gcbv-list'), # 通用视图类gcbv
 path('gcbv/detail/<int:pk>/', views.CourseGenericDetailAPIView.as_view(), name='gcbv-detail'),# 通用视图类gcbv


]

6.3.3 测试

查询列表

新增

查询单个

修改

删除

6.5 DRF的视图集viewsets

6.5.1 代码

from django.shortcuts import render
from rest_framework.decorators import api_view  # fbv
from rest_framework.views import APIView  #cbv
from rest_framework import generics # gcbv通用视图类
from rest_framework import viewsets # 视图集
from rest_framework.response import Response
from rest_framework import status
from .models import Course
from .serializers import CourseSerializer


"""
 一、 函数式编程 FBV
"""
@api_view(['GET', 'POST'])
def coures_list(request):
    '''
    获取课程列表或新增一个课程
    :param request:
    :return:
    '''
    if request.method == 'GET':
        courses = CourseSerializer(instance=Course.objects.all(), many=True)
        return Response(data=courses.data,status=status.HTTP_200_OK)
    elif request.method == 'POST':
        serializer = CourseSerializer(data=request.data) # partial=True 只验证部分字段,适用于非必填字段
        if serializer.is_valid():
            serializer.save(teacher=request.user) # teacher 字段为外键,获取登录用户id,因为复用了django的用户模型,有认证功能
            return Response(data=serializer.data, status=status.HTTP_201_CREATED)
        return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
def course_detail(request, pk):
    '''
    获取单个课程详情,更新或删除一个课程
    :param request:
    :param pk:
    :return:
    '''''
    try:
        course = Course.objects.get(pk=pk)
    except Course.DoesNotExist:
        return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
    if request.method == 'GET':
        serializer = CourseSerializer(course)
        return Response(data=serializer.data, status=status.HTTP_200_OK)
    elif request.method == 'PUT':
        serializer = CourseSerializer(instance=course, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    elif request.method == 'DELETE':
        course.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
    else:
        return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)

"""
 二、 函数式编程 CBV
"""
class CourseList(APIView):
    """
    获取课程列表或新增一个课程
    """
    def get(self, request):
        queryset = Course.objects.all()
        serializer = CourseSerializer(instance=queryset, many=True)
        return Response(data=serializer.data, status=status.HTTP_200_OK)

    def post(self, request):
        serializer = CourseSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(teacher=self.request.user)
            return Response(data=serializer.data, status=status.HTTP_201_CREATED)
        return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class CourseDetail(APIView):
    """
    获取单个课程详情,更新或删除一个课程
    """

    @staticmethod
    def get_object(pk):
        '''
        获取课程对象
        :param self:
        :param pk:
        :return:
        '''
        try:
            return Course.objects.get(pk=pk)
        except Course.DoesNotExist:
            return


    def get(self, request, pk):
        obj = self.get_object(pk=pk)
        if obj is None:
            return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = CourseSerializer(obj)
        return Response(data=serializer.data, status=status.HTTP_200_OK)
    def put(self, request, pk):
        '''
        更新课程
        :param request:
        :param pk:
        :return:
        '''
        obj = self.get_object(pk=pk)
        if obj is None:
            return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = CourseSerializer(instance=obj, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    def delete(self, request, pk):
        '''
        删除课程
        :param request:
        :param pk:
        :return:
        '''
        obj = self.get_object(pk=pk)
        if obj is None:
            return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
        obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


'''
 三、 通用视图类
'''

class CourseGenericAPIView(generics.ListCreateAPIView):
    '''
    获取课程列表或新增一个课程
    '''
    queryset = Course.objects.all()
    serializer_class = CourseSerializer

    def perform_create(self, serializer):   # 重写perform_create方法,在保存之前添加teacher字段
        serializer.save(teacher=self.request.user)


class CourseGenericDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
    '''
    获取单个课程详情,更新或删除一个课程
    '''
    queryset = Course.objects.all()
    serializer_class = CourseSerializer

'''
 四、 视图集
'''
class CourseViewSet(viewsets.ModelViewSet):
    queryset = Course.objects.all()
    serializer_class = CourseSerializer
    def perform_create(self, serializer):  # 重写perform_create方法,在保存之前添加teacher字段
        serializer.save(teacher=self.request.user)

6.5.2 路由urls---》 这个写法与之前路由不一样

# -*- coding: utf-8 -*-
# @Time    : 2024/11/1 10:27
# @Author  : super
# @File    : urls.py
# @Software: PyCharm
# @Describe:
from django.urls import path,include
from studyApp import views
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(prefix='courseviewsets', viewset=views.CourseViewSet)

urlpatterns = [
 # 函数视图FBV
 path('fbv/list/', views.coures_list, name='fbv-list'), # 函数视图FBV
 path('fbv/detail/<int:pk>/', views.course_detail, name='fbv-detail'), # 函数视图FBV
 # 类视图CBV
 path('cbv/list/', views.CourseList.as_view(), name='cbv-list'), # 类视图CBV
 path('cbv/detail/<int:pk>/', views.CourseDetail.as_view(), name='cbv-detail'), # 类视图CBV
 # 通用视图类gcbv
 path('gcbv/list/', views.CourseGenericAPIView.as_view(),name='gcbv-list'), # 通用视图类gcbv
 path('gcbv/detail/<int:pk>/', views.CourseGenericDetailAPIView.as_view(), name='gcbv-detail'),# 通用视图类gcbv
 # 视图集写法不一样
 path('', include(router.urls)),
]

6.5.3 测试

列表

新增

查询单个

 

修改单个

删除单个 

 七、DRF的认证(了解即可)

前面配置的三种认证,这里了解即可,一般使用jwt,博主其他博文有介绍

7.1 BasicAuthenrication用户名密码认证

这个认证一般用于测试,不要在生产环境使用

7.2 SessionAuthenrication认证

使用的是django默认的后端会话, 

7.3 TokenAuthenrication认证

这个要配置,之前配置了

 之前执行数据同步将对应库表更新到了数据库,双击这个默认数据库

7.3.1 使用django manage.py 生成token(测试使用)

python manage.py drf_create_token root  
# root  是对应用户

在上面的库表可见

7.3.2 通过django的信号机制生成token

7.3.2.1 在视图写函数实现
'''
token 认证
'''
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
from rest_framework.authtoken.models import Token


@receiver(post_save, sender=settings.AUTH_USER_MODEL) # django  信号
def generate_token(sender, instance=None, created=False, **kwargs):
    '''
    创建用户生成token
    :param sender:
    :param instance:
    :param created:
    :param kwargs:
    :return:
    '''
    if created:
        Token.objects.create(user=instance)

7.3.2.2 项目urls配置路由

"""
URL configuration for djangoRESTFramework project.

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/4.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path,include
from rest_framework.authtoken import views 

urlpatterns = [
    path('api-token-auth/', views.obtain_auth_token), # token认证
    path('admin/', admin.site.urls),
    path('studyApp/',include('studyApp.urls')),
    path('api-auth/', include('rest_framework.urls')), # DRF登录退出接口,可点击进去看看
]
7.3.2.3 后台创建一个用户
bocai
bocai@163.com

 7.3.2.4 调用接口生成token

 7.3.2.5 其他接口使用token

 7.3.2.6 每个方法设置不同认证

 方法认证优先级大于全局settings

函数视图添加方法

类视图\通用类、视图集添加方法相同

from django.shortcuts import render
from rest_framework.decorators import api_view, authentication_classes # fbv
from rest_framework.views import APIView  #cbv
from rest_framework import generics # gcbv通用视图类
from rest_framework import viewsets # 视图集
from rest_framework.response import Response
from rest_framework import status
from .models import Course
from .serializers import CourseSerializer
from rest_framework.authentication import BasicAuthentication,SessionAuthentication,TokenAuthentication

'''
token 认证
'''
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
from rest_framework.authtoken.models import Token


@receiver(post_save, sender=settings.AUTH_USER_MODEL) # django  信号
def generate_token(sender, instance=None, created=False, **kwargs):
    '''
    创建用户生成token
    :param sender:
    :param instance:
    :param created:
    :param kwargs:
    :return:
    '''
    if created:
        Token.objects.create(user=instance)


"""
 一、 函数式编程 FBV
"""
@api_view(['GET', 'POST'])
@authentication_classes((BasicAuthentication,TokenAuthentication))
def coures_list(request):
    '''
    获取课程列表或新增一个课程
    :param request:
    :return:
    '''
    if request.method == 'GET':
        courses = CourseSerializer(instance=Course.objects.all(), many=True)
        return Response(data=courses.data,status=status.HTTP_200_OK)
    elif request.method == 'POST':
        serializer = CourseSerializer(data=request.data) # partial=True 只验证部分字段,适用于非必填字段
        if serializer.is_valid():
            serializer.save(teacher=request.user) # teacher 字段为外键,获取登录用户id,因为复用了django的用户模型,有认证功能
            return Response(data=serializer.data, status=status.HTTP_201_CREATED)
        return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
@authentication_classes((BasicAuthentication,TokenAuthentication))
def course_detail(request, pk):
    '''
    获取单个课程详情,更新或删除一个课程
    :param request:
    :param pk:
    :return:
    '''''
    try:
        course = Course.objects.get(pk=pk)
    except Course.DoesNotExist:
        return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
    if request.method == 'GET':
        serializer = CourseSerializer(course)
        return Response(data=serializer.data, status=status.HTTP_200_OK)
    elif request.method == 'PUT':
        serializer = CourseSerializer(instance=course, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    elif request.method == 'DELETE':
        course.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
    else:
        return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)

"""
 二、 函数式编程 CBV
"""
class CourseList(APIView):
    """
    获取课程列表或新增一个课程
    """
    authentication_classes = (BasicAuthentication,SessionAuthentication,TokenAuthentication)
    def get(self, request):
        queryset = Course.objects.all()
        serializer = CourseSerializer(instance=queryset, many=True)
        return Response(data=serializer.data, status=status.HTTP_200_OK)

    def post(self, request):
        serializer = CourseSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(teacher=self.request.user)
            return Response(data=serializer.data, status=status.HTTP_201_CREATED)
        return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class CourseDetail(APIView):
    """
    获取单个课程详情,更新或删除一个课程
    """
    authentication_classes = (BasicAuthentication, SessionAuthentication, TokenAuthentication)
    @staticmethod
    def get_object(pk):
        '''
        获取课程对象
        :param self:
        :param pk:
        :return:
        '''
        try:
            return Course.objects.get(pk=pk)
        except Course.DoesNotExist:
            return


    def get(self, request, pk):
        obj = self.get_object(pk=pk)
        if obj is None:
            return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = CourseSerializer(obj)
        return Response(data=serializer.data, status=status.HTTP_200_OK)
    def put(self, request, pk):
        '''
        更新课程
        :param request:
        :param pk:
        :return:
        '''
        obj = self.get_object(pk=pk)
        if obj is None:
            return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = CourseSerializer(instance=obj, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    def delete(self, request, pk):
        '''
        删除课程
        :param request:
        :param pk:
        :return:
        '''
        obj = self.get_object(pk=pk)
        if obj is None:
            return Response({'message': 'Course not found'}, status=status.HTTP_404_NOT_FOUND)
        obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


'''
 三、 通用视图类
'''

class CourseGenericAPIView(generics.ListCreateAPIView):
    '''
    获取课程列表或新增一个课程
    '''
    queryset = Course.objects.all()
    serializer_class = CourseSerializer

    def perform_create(self, serializer):   # 重写perform_create方法,在保存之前添加teacher字段
        serializer.save(teacher=self.request.user)


class CourseGenericDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
    '''
    获取单个课程详情,更新或删除一个课程
    '''
    queryset = Course.objects.all()
    serializer_class = CourseSerializer

'''
 四、 视图集
'''
class CourseViewSet(viewsets.ModelViewSet):
    queryset = Course.objects.all()
    serializer_class = CourseSerializer
    def perform_create(self, serializer):  # 重写perform_create方法,在保存之前添加teacher字段
        serializer.save(teacher=self.request.user)

八、DRF的权限

8.1 常用的权限类

8.2 设置权限策略

函数视图添加方法

类视图\通用类、视图集添加方法相同 

8.3 如何自定义对象级别权限

8.3.1 新建permissons.py文件

# -*- coding: utf-8 -*-
# @Time    : 2024/11/1 15:58
# @Author  : super
# @File    : permissions.py
# @Software: PyCharm
# @Describe:
from rest_framework import permissions

class IsOwnerReadOnly(permissions.BasePermission):
    """
    自定义权限只允许对象的所有者编辑它。
    """
    def has_object_permission(self, request, view, obj):
        """
        判断用户是否有权限访问该对象。
        :param request:
        :param view:
        :param obj:
        :return: bool
        """
        if request.method in permissions.SAFE_METHODS:
            return True
        # 判断当前用户是否是该对象的拥有者
        return obj.teacher == request.user

8.3.2 导入到视图views.py应用

这里是修改

8.3.3 测试

这个id=9 是root创建的

 那么bocai无法修改

九、如何使用drf的接口文档 

9.1 如何生成接口文档

9.1.1 安装库

前面安装就可不安装

pip install coreapi
pip install pyyaml

9.1.2 settings配置

'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema',

 9.1.3 urls配置

"""
URL configuration for djangoRESTFramework project.

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/4.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path,include
from rest_framework.authtoken import views
from rest_framework.schemas import get_schema_view
schema_view = get_schema_view(title='DRF API文档',description="API", version="0.1")

urlpatterns = [
    path('api-token-auth/', views.obtain_auth_token), # token认证
    path('admin/', admin.site.urls),
    path('studyApp/',include('studyApp.urls')),
    path('api-auth/', include('rest_framework.urls')), # DRF登录退出接口,可点击进去看看
    path('schema/', schema_view),
]

9.1.4 访问

http://127.0.0.1:8000/schema/

谷歌浏览器

9.2 接口文档的使用方法

9.2.1 修改settings

'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',

9.2.2 修改urls

"""
URL configuration for djangoRESTFramework project.

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/4.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path,include
from rest_framework.authtoken import views
from rest_framework.documentation import include_docs_urls
# from rest_framework.schemas import get_schema_view
# schema_view = get_schema_view(title='DRF API文档',description="API", version="0.1")

urlpatterns = [
    path('api-token-auth/', views.obtain_auth_token), # token认证
    path('admin/', admin.site.urls),
    path('studyApp/',include('studyApp.urls')),
    path('api-auth/', include('rest_framework.urls')), # DRF登录退出接口,可点击进去看看
    # path('schema/', schema_view),
    path('docs/',include_docs_urls(title='DRF API 文档',description='Django REST Framwork 快速入门')),
]

 9.2.3 访问

http://127.0.0.1:8000/docs/

9.2.4 使用

注意:配置认证页面不能刷新

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/905889.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于centos7.9搭建MariaDB10.5高可用集群

MariaDB-HA 环境初始化安装MariaDB配置集群 基于centos7.9搭建MariaDB10.5数据库高可用集群&#xff0c;对标mysql5.7 节点IPnode1192.168.200.101node2192.168.200.102node3192.168.200.103 环境初始化 #!/bin/bash# 定义节点信息 NODES("192.168.200.101 node1"…

WAF+AI结合,雷池社区版的强大防守能力

网上攻击无处不不在&#xff0c;为了保护我自己的网站&#xff0c;搜索安装了一个开源免费的WAF 刚安装完成就收到了海外的攻击&#xff0c;看到是海外的自动化攻击工具做的 雷池刚好也有AI分析&#xff0c;于是就尝试使用这个功能&#xff0c;看看这个ai能力到底怎么样 以下…

服务器宝塔安装哪吒监控

哪吒文档地址&#xff1a;https://nezha.wiki/guide/dashboard.html 一、准备工作 OAuth : 我使用的gitee&#xff0c;github偶尔无法访问&#xff0c;不是很方便。第一次用了极狐GitLab&#xff0c;没注意&#xff0c;结果是使用90天&#xff0c;90天后gg了&#xff0c;无法登…

ThingsBoard规则链节点:Math Function节点详解

引言 1. Math Function 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 数据预处理 3.2 阈值判断 3.3 复杂计算 3.4 动态阈值 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台&#xff0c…

Spark入门到实践

Spark入门到实践 一、Spark 快速入门1.1 Spark 概述1.2 Spark 最简安装1.3 Spark实现WordCount1.3.1 下载安装Scala1.3.2 添加Spark依赖1.3.3 Scala实现WordCount1.3.4 通过IDEA运行WordCount1.3.5 IDEA配置WordCount输入与输出路径1.3.6 通过IDEA运行WordCount1.3.7 查看运行结…

.NET 9 AOT的突破 - 支持老旧Win7与XP环境

引言 随着技术的不断进步&#xff0c;微软的.NET 框架在每次迭代中都带来了令人惊喜的新特性。在.NET 9 版本中&#xff0c;一个特别引人注目的亮点是 AOT&#xff08; Ahead-of-Time&#xff09;支持&#xff0c;它允许开发人员将应用程序在编译阶段就优化为能够在老旧的 Win…

网络层之IP协议,它带来了哪些功能,真的能顺着网线找到?

前言 在上一篇&#xff0c;学习了链路层的以太网协议&#xff0c;知道了MAC地址&#xff0c;在以太网中&#xff0c;找到对应的终端最终依靠的是MAC地址&#xff0c;但是在实际使用中&#xff0c;大家可能发现并不是使用的MAC地址&#xff0c;而是IP协议&#xff0c;比如 &…

linux之网络子系统- 内核发送数据包流程以及相关实际问题

一、相关实际问题 查看内核发送数据消耗的CPU时应该看sy还是si在服务器上查看/proc/softirqs&#xff0c;为什么NET_RX要比NET_TX大得多发送网络数据的时候都涉及那些内存拷贝操作零拷贝到底是怎么回事为什么Kafka的网络性能很突出 二、网络包发送过程总览 调用系统调用send发…

使用WebStorm开发Vue3项目

记录一下使用WebStorm开发Vu3项目时的配置 现在WebStorm可以个人免费使用啦&#xff01;&#x1f929; 基本配置 打包工具&#xff1a;Vite 前端框架&#xff1a;ElementPlus 开发语言&#xff1a;Vue3、TypeScript、Sass 代码检查&#xff1a;ESLint、Prettier IDE&#xf…

操作系统及MySQL管理系统客户端的介绍

操作系统 1、Windows&#xff1a; 图形化管理工具&#xff1a;如控制面板、设置应用、任务管理器等。 客户端&#xff1a;命令提示符&#xff08;cmd&#xff09;和PowerShell用于命令行操作。 2、Linux&#xff1a; 图形化管理工具&#xff1a;如GNOME、KDE等桌面环境中的系…

基于SSM+小程序的旅游社交登录管理系统(旅游4)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 ​ 本旅游社交小程序功能有管理员和用户。管理员有个人中心&#xff0c;用户管理&#xff0c;每日签到管理&#xff0c;景点推荐管理&#xff0c;景点分类管理&#xff0c;防疫查询管理&a…

一文带你了解:六款适合PC端的工时管理工具

1. 板栗看板 板栗看板是一个可视化的事项管理工具&#xff0c;由看板&#xff08;board&#xff09;、列表&#xff08;list&#xff09;、卡片&#xff08;card&#xff09;三个基本元素构成。用户通过在 “看板” 上布置和移动 “列表” 与 “卡片”&#xff0c;可以跟踪事项…

数据结构算法学习方法经验总结

DSA:Data Structures, Algorithms, and Problem-Solving Techniques 三大核心支柱 一次学习一个主题&#xff0c;按照如下顺序学习 如何开始学习新的主题 学习资源 https://www.youtube.com/playlist?listPLDN4rrl48XKpZkf03iYFl-O29szjTrs_O (Algorithms) https://ww…

ANA基因组数据库(ANAgdb)

ANA进化阶由早期发育的被子植物谱系组成&#xff0c;包括无油樟目&#xff08;Amborellales&#xff09;、睡莲目&#xff08;Nymphaeales&#xff09;和木兰藤目&#xff08;Austrobaileyales&#xff09;&#xff0c;在进化上具有重要地位。 ANA基因组数据库&#xff08;ANA…

晟矽微PWM案例分析

/****************************************************************************** ; * 型号 : MC32F7361 ; * 创建日期 : 2021.12.21 ; * 公司/作者 : SINOMCU-FAE ; * 晟矽微技术支持 : 204…

检索引擎Elasticsearch

一.为什么要用Elasticsearch 由于我们在运行我们的项目的时候通常都是将数据存到mysql或者sql serve等数据库中&#xff0c;在进行数据搜索时使用sql 语句 like进行模糊匹配查询&#xff0c;其一&#xff1a;虽然可以查到数据&#xff0c;但是它模糊匹配查询速度较慢&#xff0…

vue前端使用pdfjs与pdfdist-mergeofd 实现预览pdf并翻页,同时解决预览pdf显示模糊的问题

vue前端使用pdfjs与pdfdist-mergeofd 实现预览pdf并翻页&#xff0c;同时解决预览pdf显示模糊的问题 插件介绍 pdfdist-mergeofd插件的作用可查看这篇文章&#xff0c;同时使用ofdjs和pdfjs遇到的问题&#xff0c;和解决方法——懒加载 该插件主要是为了解决pdfjs和ofdjs同时…

深度学习:yolov3的使用--建立模型

使用argparse模块来定义和解析命令行参数 创建一个ArgumentParser对象 parser argparse.ArgumentParser() 训练的轮数&#xff0c;每批图像的大小&#xff0c;更新模型参数之前累积梯度的次数,模型定义文件的路径。 parser.add_argument("--epochs", typeint, d…

38.第二阶段x86游戏实战2-HOOK窗口消息机制(解决多开窗口句柄问题)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…

详解汉明纠错码原理以及FPGA实现

文章目录 一、汉明纠错码简介二、汉明码编码原理以及步骤三、汉明码纠错原理以及步骤四、FPGA实现74汉明编码器五、FPGA实现74汉明解码器 一、汉明纠错码简介 汉明纠错码&#xff08;Hamming Code&#xff09;是一种用于检测和纠正数据传输中错误的编码方法。它由理查德汉明&am…