Django REST framework 源码剖析-视图类详解(Views)

news2025/2/25 5:43:11

Django REST framework视图图解

在这里插入图片描述

  • 视图类(View)

‌视图‌是DRF中处理用户请求的基本单元。它们可以是函数视图(FBV)或类视图(CBV)。函数视图使用函数来处理请求,而类视图则使用类来处理请求。类视图默认会自动dispatch特定的HTTP方法,如GET、POST等,不需要像函数视图那样通过单独的条件判断来处理不同的HTTP方法。此外,类视图可以使用面向对象的技术,如Mixin(多继承、混用),将代码拆解成可复用的组件‌,GenericAPIView可以与ListModelMixin、CreateModelMixin、RetrieveModelMixin、UpdateModelMixin、DestroyModelMixin等Mixin结合使用,以实现增删改查等功能‌。

  • 视图集(ViewSet)

‌视图集‌是DRF中用于组织相关视图的集合。它们继承自APIView或GenericAPIView,并且可以定义多个方法(如list、create、retrieve、update、destroy等),这些方法对应不同的HTTP请求。视图集可以解决路由匹配和合并的问题,并且方法名可以自定义,路由匹配规则也需要相应修改。视图集还可以与Mixin结合使用,以实现更复杂的业务逻辑‌。

视图类

APIView

  • rest_framework.views.APIView
  • APIView是REST framework提供的所有视图的基类,继承自Django的View父类
APIView与View的不同之处
  • 传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象
  • 视图方法可以返回REST framework的Response对象,视图会为响应数据- 设置(render)符合前端要求的格式
  • 任何APIException异常都会被捕获到,并且处理成合适的响应信息
  • 在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制
支持定义的类属性
  • authentication_classes 列表或元祖,身份认证类
  • permissoin_classes 列表或元祖,权限检查类
  • throttle_classes 列表或元祖,流量控制类
APIViews 示例
from rest_framework.views import APIView
from rest_framework.response import Response

# url(r'^students/$', views.StudentsAPIView.as_view()),
class StudentsAPIView(APIView):
  	
    def get(self, request):
        data_list = Student.objects.all()
        serializer = StudentModelSerializer(instance=data_list, many=True)
        return Response(serializer.data)

GenericAPIView

  • rest_framework.generics.GenericAPIView
  • 继承自APIVIew,主要增加了操作序列化器和数据库查询的方法,作用是为下面Mixin扩展类的执行提供方法支持,通常在使用时,可搭配一个或多个Mixin扩展类
属性
serializer_class 指明视图使用的序列化器
queryset 指明使用的数据查询集
pagination_class 指明分页控制类
filter_backends 指明过滤控制后端
方法
get_serializer_class(self)
  • 当出现一个视图类中调用多个序列化器时,那么可以通过条件判断在get_serializer_class方法中通过返回不同的序列化器类名就可以让视图方法执行不同的序列化器对象了
  • 返回序列化器类,默认返回serializer_class,可以重写,例如:
def get_serializer_class(self):
    if self.request.user.is_staff:
        return FullAccountSerializer
    return BasicAccountSerializer
get_serializer(self, args, *kwargs)
  • 返回序列化器对象,主要用来提供给Mixin扩展类使用,如果我们在视图中想要获取序列化器对象,也可以直接调用此方法
  • 该方法在提供序列化器对象的时候,会向序列化器对象的context属性补充三个数据:request、format、view,这三个数据对象可以在定义序列化器时使用
  • request 当前视图的请求对象
  • view 当前请求的类视图对象
  • format 当前请求期望返回的数据格式
get_queryset(self)
  • 返回视图使用的查询集,主要用来提供给Mixin扩展类使用,是列表视图与详情视图获取数据的基础,默认返回queryset属性,可以重写,例如:
def get_queryset(self):
    user = self.request.user
    return user.accounts.all()
get_object(self)
  • 返回详情视图所需的模型类数据对象,主要用来提供给Mixin扩展类使用
    在试图中可以调用该方法获取详情信息的模型类对象
  • 若详情访问的模型类对象不存在,会返回404
  • 该方法会默认使用APIView提供的check_object_permissions方法检查当前对象是否有权限被访问, 例如:
# url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()),
class BookDetailView(GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    def get(self, request, pk):
        book = self.get_object() # get_object()方法根据pk参数查找queryset中的数据对象
        serializer = self.get_serializer(book)
        return Response(serializer.data)
GenericAPIView 示例
from rest_framework.generics import GenericAPIView

from students.models import Student
from .serializers import StudentModelSerializer, StudentModel2Serializer
from rest_framework.response import Response

class StudentsGenericAPIView(GenericAPIView):
    # 本次视图类中要操作的数据[必填]
    queryset = Student.objects.all()
    # 本次视图类中要调用的默认序列化器[选填]
    serializer_class = StudentModelSerializer

    def get(self, request):
        """获取所有学生信息"""
        serializer = self.get_serializer(instance=self.get_queryset(), many=True)

        return Response(serializer.data)

    def post(self,request):

        data = request.data

        serializer = self.get_serializer(data=data)

        serializer.is_valid(raise_exception=True)

        instance = serializer.save()

        serializer = self.get_serializer(instance=instance)

        return Response(serializer.data)


class StudentGenericAPIView(GenericAPIView):
    queryset = Student.objects.all()

    serializer_class = StudentModelSerializer

    def get_serializer_class(self):
        """重写获取序列化器类的方法"""
        if self.request.method == "GET":
            return StudentModel2Serializer
        else:
            return StudentModelSerializer

    # 在使用GenericAPIView视图获取或操作单个数据时,视图方法中的代表主键的参数最好是pk
    def get(self,request,pk):
        """获取一条数据"""
        serializer = self.get_serializer(instance=self.get_object())

        return Response(serializer.data)

    def put(self,request,pk):

        data = request.data

        serializer = self.get_serializer(instance=self.get_object(),data=data)

        serializer.is_valid(raise_exception=True)

        serializer.save()

        serializer = self.get_serializer(instance=self.get_object())

        return Response(serializer.data)
序列化器示例
from rest_framework import serializers

from students.models import Student

class StudentModelSerializer(serializers.ModelSerializer):
    class Meta:
        model= Student
        fields = "__all__"


class StudentModel2Serializer(serializers.ModelSerializer):
    class Meta:
        model= Student
        fields = ("name","class_null")

5个视图拓展类

  • 提供了几种后端视图(对数据资源进行增删改查)处理流程的实现,如果需要编写的视图属于这五种,则视图可以通过继承相应的扩展类来复用代码,减少自己编写的代码量
  • 这五个扩展类需要搭配GenericAPIView父类,因为五个扩展类的实现需要调用GenericAPIView提供的序列化器与数据库查询的方法
ListModelMixin
  • 列表视图扩展类,提供list(request, *args, **kwargs)方法快速实现列表视图,返回200状态码, 该Mixin的list方法会对数据进行过滤和分页
源码
class ListModelMixin(object):
    """
    List a queryset.
    """
    def list(self, request, *args, **kwargs):
        # 过滤
        queryset = self.filter_queryset(self.get_queryset())
        # 分页
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        # 序列化
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
示例
from rest_framework.mixins import ListModelMixin
from rest_framework.generics import GenericAPIView

class BookListView(ListModelMixin, GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    def get(self, request):
        return self.list(request)
CreateModelMixin
  • 创建视图扩展类,提供create(request, *args, **kwargs)方法快速实现创建资源的视图,成功返回201状态码, 如果序列化器对前端发送的数据验证失败,返回400错误
源码
class CreateModelMixin(object):
    """
    Create a model instance.
    """
    def create(self, request, *args, **kwargs):
        # 获取序列化器
        serializer = self.get_serializer(data=request.data)
        # 验证
        serializer.is_valid(raise_exception=True)
        # 保存
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        serializer.save()

    def get_success_headers(self, data):
        try:
            return {'Location': str(data[api_settings.URL_FIELD_NAME])}
        except (TypeError, KeyError):
            return {}
示例
from rest_framework.mixins import CreateModelMixin
from rest_framework.generics import GenericAPIView

class Book(CreateModelMixin, GenericAPIView):
    queryset = models.Book.objects.all()
    serializer_class = BookSerializer

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
RetrieveModelMixin
  • 详情视图扩展类,提供retrieve(request, *args, **kwargs)方法,可以快速实现返回一个存在的数据对象, 如果存在,返回200, 否则返回404
源码
class RetrieveModelMixin(object):
    """
    Retrieve a model instance.
    """
    def retrieve(self, request, *args, **kwargs):
        # 获取对象,会检查对象的权限
        instance = self.get_object()
        # 序列化
        serializer = self.get_serializer(instance)
        return Response(serializer.data)
示例
from rest_framework.mixins import RetrieveModelMixin
from rest_framework.generics import GenericAPIView

class BookDetailView(RetrieveModelMixin, GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    def get(self, request, pk):
        return self.retrieve(request)
UpdateModelMixin

更新视图扩展类,提供update(request, *args, **kwargs)方法,可以快速实现更新一个存在的数据对象, 同时也提供partial_update(request, *args, **kwargs)方法,可以实现局部更新, 成功返回200,序列化器校验数据失败时,返回400错误

源码
class UpdateModelMixin(object):
    """
    Update a model instance.
    """
    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        return Response(serializer.data)

    def perform_update(self, serializer):
        serializer.save()

    def partial_update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return self.update(request, *args, **kwargs)
示例
from rest_framework.mixins import UpdateModelMixin
from rest_framework.generics import GenericAPIView

class BookDetail(UpdateModelMixin, GenericAPIView):
    queryset = models.Book.objects.all()
    serializer_class = BookSerializer

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
DestroyModelMixin
  • 删除视图扩展类,提供destroy(request, *args, **kwargs)方法,可以快速实现删除一个存在的数据对象, 成功返回204,不存在返回404
源码
class DestroyModelMixin(object):
    """
    Destroy a model instance.
    """
    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        self.perform_destroy(instance)
        return Response(status=status.HTTP_204_NO_CONTENT)

    def perform_destroy(self, instance):
        instance.delete()
示例
from rest_framework.mixins import DestroyModelMixin
from rest_framework.generics import GenericAPIView

class BookDetail(DestroyModelMixin, GenericAPIView):
    queryset = models.Book.objects.all()
    serializer_class = BookSerializer

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
混合使用示例 (创建、列表)
"""GenericAPIView结合视图扩展类实现api接口"""
from rest_framework.mixins import ListModelMixin,CreateModelMixin
class Students2GenericAPIView(GenericAPIView,ListModelMixin,CreateModelMixin):
    # 本次视图类中要操作的数据[必填]
    queryset = Student.objects.all()
    # 本次视图类中要调用的默认序列化器[选填]
    serializer_class = StudentModelSerializer

    def get(self, request):
        """获取多个学生信息"""
        return self.list(request)

    def post(self,request):
        """添加学生信息"""
        return self.create(request)
混合使用示例 (更新、删除)
from rest_framework.mixins import RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin
class Student2GenericAPIView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
    queryset = Student.objects.all()

    serializer_class = StudentModelSerializer

    # 在使用GenericAPIView视图获取或操作单个数据时,视图方法中的代表主键的参数最好是pk
    def get(self,request,pk):
        """获取一条数据"""
        return self.retrieve(request,pk)

    def put(self,request,pk):
        """更新一条数据"""
        return self.update(request,pk)

    def delete(self,request,pk):
        """删除一条数据"""
        return self.destroy(request,pk)

GenericAPIView的9个视图子类

CreateAPIView
  • 提供 post 方法
  • 继承自: GenericAPIView、CreateModelMixin
ListAPIView
  • 提供 get 方法
  • 继承自:GenericAPIView、ListModelMixin
ListCreateAPIView
  • 提供 get 和 post方法
  • 继承自:GenericAPIView、ListModelMixin、CreateModelMixin
RetrieveAPIView
  • 提供 get 方法
  • 继承自: GenericAPIView、RetrieveModelMixin
DestoryAPIView
  • 提供 delete 方法
  • 继承自:GenericAPIView、DestoryModelMixin
UpdateAPIView
  • 提供 put 和 patch 方法
  • 继承自:GenericAPIView、UpdateModelMixin
RetrieveUpdateAPIView
  • 提供 get、put、patch方法
  • 继承自: GenericAPIView、RetrieveModelMixin、UpdateModelMixin
RetrieveDestroyAPIView
  • 提供 get 和 delete 方法
  • 继承自:GenericAPIView、RetrieveModelMixin、DestoryModelMixin
RetrieveUpdateDestoryAPIView
  • 提供 get、put、patch、delete方法
  • 继承自:GenericAPIView、RetrieveModelMixin、UpdateModelMixin、DestoryModelMixin
CURD完整示例
import hashlib
from django.db import models
from django.conf import settings
from django.db import models
from django.contrib.auth.models import AbstractUser


table_prefix = "rest_"


class CoreModel(models.Model):
    """
        核心标准抽象模型模型,可直接继承使用
        增加审计字段, 覆盖字段时, 字段名称请勿修改, 必须统一审计字段名称
    """
    id = models.BigAutoField(
        primary_key=True,
        help_text="Id",
        verbose_name="Id"
    )
    description = models.CharField(
        max_length=255,
        verbose_name="描述",
        null=True,
        blank=True,
        help_text="描述"
    )
    creator = models.ForeignKey(
        to=settings.AUTH_USER_MODEL,
        related_query_name='creator_query',
        null=True,
        verbose_name='创建人',
        help_text="创建人",
        on_delete=models.SET_NULL,
        db_constraint=False
    )
    modifier = models.CharField(
        max_length=255,
        null=True,
        blank=True,
        help_text="修改人",
        verbose_name="修改人"
    )
    dept_belong_id = models.CharField(
        max_length=255,
        help_text="数据归属部门",
        null=True,
        blank=True,
        verbose_name="数据归属部门"
    )
    update_datetime = models.DateTimeField(
        auto_now=True,
        null=True,
        blank=True,
        help_text="修改时间",
        verbose_name="修改时间"
    )
    create_datetime = models.DateTimeField(
        auto_now_add=True,
        null=True,
        blank=True,
        help_text="创建时间",
        verbose_name="创建时间"
    )

    class Meta:
        abstract = True
        verbose_name = '核心模型'
        verbose_name_plural = verbose_name


class Users(CoreModel, AbstractUser):
    GENDER_CHOICES = (
        (0, "未知"),
        (1, "男"),
        (2, "女"),
    )
    USER_TYPE = (
        (0, "后台用户"),
        (1, "前台用户"),
    )
    username = models.CharField(
        max_length=150,
        unique=True,
        db_index=True,
        verbose_name="用户账号",
        help_text="用户账号"
    )
    employee_no = models.CharField(
        max_length=150,
        unique=True,
        db_index=True,
        null=True,
        blank=True,
        verbose_name="工号",
        help_text="工号"
    )
    email = models.EmailField(
        max_length=255,
        verbose_name="邮箱",
        null=True,
        blank=True,
        help_text="邮箱"
    )
    mobile = models.CharField(
        max_length=255,
        verbose_name="电话",
        null=True,
        blank=True,
        help_text="电话"
    )
    avatar = models.CharField(
        max_length=255,
        verbose_name="头像",
        null=True,
        blank=True,
        help_text="头像"
    )
    name = models.CharField(
        max_length=40,
        verbose_name="姓名",
        help_text="姓名"
    )
    gender = models.IntegerField(
        choices=GENDER_CHOICES,
        default=0,
        verbose_name="性别",
        null=True,
        blank=True,
        help_text="性别"
    )
    user_type = models.IntegerField(
        choices=USER_TYPE,
        default=0,
        verbose_name="用户类型",
        null=True,
        blank=True,
        help_text="用户类型"
    )
    last_token = models.CharField(
        max_length=255,
        null=True,
        blank=True,
        verbose_name="最后一次登录Token",
        help_text="最后一次登录Token"
    )

    def set_password(self, raw_password, **kwargs):
        super().set_password(
            hashlib.md5(raw_password.encode(encoding="UTF-8")).hexdigest()
        )

    class Meta:
        db_table = table_prefix + "system_users"
        verbose_name = "用户表"
        verbose_name_plural = verbose_name
        ordering = ("-create_datetime",)


class Book(CoreModel):
    title = models.CharField(
        verbose_name="标题",
        max_length=1024,
        null=True,
        blank=True,
        help_text="标题",
    )
    author = models.CharField(
        verbose_name="作者",
        max_length=1024,
        null=True,
        blank=True,
        help_text="作者",
    )

    class Meta:
        db_table = table_prefix + "book"
        verbose_name = "图书表"
        verbose_name_plural = verbose_name
from myproject import models
from rest_framework.fields import empty
from rest_framework.request import Request
from rest_framework.serializers import ModelSerializer

from rest_framework.generics import CreateAPIView, ListAPIView, ListCreateAPIView
from rest_framework.generics import RetrieveAPIView, UpdateAPIView, DestroyAPIView, RetrieveDestroyAPIView, RetrieveUpdateAPIView, RetrieveUpdateDestroyAPIView


class CustomModelSerializer(ModelSerializer):
    """
        增强DRF的ModelSerializer,
        (1)self.request能获取到rest_framework.request.Request对象
    """
    def __init__(self, instance=None, data=empty, request=None, **kwargs):
        super().__init__(instance, data, **kwargs)
        self.request: Request = request or self.context.get("request", None)


class BookSerializer(CustomModelSerializer):
    creator = UserSerializer(required=False)
    create_datetime = serializers.DateTimeField(
        format="%Y-%m-%d %H:%M:%S", required=False, read_only=True
    )
    update_datetime = serializers.DateTimeField(
        format="%Y-%m-%d %H:%M:%S", required=False
    )
    # creator = serializers.StringRelatedField()

    class Meta:
        model = Book
        fields = ["title", "author", "create_datetime", "update_datetime", "creator"]
        depth = 1

# 此视图只可以新增、不可以查询
class Book(CreateAPIView):
    queryset = models.Book.objects.all()
    serializer_class = BookSerializer


# 此视图查询一条、修改、删除都包含
class BookDetail(RetrieveUpdateDestroyAPIView):  
    queryset = models.Book.objects.all()
    serializer_class = BookSerializer

总结

两个基类

  • APIView
  • GenericAPIView: 数据库操作, queryset 和serializer_class

5个视图扩展类(rest_framework.mixins)

  • CreateModelMixin: create方法创建一条
  • DestroyModelMixin: destory方法删除一条
  • ListModelMixin: list方法获取所有
  • RetrieveModelMixin: retrieve获取一条
  • UpdateModelMixin: update修改一条

9个子类视图(rest_framework.generics)

  • CreateAPIView: 继承CreateModelMixin,GenericAPIView,有post方法,新增数据
  • DestroyAPIView: 继承DestroyModelMixin,GenericAPIView,有delete方法,删除数据
  • ListAPIView: 继承ListModelMixin,GenericAPIView,有get方法获取所有
  • UpdateAPIView: 继承UpdateModelMixin,GenericAPIView,有put和patch方法,修改数据
  • RetrieveAPIView: 继承RetrieveModelMixin,GenericAPIView,有get方法,获取一条
  • ListCreateAPIView: 继承ListModelMixin,CreateModelMixin,GenericAPIView,有get获取所有,post方法新增
  • RetrieveDestroyAPIView: 继承RetrieveModelMixin,DestroyModelMixin,GenericAPIView,有get方法获取一条,delete方法删除
  • RetrieveUpdateAPIView: 继承RetrieveModelMixin,UpdateModelMixin,GenericAPIView,有get获取一条,put,patch修改
  • RetrieveUpdateDestroyAPIView: 继承RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView,有get获取一条,put,patch修改,delete删除

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

spring中使用@Validated,什么是JSR 303数据校验,spring boot中怎么使用数据校验

文章目录 一、JSR 303后台数据校验1.1 什么是 JSR303&#xff1f;1.2 为什么使用 JSR 303&#xff1f; 二、Spring Boot 中使用数据校验2.1 基本注解校验2.1.1 使用步骤2.1.2 举例Valid注解全局统一异常处理 2.2 分组校验2.2.1 使用步骤2.2.2 举例Validated注解Validated和Vali…

网页单机版五子棋小游戏项目练习-初学前端可用于练习~

今天给大家分享一个 前端练习的项目&#xff0c;技术使用的是 html css 和javascrpit 。希望能对于 刚刚学习前端的小伙伴一些帮助。 先看一下 实现的效果图 1. HTML&#xff08;HyperText Markup Language&#xff09; HTML 是构建网页的基础语言&#xff0c;它的主要作用是定…

UE5材质节点Distance

Distance可以计算两个物体间的距离&#xff0c;可以用来做过渡效果 当相机和物体距离3000的时候&#xff0c;就会渐渐从蓝过渡到红色&#xff0c;除以500是为了平滑过渡

【AIGC-ChatGPT进阶提示词指令】AI美食助手的设计与实现:Lisp风格系统提示词分析

引言 在人工智能助手的应用领域中&#xff0c;美食烹饪是一个既专业又贴近生活的方向。本文将详细分析一个基于Lisp风格编写的美食助手系统提示词&#xff0c;探讨其结构设计、功能实现以及实际应用效果。 提出你的菜系&#xff0c;为你分析&#xff0c;并生成图片卡片 提示词…

基于开发/发布/缺陷分离模型的 Git 分支管理实践20250103

基于开发/发布/缺陷分离模型的 Git 分支管理实践 引言 在现代软件开发中&#xff0c;合理的分支管理策略是保证项目成功的关键因素之一。本文将详细介绍一种基于开发/发布/缺陷分离的 Git 分支管理模型&#xff0c;这种模型不仅能提升团队协作效率&#xff0c;还能确保代码质…

【Cocos TypeScript 零基础 3.1】

目录 场景跳转 场景跳转 把新建好的TS文件与场景绑定 选中 场景 或 camera 拖进右边的 属性检查器 双击T文件,进入编辑 至于用什么IDE看个位朋友高兴 我这里有 VScode ,先用这个,老师也没有推荐 (老师也用的是这个) VScode UI 也有中文包,请自行上网搜索 打开创建的TS文件后…

SAP SD学习笔记23 - 无偿出荷(免费交货)与继续无偿出荷(继续免费交货)

上一章讲了SAP中的一括请求处理。 SAP SD学习笔记22 - VF04&#xff0c;VF06&#xff0c;VF24 等一括请求处理-CSDN博客 本章继续讲SAP中的内容&#xff1a;无偿出荷 和 继续无偿出荷。 - 无偿出荷本身是挺常用的&#xff0c;常见的例子就是送给客户样品&#xff1b; - 继续…

021-spring-springmvc-组件

SpringMVC的handMapping 比较重要的部分 比较重要的部分 比较重要的部分 关于组件的部分 这里以 RequestMappingHandlerMapping 为例子 默认的3个组件是&#xff1a; org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping org.springframework.web.servlet.mvc…

实现一个iOS晃动动画

有时候在开发中&#xff0c; 需要我们实现一个晃动动画&#xff0c; 达到一个提示的效果&#xff0c;如下图所示 思路&#xff0c; 我们要实现的本质上是一个旋转动画&#xff0c;然后 设置一个旋转角度&#xff0c;以底部中间为中心旋转&#xff0c; 左右各有一个旋转的角度…

C# 服务调用RFC函数获取物料信息,并输出生成Excel文件

这个例子是C#服务调用RFC函数&#xff0c;获取物料的信息&#xff0c;并生成Excel文件 上接文章&#xff1a;C#服务 文章目录 创建函数创建结构编写源代码创建批处理文件运行结果-成功部署服务器C#代码配置文件注意&#xff01;&#xff01; 创建函数 创建结构 编写源代码 创建…

戴尔/Dell 电脑按什么快捷键可以进入 Bios 设置界面?

BIOS&#xff08;基本输入输出系统&#xff09;是计算机硬件与操作系统之间的桥梁&#xff0c;它负责初始化和测试系统硬件组件&#xff0c;并加载启动操作系统。在某些情况下&#xff0c;如调整启动顺序、更改系统时间或日期、修改硬件配置等&#xff0c;您可能需要进入BIOS进…

利用3DGS中convert.py处理自采数据

前言 3DGS源码中convert.py提供对自采数据集的处理&#xff0c;需要预先安装Colmap和ImageMagick. ubuntu22.04安装colmap 点击进入NVIDIA官网&#xff0c;查看GPU的CMAKE_CUDA_ARCHITECTURES 1、克隆colmap源码&#xff0c;并进入colmap文件夹 git clone https://github.c…

数据结构(ing)

学习内容 指针 指针的定义&#xff1a; 指针是一种变量&#xff0c;它的值为另一个变量的地址&#xff0c;即内存地址。 指针在内存中也是要占据位置的。 指针类型&#xff1a; 指针的值用来存储内存地址&#xff0c;指针的类型表示该地址所指向的数据类型并告诉编译器如何解…

实践:事件循环

实践&#xff1a;事件循环 代码示例 console.log(1); setTimeout(() > console.log(2), 0); Promise.resolve(3).then(res > console.log(res)); console.log(4);上述的代码的输出结果是什么 1和4肯定优先输出&#xff0c;因为他们会立即方式堆栈的执行上下文中执行&am…

从零开始开发纯血鸿蒙应用之逻辑封装

从零开始开发纯血鸿蒙应用 一、前言二、逻辑封装的原则三、实现 FileUtil1、统一的存放位置2、文件的增删改查2.1、文件创建与文件保存2.2、文件读取2.2.1、读取内部文件2.2.2、读取外部文件 3、文件删除 四、总结 一、前言 应用的动态&#xff0c;借助 UI 响应完成&#xff0…

ESP32 I2S音频总线学习笔记(一):初识I2S通信与配置基础

文章目录 简介为什么需要I2S&#xff1f;关于音频信号采样率分辨率音频声道 怎样使用I2S传输音频&#xff1f;位时钟BCLK字时钟WS串行数据SD I2S传输模型I2S通信格式I2S格式左对齐格式右对齐格式 i2s基本配置i2s 底层API加载I2S驱动设置I2S使用的引脚I2S读取数据I2S发送数据卸载…

CSS 中 content换行符实现打点 loading 正在加载中的效果

我们动态加载页面内容的时候&#xff0c;经常会使用“正在加载中…”这几个字&#xff0c;基本上&#xff0c;后面的 3 个点都是静态的。静态的问题在于&#xff0c;如果网络不流畅&#xff0c;加载时间比较长&#xff0c;就会给人有假死的 感觉&#xff0c;但是&#xff0c;如…

25考研王道数据结构课后习题笔记

声明&#xff1a;以下内容来自于B栈知名up主–白话拆解数据结构 回答&#xff1a;为什么要做这个&#xff0c;因为我这个学期学完了数据结构&#xff0c;而且这个数据结构是408的重头&#xff0c;为什么选择25的&#xff0c;因为这个25考研刚刚结束&#xff0c;25相对成熟&…

小程序发版后,强制更新为最新版本

为什么要强制更新为最新版本&#xff1f; 在小程序的开发和运营过程中&#xff0c;强制用户更新到最新版本是一项重要的策略&#xff0c;能够有效提升用户体验并保障系统的稳定性与安全性。以下是一些主要原因&#xff1a; 1. 功能兼容 新功能或服务通常需要最新版本的支持&…

GRAPE——RLAIF微调VLA模型:通过偏好对齐提升机器人策略的泛化能力(含24年具身模型汇总)

前言 24年具身前沿模型大汇总 过去的这两年&#xff0c;工作之余&#xff0c;我狂写大模型与具身的文章&#xff0c;加之具身大火&#xff0c;每周都有各种朋友通过CSDN私我及我司「七月在线」寻求帮助/指导(当然&#xff0c;也欢迎各大开发团队与我司合作共同交付&#xff09…