drf知识--07

回顾之视图层

# 两个视图基类:

from rest_framework.views import  APIView
        包装新的request、去除csrf认证、执行三大认证和处理全局异常
        -as_view
        -dispatch
        -parser_class
        -render_class

from rest_framework.generics import GenericAPIView
   继承自APIView
   类属性:queryset、serializer_class

# 方法:
get_queryset:子类可以重写
get_object :获取单条
get_serializer: 传参数,返回序列化类的对象
get_serializer_class :返回序列化类,不能传参数,再加括号用self.get_serializer(instance=qs,many=True)self.get_serializer_class()(instance=qs,many=True)
需要写跟 请求方式 同名的方法:get  get  post delete put 分到了两个类中
# views.py
from rest_framework.generics import GenericAPIView
from .models import Publish
from .serializer import PublishSerializerclass BookView(GenericAPIView):queryset = Book.objects.all()serializer_class = BookSerializerdef get(self, request):object_list = self.get_queryset()  # 获取所有要序列化的数据ser = self.get_serializer(instance=object_list, many=True)  # 获取序列化类return Response(ser.data)def post(self, request):ser = self.get_serializer(data=request.data)if ser.is_valid():ser.save()return Response(ser.data)else:return Response(ser.errors)class BookDetailView(GenericAPIView):queryset = Book.objects.all()serializer_class = BookSerializerdef put(self, request, *args, **kwargs):obj = self.get_object()  # 获取单挑---》内部就是按pk从request中取,取出pk对应的值,查询的ser = self.get_serializer(instance=obj, data=request.data)if ser.is_valid():ser.save()return Response(ser.data)else:return Response(ser.errors)def get(self, request, *args, **kwargs):obj = self.get_object()ser = self.get_serializer(instance=obj)return Response(ser.data)def delete(self, request, *args, **kwargs):self.get_object().delete()return Response('')

# 5个视图扩展类:

    CreateModelMixin:create 就是原来继承GenericAPIView后post中写的代码
    ListModelMixin:list 就是原来继承GenericAPIView后get中写的代码
    DestroyModelMixin:destroy 就是原来继承GenericAPIView后delete中写的代码
    RetrieveModelMixin:retrieve 就是原来继承GenericAPIView后get中写的代码
    UpdateModelMixin:update 就是原来继承GenericAPIView后put中写的代码    
    以后可以通过5个视图扩展类+GenericAPIView写接口--》还是要写 get  get  post delete put这些方法,但是具体内容可以直接使用父类的方法
    但是如果通过5个视图扩展类+GenericViewSet写接口---》路由写法变了--》映射关系,自动生成---》get:list-->所以以后再视图类中不需要写跟请求方式同名的方法了---》一个视图类中就能完成5个接口

# 9个视图子类 --视图类:

    都会继承GenericAPIView+5个视图扩展类+跟请求方式同名的方法
            UpdateAPIView
            RetrieveUpdateDestroyAPIView
            RetrieveUpdateAPIView
            RetrieveDestroyAPIView
            RetrieveAPIView
            ListCreateAPIView
            ListAPIView
            DestroyAPIView
            CreateAPIView
    以后视图类,继承自上面9个之一,只需要写两个类属性,就会直接有接口

回顾之视图集

ViewSetMixin:只要继承了它,路由写法变了:映射  自动生成  这个类必须视图类前面
ViewSet:ViewSetMixin+APIView 以后想路由自动生成,之前继承APIView的现在继承它
GenericViewSet:ViewSetMixin+GenericAPIView 以后想路由自动生成
ModelViewSet:快速实现5个接口,继承了ViewSetMixin+GenericAPIView+5个视图扩展类
ReadOnlyModelViewSet:快速实现2个接口

                继承了ViewSetMixin+GenericAPIView+2个视图扩展类

# 以后视图类继承谁的问题?
    -只想在视图类中写login接口
        APIView---》post
        GenericViewSet---》login--》装饰器

回顾之路由

# 继承ViewSetMixin的视图类,路由写法变了:
        映射的方式\自动生成的方式(这个用的多)
# 自动生成的使用步骤:
1、导入一个类:
            from rest_framework.routers import SimpleRouter, DefaultRouter
2、类实例化得到对象
            router = SimpleRouter()  # 生成的路径少
            router = DefaultRouter() # 多一个 / 路径
                    api/v1/--->显示了所有能访问的路由
                    api/v1/books/
                    api/v1/users/
3、注册视图类:有几个就注册几次
            router.register('books', views.BookView, 'books')
            router.register('users', views.UserView, 'users')
4、在总路由中加入
            方式一:urlpatterns += router.urls
            方式二:(可以加前缀)
            urlpatterns = [
                path('', include(router.urls)),
            ]

# 继承ViewSetMixin的视图类中有其他方法,如何注册路由
   action装饰器:
        methods
        detail:加不加pk     # books/1/login
        url_path:='xx':books/xx    如果不写,默认是方法名
        url_name:  反向解析用
# 以后在视图类上 通过 self.action  就能拿到当次请求的请求 action 方法名

class BookView(ReadOnlyModelViewSet):  # list  retrievedef get_queryset(self):if self.action=='list':return super().get_queryset()elif self.action=='xx':return Book.objects.all().filter(name__startswith="红")def get_serializer_class(self):# print('我一定会执行')# print(self.action)# return super().get_serializer_class()if self.action=='list':return 序列化所有的序列化类elif self.action=='retrieve':return 序列化单条的序列化类elif self.action=='login':return 序列化单条的序列化类

认证组件

# 登录功能
# 认证类:
        1 写一个类,继承BaseAuthentication
        2 重写 authenticate(self, request) 方法
        3 在方法内部,根据用户携带的 数据【token】,判断是否登录[核心逻辑],如果登录就继续往后走[返回两个变量],如果没登录,抛异常,就不会往后走[视图的方法就不执行了] 

# 必须有token才能登录,通过token去user
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from .models import User, UserToken
class LoginAuth(BaseAuthentication):def authenticate(self, request):token = request.query_params.get('token')user_token = UserToken.objects.filter(token=token).first()# 当前登录用户if user_token:user = user_token.userreturn user, user_tokenelse:raise AuthenticationFailed("您没有登录")

# 在视图类中使用 ---【这个视图类管理的所有方法,都会有登录认证的校验】

        class BookDetailView(GenericViewSet):
                        authentication_classes = [LoginAuth

# 在配置文件中配置,所有接口都会有,包括登录接口

# setting.pyREST_FRAMEWORK = {# 全局配置登录认证'DEFAULT_AUTHENTICATION_CLASSES': ['app01.auth.LoginAuth']}

# 局部禁用:
      class 视图类(APIView):
            authentication_classes = [ ]

 #  authenticate中如何判断是否登录:

class LoginAuth(BaseAuthentication):def authenticate(self, request):# 完成对用户的校验# 当次请求requesttoken = request.query_params.get('token') or request.META.get('HTTP_TOKEN')# 表中校验user_token = UserToken.objects.filter(token=token).first()# 当前登录用户if user_token:user = user_token.user# 校验过后,返回两个值# return后,在后续的视图类的方法中 通过 request.user 就能取到当前登录用户# 如果不按这个规则来,后续request.user取不到当前登录用户return user, user_tokenelse:raise AuthenticationFailed("您没有登录")

权限组件

# 访问某个接口有没有权限---》大部分情况下需要登录后再校验
# 使用方式跟认证雷同
# 写权限类     # 显示中文提示:self.message=中文
        1 写一个类,继承BasePermission
        2 重写 has_permission 方法
        3 在方法内部,根据用户的 类型,判断有没有权限,如果有返回True,如果没有返回False
# 在视图类中使用 ---【这个视图类管理的所有方法,都会有权限控制】
    class BookDetailView(GenericViewSet):
          permission_classes = [CommonPermission]
# 在配置文件中配置,所有接口都会有,包括登录接口

setting.py
REST_FRAMEWORK = {# 全局配置登录认证'DEFAULT_PERMISSION_CLASSES': ['']
}

# 局部禁用:
      class 视图类(APIView):
            permission_classes = [ ]
# 权限类代码
from rest_framework.permissions import BasePermission

# 只有超级管理员能访问,其他人都不能访问

class CommonPermission(BasePermission):def has_permission(self, request, view):# 到这,正常应该登录完了,登录完了 request.user 当前登录用户# 拿到用户后判断用户是否有权限--》用户表汇总用户类型字段 user_type--》根据类型判断权限try:user_type = request.user.user_typeif user_type == 2:return Trueelse:# user.get_字段名_display()  返回这个字段的choice对应的文字self.message = '您是:%s,您没有权限操作这个' % request.user.get_user_type_display()return Falseexcept Exception as e:# 未登录用户也没有权限self.message = '您没有登录,您没有权限操作这个'return False

# 补充,后续的权限类,可能逻辑更复杂
    # 后续可能使用ACL权限控制,RBAC权限控制
    # 开直播 in [看视频]
    #开直播 in  [看视频,收礼物,开直播]

频率组件

# 控制用户访问某个接口的频次,比如一分钟只能访问5次
# 使用步骤---跟上面有区别
    1 写个类,继承 SimpleRateThrottle
    2 重写方法:def get_cache_key(self, request, view): 返回什么就以什么做限制
    3 写一个类属性:
        rate = '5/minute'   # second  minute hour day
        rate = '5/m'
        rate = '5/d'
# 视图类上配置
    class BookView(ViewSetMixin, ListCreateAPIView):
            throttle_classes = [CommonThrottle]

# 全局配置--全局所有接口都会有频率限制

setting.pyREST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ['app01.throttling.CommonThrottle'],}

#  局部禁用
    class BookView(ViewSetMixin, ListCreateAPIView):
        throttle_classes = [ ]

# 频率类代码

from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
class CommonThrottle(SimpleRateThrottle):rate = '5/d'def get_cache_key(self, request, view):ip = request.META.get('REMOTE_ADDR')return ip  # 返回什么,就以什么做频率限制(ip,用户id)

登录认证+权限+频率代码总结

# urls.py
from django.contrib import admin
from django.urls import path,includeurlpatterns = [path('admin/', admin.site.urls),path('api/v1/', include('app01.urls')),
]# app01\urls.py
from django.urls import path, include
from . import views
from rest_framework.routers import SimpleRouter, DefaultRouterrouter = DefaultRouter()
router.register('users', views.UserView, 'users')
router.register('books', views.BookView, 'books')
router.register('books', views.BookDetailView, 'books')
urlpatterns = [path('', include(router.urls)),]
views.py
from django.shortcuts import render# Create your views here.from rest_framework.decorators import action
from rest_framework.viewsets import ViewSet
from .models import User, UserToken
from rest_framework.response import Response
import uuid
from rest_framework.viewsets import ViewSetMixin, GenericViewSet
from rest_framework.generics import ListCreateAPIView, GenericAPIView
from rest_framework.mixins import CreateModelMixin, ListModelMixin, DestroyModelMixin, RetrieveModelMixin, \UpdateModelMixin
from .models import Book
from .serializer import BookSerializer
from .auth import LoginAuth# 登录入口   1、拿到验证码
class UserView(ViewSet):authentication_classes = []permission_classes = []throttle_classes = []@action(methods=['POST'], detail=False)def login(self, request):username = request.data.get('username')password = request.data.get('password')user = User.objects.filter(name=username, password=password).first()if user:token = str(uuid.uuid4())UserToken.objects.update_or_create(defaults={'token': token}, user_id=user.pk)return Response({'code': '100', 'msg': '登录成功', 'token': token})else:return Response({'code': '101', 'msg': '用户名或密码错误'})# 添加和查询所有
class BookView(ViewSetMixin, ListCreateAPIView):authentication_classes = [LoginAuth]  # 验证是否登录queryset = Book.objects.all()serializer_class = BookSerializerdef list(self, request, *args, **kwargs):print(request.user.name)print(request.auth)return super().list(request, *args, **kwargs)class BookDetailView(GenericViewSet, DestroyModelMixin, RetrieveModelMixin, UpdateModelMixin):queryset = Book.objects.all()serializer_class = BookSerializer
# auth.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from .models import UserTokenclass LoginAuth(BaseAuthentication):def authenticate(self, request):token = request.query_params.get('token') or request.META.get('HTTP_TOKEN')user_token = UserToken.objects.filter(token=token).first()if user_token:user = user_token.userreturn user, user_tokenelse:raise AuthenticationFailed("您没有登录")
# permission.py
from rest_framework.permissions import BasePermission
# 只有超级管理员能访问,其他人都不能访问
class CommonPermission(BasePermission):def has_permission(self, request, view):try:user_type = request.user.user_typeif user_type == 2:return Trueelse:# user.get_字段名_display()  返回这个字段的choice对应的文字self.message = '您是:%s,您没有权限操作这个' % request.user.get_user_type_display()return Falseexcept Exception as e:# 未登录用户也没有权限if 'login' in request.path:return Trueelse:self.message = '您没有登录,您没有权限操作这个'return False
# throttling.py
from rest_framework.throttling import  SimpleRateThrottleclass CommonThrottle(SimpleRateThrottle):rate = '3/m'def get_cache_key(self, request, view):ip = request.META.get('REMOTE_ADDR')return ip
# setting.py
REST_FRAMEWORK = {# 全局配置登录认证'DEFAULT_AUTHENTICATION_CLASSES': ['app01.auth.LoginAuth'],    # 认证组件'DEFAULT_PERMISSION_CLASSES': ['app01.permission.CommonPermission'],   # 权限组件'DEFAULT_THROTTLE_CLASSES': ['app01.throttling.CommonThrottle'],   # 频率组件
}
# models.py# Create your models here.
from django.db import modelsclass Book(models.Model):name = models.CharField(max_length=32)price = models.DecimalField(max_digits=5, decimal_places=2)publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)authors = models.ManyToManyField(to='Author')@propertydef publish_detail(self):return {'name': self.publish.name, 'city': self.publish.city}@propertydef author_list(self):l = []for author in self.authors.all():l.append({'name': author.name, 'age': author.age})return ldef __str__(self):return self.nameclass Author(models.Model):name = models.CharField(max_length=32)age = models.IntegerField()author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)def __str__(self):return self.nameclass AuthorDetail(models.Model):telephone = models.BigIntegerField()birthday = models.DateField()addr = models.CharField(max_length=64)class Publish(models.Model):name = models.CharField(max_length=32)city = models.CharField(max_length=32)email = models.EmailField(blank=True, null=True)def __str__(self):return self.nameclass Meta:verbose_name = '出版社'verbose_name_plural = verbose_name#### 用户表,用来做登录
### 用户登录成功户,存登录状态
class User(models.Model):name = models.CharField(max_length=64)password = models.CharField(max_length=64)gender = models.CharField(max_length=64, default="男")# user_token = models.OneToOneField(to='UserToken')# 后续可以通过存的数字,取到文字user_type = models.IntegerField(default=0, choices=((0, '普通登录用户'), (1, '管理员'), (2, '超级管理员')))class UserToken(models.Model):user = models.OneToOneField(to='User', on_delete=models.CASCADE)token = models.CharField(max_length=64)

# GET是查看 ,POST是拿数据

# 先POST通过/users/去生成token写在表里

        再通过GET带上token去查看所有

权限组件源码分析

# 目标:
    1 为什么写一个类继承BasePermission,重写has_permission
        -可以不继承这个类,只重写这个方法也可以
    2 权限类中 self.message  会返回给前端
    3 局部配置:放在视图类中:permission_classes = [CommonPermission]
    4 全局配置,配置在配置文件中也可以--》视图类中就没有
        就会使用:permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
        优先从你项目的配置文件配置的DEFAULT_PERMISSION_CLASSES取,如果没有
        就会去drf的配置文件DEFAULT_PERMISSION_CLASSES取
# 从哪里开始找?
    继承APIView后,权限是在执行视图类的方法之前执行的
    执行视图类的方法---》dispath中

def dispatch(self, request, *args, **kwargs):try:# 三大认证:认证,权限,频率self.initial(request, *args, **kwargs)####执行视图类的方法开始###if request.method.lower() in self.http_method_names:handler = getattr(self, request.method.lower(),self.http_method_not_allowed)else:handler = self.http_method_not_allowedresponse = handler(request, *args, **kwargs)####执行视图类的方法结束###except Exception as exc:response = self.handle_exception(exc)return self.response#2 找到APIView的initialdef initial(self, request, *args, **kwargs):self.perform_authentication(request)#认证self.check_permissions(request)#权限 self.check_throttles(request)#频率# 3 self.check_permissions(request)---APIViewdef check_permissions(self, request):# self是 视图类的对象#self.get_permissions [CommonPermission(),]--->咱们配置的一个个权限类的对象,放到列表中# permission 权限类的对象for permission in self.get_permissions():# 咱们写的权限类,要重写has_permission,传了俩参数# 参数:request 是新的request# 参数:self 是?视图类的对象,就是咱么在视图类中写的self,它里面有# request和action等if not permission.has_permission(request, self):# 视图类的对象,没有权限self.permission_denied(request,# 从权限类的对象中反射了message,就是写的给前端看的文字message=getattr(permission, 'message', None),#响应状态码code=getattr(permission, 'code', None))# 4 self.get_permissions() ---> APIView的def get_permissions(self):# 咱么视图类上配置的 permission_classes = [CommonPermission]# 返回值是 [CommonPermission(),]--->咱们配置的一个个权限类的对象,放到列表中return [permission() for permission in self.permission_classes]# 5 self.permission_denied  --》APIView中def permission_denied(self, request, message=None, code=None):if request.authenticators and not request.successful_authenticator:raise exceptions.NotAuthenticated()# 抛了异常,会被全局异常捕获,detai会放在响应体中,code会放在响应状态码中raise exceptions.PermissionDenied(detail=message, code=code)

认证类源码分析

# 继承APIView后,权限是在执行视图类的方法之前执行的
   执行视图类的方法---》dispath中        

def dispatch(self, request, *args, **kwargs):try:# 三大认证:认证,权限,频率self.initial(request, *args, **kwargs)####执行视图类的方法开始###if request.method.lower() in self.http_method_names:handler = getattr(self, request.method.lower(),self.http_method_not_allowed)else:handler = self.http_method_not_allowedresponse = handler(request, *args, **kwargs)####执行视图类的方法结束###except Exception as exc:response = self.handle_exception(exc)return self.response#2 找到APIView的initialdef initial(self, request, *args, **kwargs):self.perform_authentication(request)#认证self.check_permissions(request)#权限 self.check_throttles(request)#频率# 3 self.perform_authentication(request)def perform_authentication(self, request):request.user # 新的request对象# 4 Request类中找 user 方法包装成了数据属性from rest_framework.request import Request@propertydef user(self):if not hasattr(self, '_user'):with wrap_attributeerrors():# self是 新的request对象self._authenticate() # 一开始没有,就走了self._authenticate()return self._user# 5  Request类中找_authenticate()def _authenticate(self):# 拿出你配置在视图类上一个个认证类的对象  LoginAuth()# authenticator就是LoginAuth()for authenticator in self.authenticators:try:# 为什么咱么要重写 authenticate#self是谁?request就是认证类的 def authenticate(self, request):# 正常返回两个值:return user, user_token# 如果抛了异常:AuthenticationFailed--》捕获了APIExceptionuser_auth_tuple = authenticator.authenticate(self)except exceptions.APIException:self._not_authenticated()raiseif user_auth_tuple is not None:#正常返回了两个值self._authenticator = authenticator# 解压赋值:self是request#后续在视图类中 request.user 就是当前登录用户self.user, self.auth = user_auth_tuplereturnself._not_authenticated()

#  咱们视图类中得认证类可以配置多个
    -如果 第一个认证类,就返回了两个值
    -后续的认证类就不走了
    -如果认证类中要返回两个值,视图类中配了多个---》把返回两个值的放在最后
    -返回的两个值,第一个给了request.user,第一个给了request.auth,后续视图类中可以取出来

# self.authenticators ---》 Request中
# Request类实例化得到对象,传入authenticators 最终给了
def __init__(self, request, parsers=None, authenticators=None,negotiator=None, parser_context=None):self.authenticators = authenticators or ()# 8 哪里对Request类实例化了? APIView中
APIView 中dispatch中---》包装了新的request
request = self.initialize_request(request, *args, **kwargs)
def initialize_request(self, request, *args, **kwargs):return Request(request,parsers=self.get_parsers(),authenticators=self.get_authenticators(),negotiator=self.get_content_negotiator(),parser_context=parser_context)# 9 self.get_authenticators()  在APIView中 self是视图类的对象def get_authenticators(self):return [auth() for auth in self.authentication_classes]

今日思维导图:

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

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

相关文章

5.8 Linux 服务实战

一、项目概述 项目名称:web 网站 项目时间:2022.7.18-2022.7.24 项目需求: ① 客户端使用kickstart部署4台虚拟机(centos7.9),所有服务器IP都为静态IP。② 客户端使用XShell的密钥登陆跳板机③ 所有后端服务器全部通过跳板机来…

Shell命令与Linux操作系统:深入理解其原理和功能(2/2)

在当今数字化时代,操作系统的安全性和稳定性对于个人用户和企业都至关重要。Linux,作为一个广泛使用的操作系统,其强大的文件权限系统是保护系统安全的核心机制之一。无论是在服务器管理、软件开发还是日常使用中,有效地管理和理解…

MongoDB文档操作

3.3 文档操作 3.1 文档介绍 文档的数据结构和 JSON 基本一样。 所有存储在集合中的数据都是 BSON 格式。 BSON 是一种类似 JSON 的二进制形式的存储格式,是 Binary JSON 的简称。 文档是一组键值(key-value)对(即 BSON),一个简单的文档例子如下&…

输入日期,计算当前日期是这一年中的第几天(涉及闰年问题)

一、应用到的知识:闰年问题,数组,for循环,命令行参数,atoi函数 1. 闰年问题: 闰年 是指该年有366日,即较平常年份多出一日。每400年就会有一次闰年;或者年份是4的倍数,但…

Flowable-升级为7.0.0.M2-第二节

目录 替换变化的类和配置把javax.servlet 替换为 jakarta.servlet修改redis的配置配置logging.level.org.springframework.boot.autoconfigureerror避免影响视听 替换变化的类和配置 把javax.servlet 替换为 jakarta.servlet import javax.servlet.ServletContext; import ja…

【Linux基础】9. 用户管理

文章目录 【 1. 用户基本管理 】1.1 useradd 添加用户1.2 passwd 更改用户密码1.3 su 切换用户1.4 userdel 删除用户 【 2. 用户的组 】2.1 more 查看系统所有组2.2 显示用户的组2.3 更改用户的组 【 3. 环境变量 】 【 1. 用户基本管理 】 1.1 useradd 添加用户 全称作用use…

【教程】使用ipagurd打包与混淆Cocos2d-x的Lua脚本

文章目录 摘要引言正文1. 准备工作2. 使用ipaguard处理Lua文件3. 运行ipagurd进行混淆代码加密具体步骤测试和配置阶段IPA 重签名操作步骤4. IPA重签名与发布 总结 摘要 本文将介绍如何使用ipagurd工具对Cocos2d-x中的Lua脚本进行打包与混淆,以及在iOS应用开发中的…

tekton 发布 kubernetes 应用

tekton 发布 kubernetes 应用 基于Kubernetes 服务部署 Tekton Pipeline 实例,部署完成后使用tekton来完成源码拉取、应用打包、镜像推送和应用部署。 本文实现一个 golang-helloworld 项目 CI/CD 的完整流程,具体包括以下步骤: 从 gitee…

css 超过一行/多行显示省略号... - 附示例

效果 1、超过一行 2、超过多行 - 以两行为例 二、示例代码 1、超过一行 margin: 20px; width: 50px; border: 1px solid red; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; 2、超过多行 - 以两行为例 margin: 20px; width: 50px; border: 1px solid r…

【日常聊聊】年度总结

🍎个人博客:个人主页 🏆个人专栏:日常聊聊 ⛳️ 功不唐捐,玉汝于成 目录 前言 博客创作的初衷: 学到的技能: Java知识的深度掌握: Spring框架的应用和实践: 前端技…

Unity so文件的问题

文章目录 问题在面板上无法显示子节点如何保存继承于so的类必须放置在单个脚本so类文件名和类名要一致 问题 最近自己在写一个行为树出现一些问题记录一下首先NodeTree肯定是so文件但是node可以是单纯的类,也可以是so。后来我发现只能是so 在面板上无法显示 第一…

linux 网络工具(二)

linux 网络工具 1. ip命令簇4.1 address4.2 link4.3 route4.4 rule 2. 其他常用命令2.1 ifup/ifdown2.2 配置主机名2.3 设置DNS服务器指向2.4 配置域名解析2.5 ss2.6 路由相关配置文件2.7 查看机器可用端口2.8 traceroute2.9 dhclient 1. ip命令簇 Linux的ip命令和ifconfig类似…

系列十七(面试)、请你谈谈RocketMQ的消息丢失问题

一、RocketMQ的消息丢失问题 1.1、概述 生产环境中为了保证服务的高可用,一般情况下都是采用集群的方式,RocketMQ也不例外,另外现在企业级的开发基本都是分布式微服务的模式,这就存在着跨网络传输数据的问题,而网络传…

【PTA】L1-016 验证身份(C++)

题目链接 : 题目要求: 一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下: 首先对前17位数字加权求和,权重分配为:{7,9,10,5&#xff0…

【七】【C语言\动态规划】最大子数组和、环形子数组的最大和、乘积最大子数组,三道题目深度解析

动态规划 动态规划就像是解决问题的一种策略,它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题,并将每个小问题的解保存起来。这样,当我们需要解决原始问题的时候,我们就可以直接利…

python脚本抢各大平台大额优惠卷

文章目录 python脚本抢各大平台大额优惠卷写在前面准备阶段一、所需工具二、ChromeDriver下载教程 三、Seleuinm安装1、打开cmd,输入如下命令 开始抢券淘宝脚本京东抢购脚本 python脚本抢各大平台大额优惠卷 写在前面 当电商平台上演盛大的购物狂欢时,如…

SpringBoot3 基础特性

1. SpringApplication 1.1. 自定义 banner 类路径添加banner.txt或设置spring.banner.location就可以定制 banner推荐网站:Spring Boot banner 在线生成工具,制作下载英文 banner.txt,修改替换 banner.txt 文字实现自定义,个性化…

数据驱动与数据安全,自动驾驶看得见的门槛和看不见的天花板

作者 |田水 编辑 |德新 尽管心理有所准备,2023年智能驾驶赛道的内卷程度还是超出了大多数人的预期。 这一年,汽车价格战突然开打,主机厂将来自销售终端的价格压力,传导到下游智驾供应商,于是,市面上出现…

医院云HIS系统源码,saas多医院版,适用于专科医院、集团医院、基层医院

医院云HIS系统源码,自主研发,自主版权,电子病历病历4级 系统概述: 一款满足基层医院各类业务需要的云HIS系统。该系统能帮助基层医院完成日常各类业务,提供病患挂号支持、病患问诊、电子病历、开药发药、会员管理、统…

数据结构:单调栈

1.单调栈 单调栈是一种数据结构,其中存放的数据应该是有序的,所以单调栈也有单调递减栈和单调递增栈 单调递增栈:栈顶到栈底的元素大小是从小到大 单调递减栈:栈顶到栈底的元素大小是从大到小 单调栈主要就是用来求一个给定序列中…