首页 > 其他分享 >05限流和序列化

05限流和序列化

时间:2024-05-15 16:57:06浏览次数:27  
标签:serializers name 05 self publish 限流 序列化 data

限流和序列化

1.限流

限流,限制用户访问频率,一般的限流用户信息都存于缓存之中,例如:用户1分钟最多访问100次 或者 短信验证码一天每天可以发送50次, 防止盗刷。

  • 对于匿名用户,使用用户IP作为唯一标识。
  • 对于登录用户,使用用户ID或名称作为唯一标识。

1.1限流组件使用步骤

(1)创建限流组件类
# 引入相关模块
from rest_framework import exceptions
from rest_framework import status
from rest_framework.throttling import SimpleRateThrottle



class CommonThrottle(SimpleRateThrottle):
    cache = default_cache  # 访问记录存放在django的缓存中(需设置缓存)
    scope = "user"  # 构造缓存中的key
    # 唯一标识符
    cache_format = 'throttle_%(scope)s_%(ident)s'

    # 设置访问频率,例如:1分钟允许访问10次
    # 其他:'s', 'sec', 'm', 'min', 'h', 'hour', 'd', 'day'
    THROTTLE_RATES = {"user": "10/m"}
		
    # 获取用户信息,组成唯一标识
    def get_cache_key(self, request, view):
 
        # 返回什么,就会以什么做限制,以ip地址限制
         return request.META.get('REMOTE_ADDR')

    # 超出限制提示信息方法
    def throttle_failure(self):
        # 调用父类wait方法,得到需要等待的时间
        wait = self.wait()
        # 异常信息
        detail = {
            "code": 1005,
            "data": "访问频率限制",
            'detail': "需等待{}s才能访问".format(int(wait))
        }
        # 抛出异常
        raise ThrottledException(detail)


  • 创建了限流类CommonThrottle,继承SimpleRateThrottle

  • 访问记录全部存放在django的缓存中

  • THROTTLE_RATES = {"user": "10/m"}设置访问频率

  • 如果超过限流限制,走throttle_failure方法提示异常信息

(2)调用限流类
class OrderView(APIView):
  	# 声明throttle_classes的值为限流类名
    throttle_classes = [CommonThrottle, ]

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

1.2 多个限流类

本质,每个限流的类中都有一个 allow_request 方法,此方法内部可以有三种情况:

  • 返回True,表示当前限流类允许访问,继续执行后续的限流类。
  • 返回False,表示当前限流类不允许访问,继续执行后续的限流类。所有的限流类执行完毕后,读取所有不允许的限流,并计算还需等待的时间。
  • 抛出异常,表示当前限流类不允许访问,后续限流类不再执行。

1.3 全局配置限流类

  • 如果每个类都需要使用限流组件,可以在settings配置文件里配置全局限流
  • 配置完全局限流组件后,视图类中则不需要在单独引用限流组件
  • 如果说在全局配置中配置了限流频率,在限流了中给予无需再设置了
REST_FRAMEWORK = {
    "DEFAULT_THROTTLE_CLASSES":["app名称.限流组件的py文件.限流组件类名", ],
    "DEFAULT_THROTTLE_RATES": {
      	# 限流频率
        "user": "10/m",
        "xx":"100/h"
    }
}
  • 如果说某个视图类想单独使用某个限流组件
  • 在视图类下单独声明一个空的throttle_classes则可以覆盖全局默认的限流组件
class OrderView(APIView):
    throttle_classes = []

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

1.4 限流类源码执行流程

2. 序列化器 Serializer,转json序列化,转字典反序列化

2.1 序列化器作用

  • 序列化,序列化器会把模型对象转换成字典,经过视图中response对象以后变成json字符串
  • 反序列化,视图中request会把客户端发送过来的数据转换成字典,序列化器可以把字典转成模型
  • 反序列化,把客户端发送过来的数据进行校验,并存储入库

2.2 序列化类的使用

# 使用步骤:
    # 1 写个py文件,叫serializer.py
    # 2 写个类,继承serializers.Serializer
    # 3 在类中写要序列化的字段
    class PublishSerializer(serializers.Serializer):
        # 写字段,要序列化的字段
        name = serializers.CharField()
        addr = serializers.CharField()
        id = serializers.IntegerField()
        
    # 4 在视图类中使用,完成  序列化
    	-多条
        	-ser = PublishSerializer(instance=publish_list, many=True)  	
            -ser.data  序列化后的数据
        -单条:
        	-ser = PublishSerializer(instance=publish)  	
            -ser.data  序列化后的数据

2.3 序列化类的快速使用

  • 视图类中引用
from app01.Serializer import PublisherSerializer


class PublishView(APIView):
  
    def get(self, request):
        publish_list = Publish.objects.all()
        ser = PublishSerializer(instance=publish_list, many=True)  # 如果序列化多条,要many=True
        return Response({'code': 100, 'msg': '查询所有成功', 'results': ser.data})

      
class PublishDetailView(APIView):
    def get(self, request, pk):
        publish = Publish.objects.filter(pk=pk).first()
        ser = PublishSerializer(instance=publish)  # 单个不写many=True
        return Response(
            {'code': 100, 'msg': '查询单条成功', 'results': ser.data})
  • 创建序列化类
from rest_framework import serializers
class PublishSerializer(serializers.Serializer):
    # 写字段,要序列化的字段
    name = serializers.CharField()
    addr = serializers.CharField()
  • 路由
urlpatterns = [
    path('publish/', views.PublishView.as_view()),
    path('publish/<int:pk>',views.PublishDetailView.as_view()),
]

2.4 序列化类反序列化校验

# 序列化类可以做字段校验---》三层
# 第一层:字段自己
serializers.CharField(max_length=12,min_length=3)
    # 第二层:局部钩子
        def validate_name(self, name):
            # 待校验的前端传入的name的数据
            if name.startswith("sb"):
                # 不行,抛异常
                raise ValidationError('不能以sb开头')
            return name
        
   # 全局钩子--》attrs前端多传的,这里不会有,attrs所有的参数
	    def validate(self, attrs):
            print(attrs)
            # 多个字段同时校验
            # 出版社名和地址不能一样---》出版社前3个字不能和地址前3个字一样
            if attrs.get('name')[:3] == attrs.get('addr')[:3]:
                raise ValidationError('出版社名和地址不能一样')
            return attrs
        
        
# 使用步骤
	# 写序列化类:写三层规则
    # 视图类中:
        ser = PublishSerializer(data=request.data)  # 把待校验数据传入
        if ser.is_valid():  # 做数据校验---》三层
            print(ser.data)
        else:
            print(ser.errors)  # 没有校验通过,打印错误信息

2.5 序列化类保存

# 使用步骤:
	# 1.在序列化类中,必须重写 create,完成真正的保存
       # 保存,必须重写create
        def create(self, validated_data):
            # validated_data 校验过后的数据---》多传的数据,在这没有
            publish = Publish.objects.create(**validated_data)
            return publish  # 不要忘了返回新增的对象---》后续会拿着这个对象做序列化  ser.data--->根据它做序列化的
    # 2.在视图类中,数据校验通过后,调用ser.save()
     ser.save()  # 使用序列化类保存--》会报错---》咱们没有指定保存到那个表--》必须重写create方法
        
        
        
# 修改功能,也要校验和保存

# 修改使用步骤
	# 1.在序列化类中,必须重写 update,完成真正的修改
        def update(self, instance, validated_data): 
      			# 笨方法
            instance.name=validated_data.get('name')
            instance.addr=validated_data.get('addr')
            instance.save() # publish 对象的save---》保存到数据中
            
            # 高级方法
            # for key in validated_data:
              # setattr(instance,key,validated_data[key])
            # instance.save()
            return instance
   # 2.视图类中
		ser = PublishSerializer(instance=publish, data=request.data)
	 			if ser.is_valid():
            # ser.save()虽然新增或修改都是调用save,但是内部做了判断
            return Response({'code': 100, 'msg': '修改成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors}) 

2.6 序列化类的常用字段

  • 除了CharField 以外,还要很多别的---》表模型中 models.CharField --->基本一一对应
  • 如果跟 表模型中对不上:你统一用 CharField
序列化器
字段
模型
字段
序列化器字段选项
BooleanField BooleanField BooleanField()
CharField CharField
TextField等
CharField(
max_length=最大长度, min_length=最小长度,
allow_blank=False, 表示是否允许客户端提交空字符串,False表示不允许
trim_whitespace=True,表示是否移除字符串两边的空白字符,True表示移除
)
EmailField EmailField EmailField(max_length=None, min_length=None, allow_blank=False)
RegexField CharField RegexField(regex=正则表达式, max_length=None, min_length=None, allow_blank=False)
SlugField SlugField SlugField(max_length=50, min_length=None, allow_blank=False)
正则字段,验证正则模式 [a-zA-Z0-9*-]+
URLField URLField URLField(max_length=200, min_length=None, allow_blank=False)
UUIDField UUIDField UUIDField(format='hex_verbose')
format: 设置UUID格式,一般默认使用hex_verbose
'hex_verbose'"5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
'hex'"5ce0e9a55ffa654bcee01238041fb31a"
'int' - 如: "123456789012312313134124512351145145114"
'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
IPAddressField IPAddressField IPAddressField(protocol='both', unpack_ipv4=False, **options)
IntegerField SmallIntegerFiled
IntegerField
BigIntegerField
IntegerField(max_value=最大值, min_value=最小值)
FloatField FloatField FloatField(max_value=None, min_value=None)
DecimalField DecimalField DecimalField(
max_digits=数值的数字总个数, decimal_places=小数位个数, coerce_to_string=None, max_value=None, min_value=None)
DateTimeField DateTimeField DateTimeField(
format=api_settings.DATETIME_FORMAT, 表示日期格式
input_formats=None)
DateField DateField DateField(format=api_settings.DATE_FORMAT, input_formats=None)
TimeField TimeField TimeField(format=api_settings.TIME_FORMAT, input_formats=None)
DurationField DurationField DurationField()
ChoiceField 对应整型或字符串中的choices=属性选项 ChoiceField(choices=元祖选项) choices与Django的用法相同
MultipleChoiceField 对应整型或字符串中的choices=属性选项 MultipleChoiceField(choices=元祖选项) choices与Django的用法相同
FileField FileField FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ImageField ImageField ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ListField python里面的List ListField(child=模型列表, min_length=None, max_length=None)
DictField python里面的Dict DictField(child=模型对象)

字段的选项参数:

参数名称 作用
max_length 最大长度
min_lenght 最小长度
allow_blank 是否允许为空字符串
trim_whitespace 是否移除两边的空白字符
max_value 最小数值
min_value 最大数值

字段的通用选项参数:

参数名称 说明
read_only 表明该字段仅用于序列化输出,默认False
write_only 表明该字段仅用于反序列化输入,默认False
required 表明该字段在反序列化时必须输入,默认True
default 反序列化时使用的默认值
miss 序列化时使用的默认值
allow_null 表明反序列化时该字段是否允许传入None,默认False
validators 表明反序列化时该字段使用的验证器函数
error_messages 表明反序列化时如果验证出错了,返回错误错误信息的字典
label 用于HTML展示API页面时,显示的字段名称。
如果不写,则默认采用模型的verbose_name,但是前提是当前序列化器继承ModelSerializer
help_text 用于HTML展示API页面时,显示的字段帮助提示信息
如果不写,则默认采用模型的help_text,但是前提是当前序列化器继承ModelSerializer

2.7 多表关联序列化和反序列化

2.7.1 定制返回格式之source

# 1.source 定制返回字段名,必须跟models表中字段必须对应,
book_name = serializers.CharField(source='name')
# 2.可以跨表查询
publish_name=serializers.CharField(source='publish.name')
# 3.所有字段都可以被转成CharField
2.7.2 定制返回字段
(1)方案一在模型表中定义方法
  • Models.py
class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField(auto_now=True, null=True)
    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
    authors = models.ManyToManyField(to='Author')

    # 出版社详情
    def publish_detail(self):
        return {'name': self.publish.name, 'city': self.publish.city}

    # 作者详情
    def author_detail(self):
        author_list = []
        for author in self.authors.all():
            author_list.append({'name': author.name, 'age': author.age})
        return author_list

    def __str__(self):
        return self.name
  • serializer
class BookSerializer(serializers.Serializer):
    name = serializers.CharField()
    price = serializers.IntegerField()
    publish_date = serializers.DateField(required=False)
    # publish_detail 此字段表中没有,通过在models表模式中定义方法
    # 此处直接应用,字段名必须与models模型表中的方法名一致
    publish_detail = serializers.DictField()
    # 可以搭配source使用
    authors = serializers.ListField(source='author_detail')
  • 展示前端

(2)方案二通过SerializerMethodField
  • 一定要配合一个方法--》get_字段名,方法返回什么,前端就看到什么

  • Serializer.py

class BookSerializer(serializers.Serializer):
    name = serializers.CharField()
    price = serializers.IntegerField()
    publish_date = serializers.DateField(required=False)
    publish_detail = serializers.SerializerMethodField()

    def get_publish_detail(self, obj):
        return {'name': obj.publish.name, 'city': obj.publish.city}

    authors = serializers.SerializerMethodField()

    def get_authors(self, obj):
        author_list = []
        for author in obj.authors.all():
            author_list.append({'name': author.name, 'age': author.age})
        return author_list
  • 前端展示

(3)方案三 子序列化
  • serializer.py
  • 自定义字段需要使用的表都序列化一下,就是创建class 表名Serializer(serializers.Serializer):
class PublishSerializer(serializers.Serializer):
    name = serializers.CharField()
    city = serializers.CharField()
    email = serializers.EmailField()


class AuthorSerializer(serializers.Serializer):
    name = serializers.CharField()
    age = serializers.CharField()


class BookSerializer(serializers.Serializer):
    name = serializers.CharField()
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    publish_date = serializers.DateField()
    # 子序列化
    # source='publish' 映射model表中的publish字段
    publish_detail = PublishSerializer(source='publish')

    # 多条结果时 many=True
    authors_list = AuthorSerializer(source='authors', many=True)

  • 前端展示

2.8 多表关联反序列化和反序列化保存

# 反序列化保存
# 使用同一个序列化类会出现
	-序列化字段和反序列化字段不一致
   	-序列化字段
    		name
        price
        publish_detail
        author_list
    -反序列化字段:
    		name
        price
        publish
        author
        
    -如果是共同的,不需要额外处理
    -如果是不同的,需要通过字段参数控制
        read_only	表明该字段仅用于序列化输出,默认False,序列化过程
        write_only	表明该字段仅用于反序列化输入,默认False,反序列化过程
        
 # 注意:
		1 read_only write_only 控制序列化类中某些字段,只用来序列化或反序列化
    2 重写updata和create,保存逻辑,我们自己写
    3 视图类中 serializer = BookSerializer(instance=pk, data=request.data)
    	-后续在序列化类中的update中def update(self, instance, validated_data):
        -instance就是当时给的
        
 # 不要有误区---》增加图书,只是增加图书,选择作者和出版社(传:id)
{name:书名,price:11,publish:{'name':'北京出版社',city:北京},authors:[{},{}]}

{name:书名,price:11,publish:2,authors:[1,2]}
  • views.py
class BookView(APIView):


    def post(self, request):
        serializer = BookSerializer(data=request.data)
        if serializer.is_valid():
            print(serializer.validated_data)  # 校验过后的数据
            serializer.save()
            return Response('成功')
        else:
            return Response({'code': 100, 'msg': serializer.errors})


class BookDetailView(APIView):

    def put(self, request, pk):
        # obj = Book.objects.all().filter(pk=pk).first()
        # 传入的instance是什么,到了 update中,instance就是什么
        serializer = BookSerializer(instance=pk, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response('成功')
        else:
            return Response({'code': 100, 'msg': serializer.errors})

  • serializer.py
class BookSerializer(serializers.Serializer):
    name = serializers.CharField()
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    publish_date = serializers.DateField(required=False,default=datetime.now)
    #### 序列化的字段和反序列化字段不一致####
    ## 1 笨办法:再写个序列化类,单独用来反序列化
    ## 2 通过 read_only write_only	控制

    # 这个字段用来做序列化
    publish_detail = PublishSerializer(source='publish',read_only=True)
    # 这个字段用来做序列化
    authors_list = AuthorSerializer(source='authors', many=True,read_only=True)

    # 反序列化字段--》只用来保存---》多表关联
    publish=serializers.IntegerField(write_only=True) # 前端传入数字---》自动跟出版社id做对应
    authors=serializers.ListField(write_only=True)

    # 反序列化字段-->可以随意命名,跟表字段没关系--》但是后续保存和修改要对应好才行
    # publish_id=serializers.IntegerField(write_only=True) # 前端传入数字---》自动跟出版社id做对应
    # authors_xx=serializers.ListField(write_only=True)
    
    # 保存
    def create(self, validated_data):
        publish_id=validated_data.pop('publish')
        authors=validated_data.pop('authors')
        book=Book.objects.create(**validated_data,publish_id=publish_id)
        book.authors.add(*authors) # 向中间表中插入数据
        return book

    # 更新
    def update(self, instance, validated_data):
        publish_id=validated_data.pop('publish')
        authors=validated_data.pop('authors')
        book_qs=Book.objects.filter(pk=instance) # 查询qs对象
        book_qs.update(**validated_data,publish_id=publish_id) # 使用qs更新
        instance=book_qs.first() # 单个对象
        instance.authors.set(authors) # 向中间表中插入数据
        # instance.author.clear()
        # instance.authors.add(*authors)
        return instance

2.9 反序列化校验源码分析

#1  执行 ser.is_valid() 就会执行 反序列化的校验---》字段自己--》局部钩子---》全局钩子
#2  入口是:ser.is_valid()---》BaseSerializer 找到了
	1 自己写的BookSerializer---》serializer.Serializer---->BaseSerializer 
    2 源码如下
    def is_valid(self, *, raise_exception=False):
        # self 是 ser对象---》自己写的BookSerializer的对象--》一开始没有
        # 一旦有了,就不执行了,优化is_valid被多次调用,只会走一次校验
        if not hasattr(self, '_validated_data'):
            try:
                # 一旦执行过,以后self中就有_validated_data
                # 接下来看self.run_validation(self.initial_data)
                self._validated_data = self.run_validation(self.initial_data)
            except ValidationError as exc:
                self._validated_data = {}
                self._errors = exc.detail
            else:
                self._errors = {}

        if self._errors and raise_exception:
            raise ValidationError(self.errors)

        return not bool(self._errors)
	  3 self.run_validation(self.initial_data)---》serializer.Serializer类的,不要按住ctrl点击,否则会进 Field 类,看错了
        
      4 serializer.Serializer类的run_validation
        def run_validation(self, data=empty):
            # data前端传入的--{"name":"张三","age":68}
            # value是---》前端传入的,字段自己校验通过的字典---{"name":"张三","age":68}
            value = self.to_internal_value(data) # 执行局部钩子
            try:
                self.run_validators(value) # 先不看,忽略掉
                # self 是 BookSerializer的对象,如果我们写了全局钩子,走我们自己的,如果没写,走父类的,父类的根本没做校验
                # value={"name":"张三","age":68}
                value = self.validate(value)# 执行全局钩子
            except (ValidationError, DjangoValidationError) as exc:
                raise ValidationError(detail=as_serializer_error(exc))

            return value
        
        
      5 全局钩子读完了:self 是 BookSerializer的对象,如果我们写了全局钩子,走我们自己的,如果没写,走父类的,父类的根本没做校验
      6 局部钩子:value = self.to_internal_value(data)--》Serializer类的
        # for循环着去BookSerializer的对象中反射  validate_字段名的方法,如果有就执行,没有就不执行
     def to_internal_value(self, data):
        for field in fields: # 序列化类中所有字段类的对象 name=CharField()
            # self 是BookSerializer类的对象
            # 去BookSerializer类中,反射  validate_field字段类的对象.field_name
            validate_method = getattr(self, 'validate_' + field.field_name, None)
            try:
                # 如果能拿到,说明咱么写了局部钩子
                if validate_method is not None:
                    # 执行局部钩子--》传入了当前字段的value值
                    validated_value = validate_method(validated_value)
            except ValidationError as exc:
               # 如果抛异常,会被捕获
                errors[field.field_name] = exc.detail
            except DjangoValidationError as exc:
                errors[field.field_name] = get_error_detail(exc)
            except SkipField:
                pass
            else:
                set_value(ret, field.source_attrs, validated_value)

        if errors:
            raise ValidationError(errors)

        return ret
        	
        
# #####读了局部和全局钩子的执行位置#####
# 保存,修改也好,都要用validated_data,它是最准确的

2.10 ModelSerializer使用

# 之前写序列化类,没有显示指明跟哪个表一一对应

# ModelSerializer 可以跟表做一一对应关系
	-序列化类中,就不需要一个个写字段了--》跟表有对应关系
  -序列化类中,就不需要重写create和update
    
# 局部钩子全局钩子跟之前一样(注意层级)
  • serializer.py
from .models import Book
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model=Book
        # all代表全部字段
        # fields = '__all__'
        # 部分字段放在列表里
        fields=['id','name','publish_detail','authors_list']

        extra_kwargs={
            'name':{'max_length':8}, # 限制name不能超过8
            'publish':{'write_only':True},
            'authors':{'write_only':True},
        }

    # 自己再重写的字段
    # 这个字段用来做序列化
    publish_detail = PublishSerializer(source='publish',read_only=True)
    # 这个字段用来做序列化
    authors_list = AuthorSerializer(source='authors', many=True,read_only=True)

    # 不需要写create了,但是字段必须是:publish和authors
  • 前端传参数图片

3. 断言

# 断言 语法
assert 条件,'字符串'
翻译成if
if 条件:
		条件成立,继续走后续代码
else:
		raise Exception('字符串')
  
  
  
  
a = 10

## assert 后写条件,只要不符合条件,就会抛AssertionError异常,后面写异常信息
assert a == 11, ("不等于11,报错了")

# 等同于---》上面只要一行代码,源码中喜欢用
if not a == 11:
    raise Exception('不等于11,报错了')

标签:serializers,name,05,self,publish,限流,序列化,data
From: https://www.cnblogs.com/Formerly/p/18194206

相关文章

  • MindSponge分子动力学模拟——自定义控制器(2024.05)
    技术背景分子动力学模拟中的控制器(Controller)可以被用于修改模拟过程中的原子坐标和原子速度等参量,从而达到控制系统特定参量的目的。例如控温器可以用于实现NVT系综,控压器可用于实现NPT系综。而在MindSponge分子动力学模拟框架下,控温控压都可以基于控制器Controller来实现。关于......
  • 2024-05-15:用go语言,考虑一个整数 k 和一个整数 x。 对于一个数字 num, 在其二进制表示
    2024-05-15:用go语言,考虑一个整数k和一个整数x。对于一个数字num,在其二进制表示中,从最低有效位开始,我们计算在x,2x,3x等位置处设定位的数量来确定其价值。举例说明,若对于x=1,num=13,则二进制表示为000001101,对应的价值为3。又如,当x=2,num=13,二进制表示依然为000001101,但对......
  • js防抖和限流函数
    functiondebounce(fn,delay){lettimer;lettht=this;returnfunction(...args){clearTimeout(timer)console.log(...args)timer=setTimeout(()=>{fn.apply(tht,args)},delay)}}function......
  • 【2024-05-14】学习调整
    20:00这几天你一直对我板着脸。你大概觉得,我应该问问你,是哪只蚊子叮咬了你。                                                 ——约翰·沃尔夫冈·冯·歌德今天部门......
  • .NET周刊【5月第2期 2024-05-12】
    国内文章C#在工业数字孪生中的开发路线实践https://mp.weixin.qq.com/s/b_Pjt2oii0Xa_sZp_9wYWg这篇文章探讨了C#在工业数字孪生技术中的应用,介绍了三种基于C#的数字孪生系统实现方案:WPF+Unity:结合WPF技术和Unity引擎,实现客户端三维应用,提供直观的生产场景展示。前端+.N......
  • 20240514打卡
    第十二周第一天第二天第三天第四天第五天第六天第七天所花时间1h0h代码量(行)1440博客量(篇)11知识点了解界面美化CSS,mdn官网学习团队趣味活动合作......
  • fastjson和 gson 的反序列化的一个差异
     publicclassResponse01{privateThirdDatathirdData;publicThirdDatagetThirdData(){returnthirdData;}//ThirdDataextendBaseThirdDatapublicvoidsetThirdData(BaseThirdDatathirdData){thi......
  • 2024/05/14
    目前市场上没有增量资金,存量资金博弈阶段,所以人工智能板块要想起来需要老题材的终结低空经济 有色金属 化工 合成生物 电力等题材依次起来,目前在炒电力。下一个板块会是谁呢,是之前的老题材重新炒作还是人工智能呢,这需要看市场的选择,等市场选出来,我们跟随就可以了,现阶段我......
  • 【2024-05-13】下一挑战
    20:00世界越来越美了,我独自一人,却很自在。我别无所求,只想被阳光晒透。                                                 ——黑塞今天一大早就起床外出了,去出差见一个......
  • .NET周刊【5月第1期 2024-05-05】
    国内文章一个开源轻量级的C#代码格式化工具(支持VS和VSCode)https://www.cnblogs.com/Can-daydayup/p/18164905CSharpier是一个开源、免费的C#代码格式化工具,特点是轻量级且依赖Roslyn引擎重构代码格式。支持的IDE包括VisualStudio(2019与2022)和VisualStudioCode等。该项......