【Django drf】 序列化类常用字段类和字段参数 定制序列化字段的两种方式 关系表外键字段的反序列化保存 序列化类继承ModelSerializer 反序列化数据校验源码分析

目录
  • 序列化类常用字段类和字段参数
    • 常用字段类
    • 常用字段参数
      • 选项参数
      • 通用参数
  • 序列化类高级用法之source
    • source填写类中字段
    • source填写模型类中方法
    • source支持跨表查询
  • 定制序列化字段的两种方式
    • 准备工作
    • 方法一:使用SerializerMethodField
    • 方法二:在模型类中写方法
  • 关系表外键字段的反序列化保存
    • 前端提交的数据
    • 序列化类添加字段
    • 重写create方法
  • 序列化类继承ModelSerializer
    • Meta类
    • 自定义序列化字段
      • 方法一:使用serializerMethodField
      • 方法二:在模型类中写方法
    • ModelSerializer使用总结
  • 反序列化之数据校验
    • 字段自己的校验规则
    • 钩子函数
  • 反序列化数据校验源码分析(了解)
    • 查看源码的设置
    • 断言assert
  • 练习

序列化类常用字段类和字段参数

常用字段类

# BooleanField	
BooleanField()
# NullBooleanField	
NullBooleanField()
# CharField	
CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
# EmailField	
EmailField(max_length=None, min_length=None, allow_blank=False)
# RegexField	
RegexField(regex, max_length=None, min_length=None, allow_blank=False)
# SlugField	
SlugField(maxlength=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+
# URLField	
URLField(max_length=200, min_length=None, allow_blank=False)
# UUIDField	
UUIDField(format=’hex_verbose’) 
format: 
1)'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 
2)'hex' 如 "5ce0e9a55ffa654bcee01238041fb31a" 
3)'int' 如: "123456789012312313134124512351145145114" 
4)'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
# IPAddressField	
IPAddressField(protocol=’both’, unpack_ipv4=False, **options)
# IntegerField	
IntegerField(max_value=None, min_value=None)
# FloatField	
FloatField(max_value=None, min_value=None)
# DecimalField	
DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) 
max_digits: 最多位数 decimal_palces: 小数点位置
# DateTimeField	
DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
# DateField	
DateField(format=api_settings.DATE_FORMAT, input_formats=None)
# TimeField	
TimeField(format=api_settings.TIME_FORMAT, input_formats=None)
# DurationField	
DurationField()
# ChoiceField	
ChoiceField(choices) choices与Django的用法相同
# MultipleChoiceField	
MultipleChoiceField(choices)
# FileField	
FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
# ImageField	
ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)

---------记住以下几个-----------
CharField
BooleanField
IntegerField
DecimalField

'''序列化类的额外字段'''
# ListField
ListField(child=,min_length=None,max_length=None)
当hobby下有多个数据时,序列化之后返回的数据格式hobby的部分用列表 ---> ['篮球','足球'] 存储。
{name:'lqz',age:19,hobby:['篮球','足球']}

# DictField
DictField(child=)
序列化之后,使用字典 ---> {'name':'刘亦菲','age':33}。
{name:'lqz',age:19,wife:{'name':'刘亦菲','age':33}}

常用字段参数

选项参数

# 选项参数
给某一些指定的字段使用的参数(不是每个字段都能使用这些参数)


# 给CharField字段类使用的参数
参数名称		    作用
max_length	    最大长度
min_lenght	    最小长度
allow_blank	    是否允许为空
trim_whitespace	    是否截断空白字符


# 给IntegerField字段类使用的参数
max_value	    最小值
min_value	    最大值

通用参数

# 通用参数:放在哪个字段类上都可以的
参数名称			作用
required	  	表明该字段在反序列化时必须输入,默认True
default	   	 	反序列化时使用的默认值(字段如果没传,就是默认值)
allow_null	   	表明该字段是否允许传入None,默认False
validators	   	该字段使用的验证器【不需要了解】
error_messages		包含错误编号与错误信息的字典
label		       	用于HTML展示API页面时,显示的字段名称
help_text	   	用于HTML展示API页面时,显示的字段帮助提示信息

# 重点
read_only		表明该字段仅用于序列化输出,默认False
			    (从数据库拿出来,给前端)
write_only		表明该字段仅用于反序列化输入,默认False
			(前端往后端传入数据)
   
# 如何理解这里的read\write
站在程序的角度:
从数据库拿数据(序列化) 			--->  读
从前端获取数据,写入数据库(反序列化)	--->  写

上述参数用于反序列化校验数据(类似form组件):
image-20230118202038684

validators参数(了解):
image-20230118203941220
给validators传入一个列表,列表中存放函数的内存地址。用这些函数来进行数据校验。

总结:

# 校验流程:
字段参数限制(max_length) ---> validators函数校验 ---> 局部钩子 ---> 全局钩子

# 有钩子函数,为什么要使用validators?
钩子函数只能在当前类生效,而validators的校验函数,可以在多个类生效,无需写重复的代码

序列化类高级用法之source

source用于修改序列化字段的名字。

# 获取所有图书接口 使用APIView+Response+序列化类

# 需求:name字段在前端显示的时候叫book_name
-使用source,字段参数,可以指定序列化表中得哪个字段
    	book_name = serializers.CharField(max_length=8, min_length=3,source='name')
-source指定的可以是字段,也可以是方法,用于重命名
-source可以做跨表查询

source参数可以填写三个东西。

source填写类中字段

视图类:
image-20230118205015484

序列化类:
image-20230118205114733

序列化类中字段和model类中的字段需要一一对应:

image-20230118205212702

可以使用source指定一个model类中字段,表示序列化这个字段。
当序列化类中字段变量名与source参数值相同时,此时会报错:
image-20230118205534680

source填写模型类中方法

model类中写函数:
image-20230118205810508

可以使用source指向模型类中的方法,方法的返回值会被序列化。

image-20230118210033114
序列化某个方法。

source支持跨表查询

image-20230118210320315

如果这里的publish是一对多外键字段,该外键在图书类。可以通过publish.name跳转到出版社,序列化出版社的名字。

代码:

class BookSerializer(serializers.Serializer):
    name_detail = serializers.CharField(max_length=8, min_length=3,source='name')
    # 或
    publish_name = serializers.CharField(max_length=8, min_length=3,source='publish.name')
    # 或
    xx = serializers.CharField(max_length=8, min_length=3,source='xx') #source的xx表示表模型中得方法
      

定制序列化字段的两种方式

准备工作

表创建:

from django.db import models

class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField(null=True)

    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
    authors = models.ManyToManyField(to='Author')

    def __str__(self):
        return self.name

    # 写了个方法,可以包装成数据属性,也可以不包
    def publish_de(self):
        return {'name': self.publish.name, 'city': self.publish.city, 'email': self.publish.email}

    def author_li(self):
        res_list = []
        for author in self.authors.all():
            res_list.append({'id': author.id, 'name': author.name, 'age': author.age})
        return res_list

class 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.name

class 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()
    # def __str__(self):
    #     return self.name

publish是外键字段。
image-20230118215642586

如果这里写CharField,那么前端得到的序列化结果是什么?

可见结果是字符串:
image-20230118220156829

这是因为我们写了__str__:
image-20230118220254669

如果我们将__str__注释掉,前端将会得到:

image-20230118220341609

如果我们不在模型类中写__str__,则需要使用source跨表查询:
image-20230118220453264

无论是__str__,还是source参数,都只能给前端返回出版社的某一个属性(名称|城市|邮箱)。

而我们希望返回一个字典对象,可以包含出版社的所有信息,如下:

# 前端显示形式
{
        "name": "西游记",
        "price": 33,
        "publish": {name:xx,city:xxx,email:sss}
}

实现该需求(定制序列化)有以下两种方法。

方法一:使用SerializerMethodField

# 第一种:在【序列化类】中写SerializerMethodField
    publish = serializers.SerializerMethodField()
    def get_publish(self, obj):
        # obj 是当前序列化的对象
        return {'name': obj.publish.name, 'city': obj.publish.city, 'email': obj.publish.email}

这里我们不使用CharField,因为CharField是用于序列化字符串形式,而我们是想要序列化对象形式的数据。

使用SerializerMethodField:
image-20230118221424257
需要配合一个方法使用,这个方法的返回值是什么,前端接收的publish就是什么。
image-20230118221448891

get_publish方法需要传入一个参数obj,这个obj是当前序列化的对象:

image-20230118222110745
通过book对象进行跨表查询,获取出版社的各个字段数据。
image-20230118222921389
出版社对象是用字典。(一个出版社对应一个字典)(由于一本书只有一个出版社,所以使用字典)

更多示例:

image-20230118222657629

由于一本书可以有多个作者,所以我们返回一个列表,列表中是一个个作者对象。
image-20230118223308508

方法二:在模型类中写方法

# 第二种:在【表模型】中写方法(又多一些)  
    def publish_detail(self):
        return {'name': self.publish.name, 'city': self.publish.city, 'email': self.publish.email}
    在序列化中取
    publish_detail=serializers.DictField()

    
# 在模型类中写逻辑代码,称之为ddd,领域驱动模型

也就是在表模型中写一个方法,与序列化类中的字段重名:
image-20230118223638524

总结:序列化类不仅仅能序列化模型类中某个字段,还能序列化模型类中的方法。这种方法和上面方法的实际区别就是,将同一段代码写在不同的位置,写在序列化类或者写在模型表。

这里如果我们序列化类使用charfield字段,会造成postman无法美化显示Json字典:
image-20230118224016474

这里是因为,我们模型类中方法返回的是一个字典,而CharField是用于序列化字符串,所以会直接将字典强行转化成字符串(如上图所示,该字典是用单引号引起来的,不是JSON格式)。

所以这里应该使用DictField:

image-20230118224434016

实现显示所有作者:

image-20230118225307485

在模型类中写函数,返回作者列表。

方式一代码演示:使用SerializerMethodField

class BookSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=8, min_length=3)
    price = serializers.IntegerField(min_value=10, max_value=99)
    publish_date = serializers.DateField()
    # publish要序列化成 {name:北京出版社,city:北京,email:2@qq.com}
    # 方式一:SerializerMethodField必须配合一个方法(get_字段名,需要接受一个参数),方法返回什么,这个字段就是什么
    publish = serializers.SerializerMethodField()
    def get_publish(self, obj):
        # obj 是当前序列化的对象
        return {'name': obj.publish.name, 'city': obj.publish.city, 'email': obj.publish.email}

    # 练习,用方式一,显示所有作者对象  []
    authors = serializers.SerializerMethodField()
    def get_authors(self, obj):
        res_list = []
        for author in obj.authors.all():
            res_list.append({'id': author.id, 'name': author.name, 'age': author.age})
        return res_list

方式二代码演示:在表模型中写(用的最多)

# 表模型中
class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField(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, 'email': self.publish.email}

    def author_list(self):
        res_list = []
        for author in self.authors.all():
            res_list.append({'id': author.id, 'name': author.name, 'age': author.age})
        return res_list
# 序列化类中
class BookSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=8, min_length=3)
    price = serializers.IntegerField(min_value=10, max_value=99)
    publish_date = serializers.DateField()

    # 方式二:在表模型中写方法
    publish_detail = serializers.DictField(read_only=True)
    # 练习,使用方式二实现,显示所有作者
    author_list = serializers.ListField(read_only=True)

在模型类中写逻辑代码的行为(逻辑不写在视图类中),称之为ddd(领域驱动模型)。
相关文章:
http://cloud.tencent.com/developer/article/1371115

关系表外键字段的反序列化保存

多表关联情况下的新增图书接口:(request.data接收前端发送的数据)
image-20230119004626267

我们要新增图书,除了上传普通字段,还要上传外键字段。
需要在前端上传出版社主键和作者列表(列表中是作者主键)。

注意:需要在序列化类中重写create方法。

前端提交的数据

前端提交常见问题:

image-20230119004923415

无法在新增图书的时候新增出版社,publish字段只能写出版社的主键。而作者和作者详情表可以一同新增。

前端的提交数据应该是这样的:

image-20230119005301074

前端示例:

image-20230119005352166

序列化类添加字段

实现反序列化需要在序列化类中添加新字段:

image-20230119010323192

这两个反序列化的字段,对应着模型类中的外键字段:

image-20230119010227557

添加write_only、read_only参数:
image-20230119010426447

如果不添加这些参数,则可能会出现一个字段既参与序列化,又参与反序列化的情况:
image-20230119104347047

查看前端接收到的序列化结果:

image-20230119104500512

这里是自动把序列化类中的字段全部都序列化了。
publish在数据库中没有对应的字段,所以这里展现给前端的是一个对象。

重写create方法

image-20230119010859490

当前我们实现反序列化还需要重写序列化类的create、updata的方法。

# 缺点
	1 在序列化中每个字段都要写,无论是序列化还是反序列化
    2 如果新增或者修改,在序列化类中都需要重写create或update
    
# 解决这个缺点,使用ModelSerializer来做

代码:

# 1 序列化字段和反序列化字段不一样  【序列化类中】
	# 反序列化用的
    publish = serializers.CharField(write_only=True)
    authors = serializers.ListField(write_only=True)
	#序列化用的
    publish_detail = serializers.DictField(read_only=True)
    author_list = serializers.ListField(read_only=True)
    
# 2 一定要重写create  【序列化类中】
	    def create(self, validated_data): 
            # validated_data 校验过后的数据  
              {"name":"三国1演义",
                "price":19,
                "publish_date": "2022-09-27",
                "publish":1,
                "authors":[1,2]
                }
            book = Book.objects.create(name=validated_data.get('name'),
                                       price=validated_data.get('price'),
                                       publish_date=validated_data.get('publish_date'),
                                       publish_id=validated_data.get('publish'),
                                       )
            authors = validated_data.get('authors')
            book.authors.add(*authors)
            return book

序列化类继承ModelSerializer

继承ModelSerializer:
image-20230119104755415
modelserializer是跟表有关联的。

Meta类

在BookmodelSerializer中写一个Meta类:
image-20230119104918220

model=Book: 指定序列化的是哪个模型类
fields='__all__': 指定序列化哪些字段,双下all表示序列化模型类所有字段。

修改视图层,使用ModelSerializer:
image-20230119105246447

查看结果:
image-20230119105421588

可以发现把publish、authors的序列化结果是主键值,而我们希望能获取出版社对象和作者对象,所以需要自己定制如何序列化。

自定义序列化字段

方法一:使用serializerMethodField

image-20230119110216828
修改Meta类的fields:
image-20230119110636376

在fields列表里填写,我们serializermethodfield产生的字段

添加read_only:
image-20230119110929207
给authors和publish添加write_only属性:
image-20230119111251961

在Meta类写extra_kwargs。你在字典里写的键值对,会当做字段参数传入字段类。

代码:

class BookModelSerializer(serializers.ModelSerializer): #ModelSerializer继承Serializer
    # 不需要写字段了,字段从表模型映射过来
    class Meta:
        model = Book  # 要序列化的表模型
        # fields='__all__' # 所有字段都序列化
        fields = ['name', 'price', 'publish_date', 'publish', 'authors', 'publish_detail',
                  'author_list']  # 列表中有什么,就是序列化哪个字段
        # 给authors和publish加write_only属性
        # name加max_len属性
        extra_kwargs = {
            'name': {'max_length': 8},
            'publish': {'write_only': True},
            'authors': {'write_only': True},
        }  
   publish_detail = serializers.SerializerMethodField(read_only=True)
	 ...
   author_list = serializers.SerializerMethodField(read_only=True)
	...

刚刚我们是使用了自定义序列化的第一种方式:在序列化类中使用SerializerMethodField。

方法二:在模型类中写方法

Meta类中的fields列表支持写入以下几种:

  1. 模型类中的字段
  2. 模型类中的方法
  3. 序列化类中的字段(SerializerMethodField)

在表模型内写方法:

image-20230119161054111

在field字段注册:
image-20230119161140674

在field字段注册模型类中的方法时,就不存在添加参数read_only了,因为这两个方法没有对应的字段。如果是方法一,则可以给SerializerMethodField字段添加参数。

ModelSerializer使用总结

#  如何使用
1 定义一个类继承ModelSerializer
2 类内部写内部内 class Meta:
3 在内部类中指定model
		填写要序列化的表
4 在内部类中指定fields
		写要序列化的字段,写__all__表示所有,__all__不包含方法,如果要包含方法必须要在列表中写一个个字段。
		示例:['字段1','字段2'...]
5 在内部类中指定extra_kwargs,给字段添加字段参数的
		因为有些字段是从模型类映射过来的,在序列化类中没有这个字段,所以需要使用extra_kwargs添加字段参数。
6 在序列化类中,可以重写某个字段,优先使用你重写的
        name = serializers.SerializerMethodField()
    	def get_name(self, obj):
        	return 'sb---' + obj.name
 
7 以后不需要重写create和update了
    	-ModelSerializer写好了,兼容性更好,任意表都可以直接存(考虑了外键关联)
    	-当有特殊需求的情况下,也可以重写

在序列化类中,可以重写某个字段,优先使用你重写的:

image-20230119155643559

这里我们在序列化类中,将name字段写了两次,此时会优先用上面的。
正常情况下会直接输出书名,我们进行重写,可以给查询到的结果做一些操作再输出给前端。
也就是说:即可以在fields里面注册某个字段,也可以手动重写字段。

查看效果:
image-20230119160044742

反序列化之数据校验

反序列化的数据校验和forms组件很像。既有字段自己的校验规则,也有局部钩子、全局钩子。

字段自己的校验规则

# 字段自己的校验规则
-如果继承的是Serializer	
    因为序列化类中有字段,所以可以直接添加字段参数。

    name=serializers.CharField(max_length=8,min_length=3,error_messages={'min_length': "太短了"})

    
-如果继承的是ModelSerializer,有两种方式:
	1. 在Meta类上面重写字段
	2. 使用Meta类extra_kwargs给字段添加字段参数

    extra_kwargs = {
    'name': {'max_length': 8, 'min_length': 3}, 'error_messages': {'min_length': "太短了"},
    }        

    注意:只能添加模型类字段包含的字段参数。	

钩子函数

# 局部钩子
    -如果继承的是Serializer,写法一样
    -如果继承的是ModelSerializer,写法一样
    
	def validate_name(self, name):
        if name.startswith('sb'):
            # 校验不通过,抛异常
            raise ValidationError('不能以sb卡头')
        else:
            return name
    注意:局部钩子不要写在Meta类中。

        
# 全局钩子
	-如果继承的是Serializer,写法一样
    -如果继承的是ModelSerializer,写法一样
	def validate(self, attrs):
        if attrs.get('name') == attrs.get('publish_date'):
            raise ValidationError('名字不能等于日期')
        else:
            return attrs
        
 '''当以上校验全部通过,序列化类的is_valid才会通过'''

局部钩子:
image-20230119164156094

form组件局部钩子函数示例: clean_name
反序列化校验局部钩子示例:validate_name
二者只是有名字上的区别。

反序列化数据校验源码分析(了解)

# 校验顺序
先校验字段自己的规则(最大,最小),走局部钩子校验,走全局钩子

# 疑问
局部钩子:validate_name,全局钩子:validate 
为什么钩子函数必须这样命名?

# 入口
从哪开始看源码,哪个操作执行了字段校验 ---> ser.is_valid()

# 序列化类的继承顺序
你自己写的序列化类 ---> 继承了ModelSerializer ---> 继承了Serializer ---> BaseSerializer ---> Field
'''一直往上查找is_valid,发现在BaseSerializer里有,如下只挑选is_valid最关键的代码'''


1. BaseSerializer内的is_valid()方法

	    def is_valid(self, *, raise_exception=False):
            '''省略'''
            # 如果没有进行校验,对象中就没有_validated_data
            if not hasattr(self, '_validated_data'):
                try:
                    # 真正进行校验的代码,如果校验成功,返回校验过后的数据 
                    self._validated_data = self.run_validation(self.initial_data) 
			       # 这里的self.run_validation运行的是Serializer类的,而不是Field类的。
                except ValidationError as exc:
            return not bool(self._errors)
    
说明:self.run_validation(self.initial_data)这行代码执行的是Serializer的run_validation
    	-补充说明:如果你按住ctrl键,鼠标点击,会从当前类中找run_validation,找不到会去父类找
    	-这不是代码的执行,代码执行要从头开始找,从自己身上再往上找(对象方法的查找顺序)
        
        
2.查看Serializer中的run_validation:
        
    	    def run_validation(self, data=empty):
                # 局部钩子的执行
                value = self.to_internal_value(data)
                try:
                    # 全局钩子的执行,从根上开始找着执行,优先执行自己定义的序列化类中得全局钩子
                    value = self.validate(value)
                except (ValidationError, DjangoValidationError) as exc:  # 注意这里还能捕获django抛出的异常
                    raise ValidationError(detail=as_serializer_error(exc))

                return value
  -全局钩子看完了,局部钩子---》 self.to_internal_value---》从根上找----》本质执行的Serializer的

3.查看Serializer中的to_internal_value

     def to_internal_value(self, data):
        for field in fields: # fields:序列化类中所有的字段,for循环每次取一个字段对象
            # 反射:去self:序列化类的对象中,反射 validate_字段名 的方法
            validate_method = getattr(self, 'validate_' + field.field_name, None)
            # field.field_name 获取字段对象的字段名称(字符串)
            try:
                # 这句话是字段自己的校验规则(最大最小长度),执行的是field的run_validation
                validated_value = field.run_validation(primitive_value)
                # 局部钩子
                if validate_method is not None:
                    validated_value = validate_method(validated_value)  # 局部钩子运行
            except ValidationError as exc:
                errors[field.field_name] = exc.detail

        return ret
    
字段对象是什么:	name=serializers.CharField(max_length=8,min_length=3,error_messages={'min_length': "太短了"})	
这里的name就是一个字段对象。具体可以研究OMR怎么实现关系表映射。


查看源码的设置

image-20230119170638082

添加这个设置可以进行前进、回退等操作。

断言assert

# 框架的源码中,大量使用断言

# assert :断言,作用的判断,断定一个变量必须是xx,如果不是就报错

# 土鳖写法
# name = 'lqz1'
# if not name == 'lqz':
#     raise Exception('name不等于lqz')
#
# print('程序执行完了')

# assert的断言写法
name = 'lqz1'
assert name == 'lqz', 'name不等于lqz'
print('程序执行完了')

练习

#1  写出book表(带关联关系)5 个接口 
	Serializer
    ModelSerializer(简单,不用重写create和update)
    name最大8,最小3,名字中不能带sb
    price最小9,最大199,不能为66
   
#2  出版社,作者,作者详情  5个接口写完(ModelSerializer好些一些)
本文转载于网络 如有侵权请联系删除

相关文章

  • 鱼与熊掌可以兼得,腾讯云推出COS on CDC对象存储服务

    01前言在云计算时代,各个企业的信息基础设施都在进行云化转型,一时间,似乎万物皆可上云。但是在上云过程中,有不少客户遇到过这样的问题:有部分数据出于合规需求,需要在本地存储与处理,怎么办?一些数据需要本地高速访问,跟公有云之间的延迟太高了,怎么办?使用私有化方式部署,需要专门的团队来采购、管理、运维,无法享受上云的便利性,怎么办?现在,这些问题统统都能得到解决。腾讯云存储产品中心推出了面向边缘计算的对象存储产品:本地专有集群(CDC,CloudDedicatedCluster)对象存储(以下简称COSonCDC),这款产品既可以满足云化转型过程中,对于数据本地访问的诉求,又可以让客户享受到业务上云的便利性,可谓鱼与熊掌可以兼得。02本地全托管的集群与一般的私有化部署产品不同,腾讯云CDC是一款面向混合云场景的全托管的产品,腾讯云负责在客户自有的数据中心或者机房完成交付、部署,后续的管理、运维、升级等所有工作也由腾讯云负责,客户只需要关注要使用的云服务即可。CDC目前包含了CVM、CBS、COS等常用的基础云服务产品,并且服务种类还在持续丰富中。CDC通过公网或专线就近接入腾讯公有云的地

  • DDD实现之路

    编者按:这篇文章最早撰写于2014年,作者也是《实现领域驱动设计》的译者。几年过去了,DDD在坊间依然方兴未艾,然而它的复杂性所引发的误解也层出不穷。对于一些基本概念的澄清甚至溯源,会帮助我们回到起点,对它展开新的认识。2004年,当EricEvans的那本《领域驱动设计——软件核心复杂性应对之道》(后文简称《领域驱动设计》)出版时,我还在念高中,接触到领域驱动设计(DDD)已经是8年后的事情了。那时,我正打算在软件开发之路上更进一步,经同事介绍,我开始接触DDD。我想,多数有经验的程序开发者都应该听说过DDD,并且尝试过将其应用在自己的项目中。不知你是否遇到过这样的场景:你创建了一个资源库(Repository),但一段时间之后发现这个资源库和传统的DAO越来越像了,你开始反思自己的实现方式是正确的吗?或者,你创建了一个聚合,然后发现这个聚合是如此的庞大,它为什么引用了如此多的对象,难道又是我做错了吗?其实你并不孤单,我相信多数同仁都曾遇到过相似的问题。前不久,我一个同事给我展示了他在2007年买的那本已经被他韦编三绝过的《领域驱动设计》,他告诉我,读过好几遍后,他依然不知道如何将D

  • 06 . Jenkins分布式构建和Pipline

    Pipline简介pipline是帮助Jenkins实现CI到CD转变的重要角色,是运行在jenkins2.X版本的核心插件,简单来 说Pipline就是一套运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连 接起来,实现单个任务难以完成的复杂发布流程,从而实现单个任务很难实现的复杂流程编排和任 务可视化,Pipeline的实现方式是一套GroovyDSL,任何发布流程都可以表述为一段Groovy脚本。 Pipline优势可持续性:jenkins的重启或者中断后不影响已经执行的PiplineJob 支持暂停:pipline可以选择停止并等待人工输入或批准后再继续执行。 可扩展:通过groovy的编程更容易的扩展插件。 并行执行:通过groovy脚本可以实现step,stage间的并行执行,和更复杂的相互依赖关系。 Pipline语法#Stage:阶段,一个pipline可以划分为若干个stage,每个stage都是一个操作, #比如clone代码、代码编译、代码测试和代码部署,阶段是一个逻辑分组,可以跨多个node执行。 #Node:节点,每个node都是一

  • ML社区八大「毒瘤」:盲目崇拜、相互攻讦、重SOTA轻实效……

    机器之心报道参与:杜伟、小舟在本文中,一名reddit用户对机器学习社区存在的「毒瘤」进行了总结,希望可以警醒人们,促使社区沿着健康的方向发展。俗话说,有人的地方就有江湖,就会充斥着各种立场和利益纠纷。科研领域亦如此,机器学习社区近来掀起来的一系列关于种族偏见的热议就是鲜活的例证。我们先回顾一下这件事情的来龙去脉:大约一周前,杜克大学提出了一种将高糊人脸照片转换成清晰面部图像的PULSE方法,但意外的是,研究中的一张生成图像掀起了众议,人们纷纷指责该方法存在种族偏见。输出后的奥巴马变成了「白人小伙」。之后,图灵奖得主、Facebook首席AI科学家YannLecun也因自己对此事的评价而遭到网友的口诛笔伐,最后不得不宣布退出推特。那么问题来了,此次事件是否反映了机器学习社区对技术或数据持有明显的偏向性态度呢?除此之外,机器学习社区还存在着哪些痼疾以及新出现的坏现象呢?今日,reddit用户yusuf-bengio发帖总结了当前机器学习社区存在的8大「毒瘤」,内容涉及同行评审、盲目学术崇拜、多样性、过度重视顶会论文发表以及学术攻讦等,引发了网友的热议。我们先来看下这些问题的具体内容。ML

  • 伪蒙特卡洛(Quasi-Monte Carlo, QMC)随机

    分享一道由群员“Melbourne”,外号“PaperMachine”,有数学小王子之称的小伙伴分享的题目! 特别说明:本文非原创,经投稿者同意后发表。01PART算法介绍期望:在概率论和统计学中,数学期望(mean)(或均值,亦简称期望)是试验中每次可能结果的概率乘以其结果的总和,是最基本的数学特征之一。它反映随机变量平均取值的大小。题目:在1*1的正方形中随机撒三个点,两两点都可构成长方形的一组对顶点,这样一共有三个长方形,需要求面积第二大的长方形的面积的期望。算法:每次随机三个点,计算第二大面积,最后统计期望。02PART蒙特卡洛蒙特卡罗法也称统计模拟法、统计试验法。是把概率现象作为研究对象的数值模拟方法。是按抽样调查法求取统计值来推定未知特性量的计算方法。蒙特卡罗是摩纳哥的著名赌城,该法为表明其随机抽样的本质而命名。故适用于对离散系统进行计算仿真试验。在计算仿真中,通过构造一个和系统性能相近似的概率模型,并在数字计算机上进行随机试验,可以模拟系统的随机特性。蒙特卡洛方法(MonteCarloMethod)指的是一类使用随机变量解决概率问题的方法。比较常见的是计算积分、计算概率、

  • 做一个爱老婆的好程序员

    大家好我是一个码农 我有一个漂亮的老婆很不幸 她是一名很有权威的产品经理秉承一个好男人就要爱老婆的原则 她不管在生活中还是工作中都是我的人生信条实不相瞒我还有一位灵魂伴侣如果通俗地称呼,可以叫她“键盘”这两位在我的生活中非常重要一位给我制造惊喜一位给我制造浪漫“惊喜”就比如说有一次当着老婆的面炒土豆丝“老公,换一个菜”“土豆要切的薄如蝉翼啊”“黄瓜要切的细如发丝”“豆腐要改花刀”“萝卜雕个花”“鸡汤要熬够12小时,待会晚饭我要喝”老婆我是个敲代码的而且离晚饭只有2小时了怎么给你熬够12小时“哎,老公” “你要听取用户的反馈啊”“交互的逻辑懂不懂”我做个土豆丝而已……“土豆丝有啥好的”“要做鸡汤”“你要有同理心场景化思考”“要是你把这个菜端上去给儿子”“他会喜欢吗”“把它想成一个产品”“为了鸡汤的潜在销量”“你要加油呀!”我……但家里没有鸡做不了鸡汤“这样啊”“那就换回土豆丝吧”“换回第一版”“我觉得第一版还挺好的”而键盘就不一样了她不会这么多要求在我改bug的时候随我敲打在我做需求的时候伴我加班在我玩游戏的时候回首掏鬼刀一开看不见走位走位哟难受关键是键盘还可以随意更换漂亮的老婆同事会特

  • jsch实现与服务器完成文件相关操作

    以前为了实现文件上传服务器的功能,于是在晚上搜了下,发现可以通过jsch来实现,同时发现jsch还是与服务器间通过一些命令完成其他操作,觉得不可思议,但是当时也没有过多的了解。而这次需要完成从从服务器下拉文件,开始想到用ftp完成,但是发现借助客户端不是太好实现,或者确实不太了解这方面的知识,想到以前用过jsch,既然能够完成文件的上传,那么是否同样能够完成文件的下载呢?当然在使用前还是会先查阅一番,如果确实可以实现,当然就会深入去了解,看了一些博客,在https://www.cnblogs.com/weiyi1314/p/9517245.html中写道可以通过put实现文件上传;get实现文件下载。建立连接:publicvoidconnect(){ try{ JSchjsch=newJSch(); jsch.getSession(config.getUsername(),config.getHost(),config.getPort()); sshSession=jsch.getSession(config.getUsername(),config.getHost(),config.

  • Bytom DAPP 开发流程

    从目前已经发布的DAPP来看,DAPP架构大致可以分成3种类型:插件钱包模式、全节点钱包模式和兼容模式。插件钱包模式是借助封装了钱包的浏览器插件通过RPC协议与区块链节点通信,插件在运行时会将Web3框架注入到DAPP前端页面中,然后DApp通过Web3来与区块链节点通信。全节点钱包模式需要项目方同步并持有一个区块链节点,并对外提供一个浏览器环境与用户进行交互。兼容模式可以在插件钱包和全节点钱包下同时使用,即上述两种方式可以自由切换,安全性能相对较高。接下来介绍的比原链DAPP的架构模式跟账户模型DAPP的插件钱包模式有些相似,都是由DAPP前端、插件钱包和合约程序共同组成,其中插件钱包需要连接去中心化的区块链服务器blockcenter,该服务器主要是为了管理插件钱包的相关信息。此外,比原链是UTXO模型的区块链系统,合约程序存在于无状态的UTXO中,如果要实现这样一个具体的DAPP,就需要在前端和后端多做一些逻辑的处理。1.编写、编译并实例化智能合约编写智能合约比原链的虚拟机是图灵完备的,理论上可以实现任意图灵计算机能实现的操作。而Equity作为比原链的智能合约语言,使用Equi

  • 区块链时代的技术福音——生态令(ECOL)

    区块链时代的技术福音——生态令(ECOL)区块链时代的风口虽已拉开,但是就其技术的成熟度、落地效用来说,人们对其实体落地场景仍是存有疑虑,并且一度成为区块链继续前行的阻力。不可否认,区块链自2017年拉开序幕后,在2018年呈直线上升式发展,各行各业都开始构建区块链领域的福地,技术开发、人才培训等更是层出不穷。有人说区块链的蛋糕已经瓜分地差不多了,但是实际上这只是一个开端。在众多机构的加持下,区块链行业布局雏形已成,这给区块链布局提供了行业氛围以及众多借鉴。然而各大集团的布局大多都是从单个领域切入,在全面性、广泛性方面略有瑕疵。链圈虽说前景巨大,但是目前因技术不成熟,各行各业的区块链布局仍处于概念性阶段,难以有实质性行动。尽管区块链融密码学、分布式存储等多项技术于一身,但它本身仍有漏洞,尤其是在现今技术还尚未成熟的情况下,极易和网络参与主体责任划分、账本数据最终归属、成本偏高、交易区块具有选择性等问题一起导致区块链技术落地应用时会面临较大风险。那么生态令(ECOL)又是如何在区块链进入到3.0时代后,利用技术规避区块链技术先存在的漏洞,应对其给实体应用带来的挑战,又将如何在实体应用场景

  • 砍人、切水果两不误!《Virtual Ninja VR》现已登陆Steam

    上周,一款忍者题材的VR游戏《VirtualNinjaVR》已经登陆Steam平台。游戏中,你将使用手里剑和武士刀,击退一波波的敌人。 《VirtualNinjaVR》是一款街机类型的游戏,玩家可以在游戏里享受用剑砍翻一群怪物的快感,同时可以用手里剑从远处发起攻击。《VirtualNinjaVR》是一款入门级游戏,可帮助玩家更好的了解VR游戏。它也是一款内容丰富的游戏,可以让玩家沉浸在体验中,感受杀死敌人的乐趣。目前,玩家可以体验《VirtualNinjaVR》的街机模式,敌人是无穷无尽的,游戏的难度会随时间不断增加。此外还有单人模式,包括五个不同的关卡,游戏最后将有一场boss战。最后游戏还有一种合作模式,可以让两名玩家一起组队,共同打败巨大的boss怪物。另外,《VirtualNinjaVR》的最终版本将包括更多怪物、模式、地图以及boss怪物,同时也会添加PVP模式以及更多合作游戏模式。该游戏的抢先体验版会持续几个月,虽然详细的日程表尚未发布,但抢先体验版也会进行一些内容更新。对于所有玩家来说,在VR世界中用剑战斗,都是一种有趣的体验。并且对比那些难度较高的VR游戏,《Virtu

  • 单因子测试框架

    SignalFactorAnalyse单因子测试框架哪些因子可以为组合提供超额收益?这是构建多因子模型的第一步,也是最关键一步。特征选择非常关键,只有把握关键特征才能对数据达到重要性认识,选择好的因子,才能获取超额收益率。对于传统交易经验、金融理论、微观市场、机器学习、深度学习等不断挖掘出来的巨量待验因子,一个快速且有效的因子测试框架,将是Multi-factor策略系统中最为关键的一环。因子模型测试思路因子有效性的判断与筛选:•备选因子确定:数学意义、经济意义、统计意义•预处理:数据空缺与错误、剔除异常值、ZScore等•非参数分析:分组回测•参数分析:信息系数IC分析、回归分析测试背景:1.一个有效的因子在逻辑上与收益率一定是有着经济意义上的联系,这也是检验因子有直接最初始的手段。本框架在此基础上对因子进行实证分析,目的是筛选掉与收益率相关性不高的因子,从而得到真正有效的因子池。2.因子有效性、因子衰减周期、因子轮动。因子模型本质上是通过因子来解释股票收益率,衡量因子有效性的指标是信息比。因子衰减周期,一些研究报告也做了诸如此类的研究,提出了因子的半衰期。半衰期是指因子IC_IR下

  • Markdown语法及常用操作

    一、标题   1.通过前面输入 # 来确定标题,最多支持6级表题。     ######六级标题    #####五级标题    ####四级标题    ###三级标题    ##二级标题    #一级标题    普通正文    2.通过输入=或者-,来确定标题,最多支持二级标题 我是一级标题 === 我是二级标题 --      注意:字体下面只输入一个符号即可,数量不限   二、斜体和粗体 *斜体*    _斜体_       #斜体:字体前后各加一个*或者一个_ **粗体**   __粗体__      #粗体:字体前后各加两个*或者两个_ ***粗斜体***   ___斜粗体___  #粗斜体:字体前后各加三个*或者三个_ ~~删除线~~     

  • 资源 | 数十种TensorFlow实现案例汇集:代码+笔记

      选自Github 机器之心编译 参与:吴攀、李亚洲 这是使用TensorFlow实现流行的机器学习算法的教程汇集。本汇集的目标是让读者可以轻松通过案例深入TensorFlow。 这些案例适合那些想要清晰简明的TensorFlow实现案例的初学者。本教程还包含了笔记和带有注解的代码。 项目地址:https://github.com/aymericdamien/TensorFlow-Examples 教程索引 0-先决条件 机器学习入门: 笔记:https://github.com/aymericdamien/TensorFlow-Examples/blob/master/notebooks/0_Prerequisite/ml_introduction.ipynb MNIST数据集入门 笔记:https://github.com/aymericdamien/TensorFlow-Examples/blob/master/notebooks/0_Prerequisite/mnist_dataset_intro.ipynb 1-入门 HelloWorl

  • sersync2 填坑记录

    <?xmlversion="1.0"encoding="ISO-8859-1"?> <headversion="2.5">     <hosthostip="localhost"port="8008"></host>     <debugstart="false"/>     <fileSystemxfs="true"/>     <filterstart="true">         <excludeexpression="(.*)\.svn"></exclude>         <excludeexpression="(.*)\.gz"><

  • pip下载时使用国内镜像 设置pip.ini文件

    https://blog.csdn.net/u011107575/article/details/109901086 https://www.python.org/ftp/python/https://registry.npmmirror.com/binary.html https://mirrors.tuna.tsinghua.edu.cn/help/pypi/ pypi镜像使用帮助 pypi镜像每5分钟同步一次。 临时使用 pipinstall-ihttps://pypi.tuna.tsinghua.edu.cn/simplesome-package 复制 注意,simple 不能少,是 https 而不是 http 设为默认 升级pip到最新的版本(>=10.0.0)后进行配置: pipinstallpip-U pipconfigsetglobal.index-urlhttps://pypi.tuna.tsinghua.edu.cn/simple 复制 如果您到pip默认源的网络连接较差,临时使用本镜像站来升级pip:

  • [原创]Zynq SDIO WIFI SotfAP调试

    编译好kernel和driver 加载firmware后,运行下述命令。 mkdir/var/run/ mkdir/var/run/hostapd  ifconfig-a                  ifconfigwlan0up               ifconfigwlan0193.168.8.1  hostapd/etc/hostapd_cfg.conf&  通过手机可扫描到zynq平台发出的WIFI信号   目前DHCP还没弄好,可先用静态的方式获取IPaddress,连接好后,可在CRT终端进行ping操作   原创文章版权©2021FPGATopic 欢迎转载注明出处 交流邮箱:cx_info

  • 练习:输入二叉树结构,输出中序遍历--C语言

    #include<stdio.h> #include<stdio.h> #defineMaxNameLen100 typedefstructTreeNode{ char*name; StructTreeNode*left_child; StructTreeNode*right_child; }TreeNode; TreeNode*NewTreeNode(constchar*name){ TreeNode*node=NULL; node=(TreeNode*)malloc(sizeof(TreeNode)); memset(node,0,sizeof(TreeNode)); node->name=strdup(name); returnnode } voidFreeTreenode(TreeNode*node){ if(node->name)free(node->name); if(node->left_child)FreeTreeNode(node->left_child); if(node->right_child)Fr

  • 2519的blog

    异或是不进位的加法,即\(axorb\lea+b\) 所以把所有数字异或起来就好 mycode: #include<bits/stdc++.h> #definerep(i,j,k)for(registerinti(j);i<=k;++i) #definedrp(i,j,k)for(registerinti(j);i>=k;--i) usingnamespacestd; typedeflonglonglxl; template<typenameT> inlineTmax(T&a,T&b){ returna>b?a:b; } template<typenameT> inlineTmin(T&a,T&b){ returna<b?a:b; } inlinechargt(){ staticcharbuf[1<<21],*p1=buf,*p2=buf; returnp1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p

  • java复习路4【寻找脑子中。。。】

         

  • PyQt5 学习笔记

    我用的PyQt5教学连接:https://blog.csdn.net/La_vie_est_belle/article/list/3 教程写得简明易懂,推荐看一下    遇到的问题:   TypeError:argument1hasunexpectedtype'NoneType'   解决办法:   将clicked所关联的槽函数使用lambde定义如下:  原因不明。。。      

  • docker

    第1章docker的概述 1.1什么是docker 1.Docker是Docker.Inc公司开源的一个基于LXC技术之上构建的Container容器引擎,源代码托管在GitHub上,基于Go语言并遵从Apache2.0协议开源。 2.Docker是通过内核虚拟化技术(namespaces及cgroups等)来提供容器的资源隔离与安全保障等.由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机(VM)额外的操作系统开销,提高资源利用率 复制 1.2docker的组成部分 1.docker是传统的CS架构分为dockerclient和dockerserver 2.Docker客户端是Docker用户与Docker交互的主要方式,当您使用Docker命令行运行命令时,Docker客户端将这些命令发送给服务器端,服务端将执行这些命令。 3.Docker命令使用DockerAPI,Docker客户端可以与多个服务端进行通信 复制 1.3docker概念的引入 如上图所示,一个宿主机上运行了多个容器,多个容器带来的一下问题怎么解决 1.怎么样保证不同的

相关推荐

推荐阅读