【django】Django REST Framework 序列化与反序列化详解
目录
1、什么是序列化和反序列化?
2、Django REST Framework中的序列化和反序列化
3、安装与配置(第10章是从零开始)
3.1 安装
3.2 配置
4、基本使用
4.1 创建序列化器
4.2 使用序列化器(将数据序列化返回给前端)
4.3 配置url
4.4 测试
4.5 反序列化(从前端获取数据反序列化)
4.5.1 url配置
4.5.2 测试
4.6 数据验证(将4.1的序列化设置验证方式多样化)
5、一对多模型序列化
5.1 模型定义
5.2 序列化器定义
5.3 使用序列化器
5.4 url配置
5.5 测试
6、多对多关系
6.1 模型定义
6.2 序列化器定义
6.3 使用序列化器
6.4 url配置
6.5 测试
7、自定义字段
7.1 模型定义
7.2 序列化器定义
7.3 使用序列化器
7.4 配置url
7.5 测试
7.6 使用depth优化序列化器
8、来个多表级联
8.1 模型定义
8.2 序列化器定义
8.3 使用序列化器
8.4 配置URL
8.5 测试
9、总结
10、前期工作
10.1 创建django项目
10.2 安装库
10.3 配置
10.3.1 创建mysql数据库drf
10.3.2 配置mysql数据
10.3.3 settings配置
10.3.4 apps.py
10.3.5 DRFDemo的urls配置
10.3.6 drf的urls配置
10.3.7 新建库表之后操作(非必须)
10.4 同步数据库
10.5 创建超级用户
10.6 启动服务
10.7 访问
10.7.1 后端管理页面
10.7.2 默认页面
前言:Django REST Framework 序列化与反序列化详解,包含一对一,一对多,多对多的关系。
在当今的Web开发中,前后端分离已经成为一种趋势。在这种模式下,后端主要负责数据处理和业务逻辑,而前端则专注于用户界面和交互。为了有效地在前后端之间传输数据,通常使用JSON这种轻量级的数据交换格式。Django REST Framework(DRF)作为一个强大的Django扩展,提供了便捷的REST API开发框架,其中的序列化和反序列化功能正是实现这一传输的关键。
1、什么是序列化和反序列化?
- 序列化:将Python对象转换为JSON或其他文本格式,以便通过HTTP进行传输。
- 反序列化:将JSON数据转换回Python对象,以便在后端进行处理。
2、Django REST Framework中的序列化和反序列化
DRF通过序列化器(Serializer)来实现这一功能。序列化器不仅负责数据的转换,还提供了数据验证和渲染的功能。
3、安装与配置(第10章是从零开始)
3.1 安装
首先,你需要安装Django REST Framework:
pip install djangorestframework
3.2 配置
然后,在你的settings.py
文件中,将rest_framework
添加到INSTALLED_APPS
中:
INSTALLED_APPS = [ ... 'rest_framework', ...
]
4、基本使用
4.1 创建序列化器
序列化器通常定义在应用程序下的serializers.py
文件中。你可以通过继承serializers.Serializer
或serializers.ModelSerializer
来创建自定义序列化器。
例如,假设你有一个Book
模型:
from django.db import models class Book(models.Model): title = models.CharField(max_length=100) author = models.CharField(max_length=50) publication_date = models.DateField()class Meta:managed = Truedb_table = 'book'verbose_name_plural = '书籍表'
你可以创建一个对应的序列化器:
from rest_framework import serializers
from .models import Book class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__' # 或者指定需要序列化的字段,如 ['title', 'author', 'publication_date']
4.2 使用序列化器(将数据序列化返回给前端)
在视图中,你可以通过实例化序列化器对象,并将要序列化的数据传递给instance
参数(对于单个对象)或many=True
(对于多个对象)来进行序列化。
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Book
from .serializers import BookSerializer class BookListView(APIView): def get(self, request, *args, **kwargs): books = Book.objects.all() serializer = BookSerializer(books, many=True) return Response(serializer.data)
4.3 配置url
urlpatterns = [# path('', views.index, name='index'), # 定义一个根路由,指向 index 视图# 你可以在这里添加更多的路由path('books/', BookListView.as_view(), name='book-list'),
]
4.4 测试
返回数据
[{"id": 1,"title": "西游记","author": "吴承恩","publication_date": "2024-10-29"},{"id": 2,"title": "红楼梦","author": "曹雪芹","publication_date": "2024-10-30"},{"id": 3,"title": "水浒传","author": "施耐庵","publication_date": "2024-10-07"},{"id": 4,"title": "三国演义","author": "罗贯中","publication_date": "2024-10-11"}
]
4.5 反序列化(从前端获取数据反序列化)
对于反序列化,你需要将前端传来的JSON数据传递给data
参数,并调用is_valid()
方法进行验证。如果验证通过,你可以调用save()
方法将数据存储到数据库中。
class BookCreateView(APIView): def post(self, request, *args, **kwargs): serializer = BookSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=201) return Response(serializer.errors, status=400)
4.5.1 url配置
urlpatterns = [ path('books/', BookListView.as_view(), name='book-list'), path('books/create/', BookCreateView.as_view(), name='book-create'), # 新增的路径
]
4.5.2 测试
现在你可以使用工具(如 Postman)来测试你的创建接口。发送一个 POST 请求到 http://localhost:8000/books/create/
,并在请求体中提供书籍的数据(JSON 格式):
{ "title": "Django REST Framework 序列化与反序列化详解", "author": "春天的菠菜", "publication_date": "2024-11-01"
}
4.6 数据验证(将4.1的序列化设置验证方式多样化)
在序列化器中,你可以通过指定字段的验证参数(如max_length
、min_length
、required
等)来进行数据验证。此外,你还可以定义validate_<field_name>
方法来对单个字段进行自定义验证,或者定义validate
方法来对多个字段进行联合验证。
class BookSerializer(serializers.ModelSerializer): title = serializers.CharField(max_length=100, min_length=5) def validate_title(self, value): if 'badword' in value.lower(): raise serializers.ValidationError('Title contains bad words.') return value def validate(self, attrs): if attrs['author'] == 'Unknown': raise serializers.ValidationError({'author': 'Author cannot be Unknown.'}) return attrs class Meta: model = Book fields = '__all__'
5、一对多模型序列化
5.1 模型定义
class Department(models.Model):name = models.CharField(max_length=100)description = models.TextField(blank=True, null=True)def __str__(self):return self.nameclass Meta:managed = Truedb_table = 'department'class Employee(models.Model):first_name = models.CharField(max_length=100)last_name = models.CharField(max_length=100)department = models.ForeignKey(Department, on_delete=models.CASCADE)hire_date = models.DateField()def __str__(self):return f"{self.first_name} {self.last_name}"class Meta:managed = Truedb_table = 'employee'
5.2 序列化器定义
在序列化器中,你可以使用serializers.PrimaryKeyRelatedField
或serializers.StringRelatedField
来引用关联对象的主键或字符串表示,或者使用嵌套的序列化器来表示关联对象的完整数据。
from rest_framework import serializers
from .models import Department, Employeeclass DepartmentSerializer(serializers.ModelSerializer):class Meta:model = Departmentfields = ['id', 'name', 'description']class EmployeeSerializer(serializers.ModelSerializer):department = DepartmentSerializer() # 使用嵌套的序列化器class Meta:model = Employeefields = ['id', 'first_name', 'last_name', 'department', 'hire_date']
在这个例子中,EmployeeSerializer
中的department
字段使用了DepartmentSerializer
作为嵌套序列化器,这样当序列化Employee
对象时,department
字段将包含完整的Department
对象数据。
5.3 使用序列化器
# newapp/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Employee
from .serializers import EmployeeSerializerclass EmployeeListView(APIView):def get(self, request, *args, **kwargs):employees = Employee.objects.all().select_related('department') # 使用select_related优化查询serializer = EmployeeSerializer(employees, many=True)return Response(serializer.data)
5.4 url配置
# newapp/urls.py
from django.urls import path
from .views import EmployeeListViewurlpatterns = [path('employees/', EmployeeListView.as_view(), name='employee-list'),
]
5.5 测试
返回的数据展示
[{"id": 1,"first_name": "Michelle","last_name": "Jackson","department": {"id": 1,"name": "公关部","description": "外部公关"},"hire_date": "2024-10-01"},{"id": 2,"first_name": "John","last_name": "Smith","department": {"id": 2,"name": "市场部","description": "开拓市场"},"hire_date": "2024-10-30"},{"id": 3,"first_name": "Mary","last_name": "Johnson","department": {"id": 1,"name": "公关部","description": "外部公关"},"hire_date": "2024-10-30"}
]
6、多对多关系
现在,假设我们有一个 Role 模型和一个 Permission 模型,其中 Role 模型有一个 permissions 字段,指向 Permission 模型,表示每个角色拥有的权限。这就是一个典型的多对多关系,因为一个角色可以拥有多个权限,同时一个权限也可以被多个角色拥有。
6.1 模型定义
# newapp/models.py
from django.db import modelsclass Permission(models.Model):name = models.CharField(max_length=100)description = models.TextField(blank=True, null=True)def __str__(self):return self.nameclass Role(models.Model):name = models.CharField(max_length=100)permissions = models.ManyToManyField(Permission)def __str__(self):return self.name
库里实际生成了三张表
6.2 序列化器定义
对于多对多关系,你可以使用serializers.PrimaryKeyRelatedField
的many=True
参数来引用关联对象的主键列表,或者使用嵌套的序列化器列表来表示关联对象的完整数据。
# newapp/serializers.py
from rest_framework import serializers
from .models import Permission, Roleclass PermissionSerializer(serializers.ModelSerializer):class Meta:model = Permissionfields = ['id', 'name', 'description']class RoleSerializer(serializers.ModelSerializer):permissions = PermissionSerializer(many=True) # 使用嵌套的序列化器列表class Meta:model = Rolefields = ['id', 'name', 'permissions']
在这个例子中,RoleSerializer 中的 permissions 字段使用了 PermissionSerializer 作为嵌套序列化器,并且设置了 many=True,这样当序列化 Role 对象时,permissions 字段将包含 Permission 对象数据的列表。
6.3 使用序列化器
无论是对于一对多关系还是多对多关系,使用序列化器的方式都是相同的。你可以在视图中实例化序列化器对象,并将要序列化的数据传递给instance
参数(对于单个对象)或many=True
(对于多个对象),然后进行序列化。
# newapp/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Role
from .serializers import RoleSerializerclass RoleListView(APIView):def get(self, request, *args, **kwargs):roles = Role.objects.all().prefetch_related('permissions') # 使用prefetch_related优化查询serializer = RoleSerializer(roles, many=True)return Response(serializer.data)
注意,在上面的例子中,我们使用了prefetch_related
来优化查询性能,这样可以减少数据库查询的次数。
6.4 url配置
# newapp/urls.py
from django.urls import path
from .views import RoleListViewurlpatterns = [path('roles/', RoleListView.as_view(), name='role-list'),
]
6.5 测试
返回数据
[{"id": 1,"name": "经理","permissions": [{"id": 1,"name": "人员跟踪","description": "人员动向"},{"id": 2,"name": "职能级别","description": "客户职能级别"},{"id": 3,"name": "固定资产","description": "固定资产"}]},{"id": 2,"name": "部长","permissions": [{"id": 2,"name": "职能级别","description": "客户职能级别"},{"id": 3,"name": "固定资产","description": "固定资产"}]}
]
7、自定义字段
包含choices类型、外键、ManyToMany
7.1 模型定义
# newapp/models.py
from django.db import modelsclass Team(models.Model):name = models.CharField(max_length=100)description = models.TextField(blank=True, null=True)def __str__(self):return self.nameclass Task(models.Model):name = models.CharField(max_length=100)description = models.TextField(blank=True, null=True)def __str__(self):return self.nameclass Member(models.Model):STATUS_CHOICES = [(0, '无效的'),(1, '活跃的'),(2, '待定的')]first_name = models.CharField(max_length=100)last_name = models.CharField(max_length=100)status = models.IntegerField(choices=STATUS_CHOICES, default=1)team = models.ForeignKey(Team, on_delete=models.CASCADE)tasks = models.ManyToManyField(Task, blank=True)def __str__(self):return f"{self.first_name} {self.last_name}"
7.2 序列化器定义
定义 TeamSerializer、TaskSerializer 和 MemberSerializer,并在 MemberSerializer 中嵌套 TeamSerializer 和 TaskSerializer 列表,并添加自定义字段 status_name 来显示 status 的可读名称。
# newapp/serializers.py
from rest_framework import serializers
from .models import Team, Task, Memberclass TeamSerializer(serializers.ModelSerializer):class Meta:model = Teamfields = ['id', 'name', 'description']class TaskSerializer(serializers.ModelSerializer):class Meta:model = Taskfields = ['id', 'name', 'description']class MemberSerializer(serializers.ModelSerializer):team = TeamSerializer(read_only=True)tasks = TaskSerializer(many=True, read_only=True)status_name = serializers.CharField(source='get_status_display', read_only=True)class Meta:model = Memberfields = ['id', 'first_name', 'last_name', 'status', 'status_name', 'team', 'tasks']def to_representation(self, instance):representation = super().to_representation(instance)# 添加自定义字段:任务数量representation['task_count'] = instance.tasks.count()# 你可以在这里添加更多的自定义字段或修改现有的字段# 例如,你可能想根据某些条件改变状态名称的颜色# representation['status_color'] = 'green' if instance.status == 1 else 'red'return representation
to_representation
方法,它会在序列化每个 Member
实例时被调用。这个方法允许我们添加自定义字段到序列化的数据中。在这个例子中,我们添加了一个 task_count
字段,它显示了每个成员的任务数量。
7.3 使用序列化器
# newapp/views.py
from rest_framework.views import APIView
from .models import Member
from .serializers import MemberSerializer
from rest_framework import statusclass MemberListView(APIView):def get(self, request, *args, **kwargs):members = Member.objects.all().prefetch_related('tasks').select_related('team') # 使用 prefetch_related 和 select_related 优化查询serializer = MemberSerializer(members, many=True)return Response(serializer.data, status=status.HTTP_200_OK)
7.4 配置url
urlpatterns = [ path('members/', MemberListView.as_view(), name='member-list'),
]
7.5 测试
返回数据
[{"id": 1,"first_name": "Mary","last_name": "Smith","status": 1,"status_name": "活跃的","team": {"id": 2,"name": "傲世天骄","description": "绝色天骄团队"},"tasks": [],"task_count": 0},{"id": 2,"first_name": "Michelle","last_name": "Jackson","status": 2,"status_name": "待定的","team": {"id": 1,"name": "海豹突击队","description": "精英男士"},"tasks": [{"id": 1,"name": "拜访傲视群雄世家","description": "拜访傲视群雄世家,获取订单需求"},{"id": 2,"name": "拜访独孤求败世家","description": "拜访独孤求败世家,获取人脉资源"},{"id": 3,"name": "拜访东方不败世家","description": "拜访东方不败世家,提供美颜代言"}],"task_count": 3},{"id": 3,"first_name": "John","last_name": "Jackson","status": 1,"status_name": "活跃的","team": {"id": 2,"name": "傲世天骄","description": "绝色天骄团队"},"tasks": [{"id": 1,"name": "拜访傲视群雄世家","description": "拜访傲视群雄世家,获取订单需求"},{"id": 2,"name": "拜访独孤求败世家","description": "拜访独孤求败世家,获取人脉资源"},{"id": 3,"name": "拜访东方不败世家","description": "拜访东方不败世家,提供美颜代言"}],"task_count": 3}
]
7.6 使用depth优化序列化器
class MemberSerializer(serializers.ModelSerializer):status_name = serializers.CharField(source='get_status_display', read_only=True)class Meta:model = Memberfields = ['id', 'first_name', 'last_name', 'status', 'status_name', 'team', 'tasks']depth = 1 # 设置 depth=1 来自动序列化关联对象def to_representation(self, instance):representation = super().to_representation(instance)# 添加自定义字段:任务数量representation['task_count'] = instance.tasks.count()# 你可以在这里添加更多的自定义字段或修改现有的字段# 例如,你可能想根据某些条件改变状态名称的颜色# representation['status_color'] = 'green' if instance.status == 1 else 'red'return representation
这样做的好处是代码变得更简洁了,不需要单独定义 TeamSerializer 和 TaskSerializer,也不需要显式地设置它们为只读或使用 many=True。但是,请注意以下几点:
- 性能问题:使用 depth 可能会导致额外的数据库查询,特别是在处理多对多关系时。
- 灵活性减少:你将无法轻松地添加自定义字段到嵌套的序列化器中。
- 控制力减弱:你将无法控制嵌套序列化器的具体行为,例如选择要包含的字段
8、来个多表级联
设计一个多表查询系统,包括省、市、县/区、街道、居委会以及人员信息。我们将使用 Django 模型来定义这些表,并创建相应的序列化器和视图。最后,我们会配置 URL 并提供测试逻辑。
8.1 模型定义
我们首先定义六张表:Province
(省)、City
(市)、County
(县/区)、Street
(街道)、Community
(居委会)和 Person
(人员)
# newapp/models.py
from django.db import modelsclass Province(models.Model):name = models.CharField(max_length=100)description = models.TextField(blank=True, null=True)def __str__(self):return self.nameclass City(models.Model):name = models.CharField(max_length=100)province = models.ForeignKey(Province, on_delete=models.CASCADE)description = models.TextField(blank=True, null=True)def __str__(self):return self.nameclass County(models.Model):name = models.CharField(max_length=100)city = models.ForeignKey(City, on_delete=models.CASCADE)description = models.TextField(blank=True, null=True)def __str__(self):return self.nameclass Street(models.Model):name = models.CharField(max_length=100)county = models.ForeignKey(County, on_delete=models.CASCADE)description = models.TextField(blank=True, null=True)def __str__(self):return self.nameclass Community(models.Model):name = models.CharField(max_length=100)street = models.ForeignKey(Street, on_delete=models.CASCADE)description = models.TextField(blank=True, null=True)def __str__(self):return self.nameclass Person(models.Model):first_name = models.CharField(max_length=100)last_name = models.CharField(max_length=100)community = models.ForeignKey(Community, on_delete=models.CASCADE)def __str__(self):return f"{self.first_name} {self.last_name}"
8.2 序列化器定义
我们将使用 depth 参数来自动序列化关联对象。我们只需要为 Person 定义一个序列化器,并设置 depth 参数
# newapp/serializers.py
from rest_framework import serializers
from .models import Personclass PersonSerializer(serializers.ModelSerializer):full_address = serializers.SerializerMethodField()class Meta:model = Personfields = ['id', 'first_name', 'last_name', 'community', 'full_address']depth = 5 # 设置 depth 为 5 来自动序列化所有关联对象def get_full_address(self, obj):parts = [obj.community.street.county.city.province.name,obj.community.street.county.city.name,obj.community.street.county.name,obj.community.street.name,obj.community.name]return ', '.join(parts)def to_representation(self, instance):representation = super().to_representation(instance)# 可以在这里添加其他自定义字段return representation
8.3 使用序列化器
我们定义一个 APIView 来处理获取所有人员的请求,并使用 select_related 和 prefetch_related 来优化查询
# newapp/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Person
from .serializers import PersonSerializerclass PersonListView(APIView):def get(self, request, *args, **kwargs):persons = Person.objects.all().select_related('community__street__county__city__province')serializer = PersonSerializer(persons, many=True)return Response(serializer.data, status=status.HTTP_200_OK)
8.4 配置URL
# newapp/urls.py
from django.urls import path
from .views import PersonListViewurlpatterns = [path('persons/', PersonListView.as_view(), name='person-list'),
]
8.5 测试
返回数据
[{"id": 1,"first_name": "Michelle","last_name": "Johnson","community": {"id": 1,"name": "青年路社区居民委员会","description": "","street": {"id": 1,"name": "湖滨街道","description": "","county": {"id": 1,"name": "上城区","description": "","city": {"id": 2,"name": "杭州市","description": "","province": {"id": 2,"name": "浙江省","description": ""}}}}},"full_address": "浙江省, 杭州市, 上城区, 湖滨街道, 青年路社区居民委员会"},{"id": 2,"first_name": "Mary","last_name": "Smith","community": {"id": 1,"name": "青年路社区居民委员会","description": "","street": {"id": 1,"name": "湖滨街道","description": "","county": {"id": 1,"name": "上城区","description": "","city": {"id": 2,"name": "杭州市","description": "","province": {"id": 2,"name": "浙江省","description": ""}}}}},"full_address": "浙江省, 杭州市, 上城区, 湖滨街道, 青年路社区居民委员会"},{"id": 3,"first_name": "John","last_name": "Smith","community": {"id": 2,"name": "百子亭社区","description": "","street": {"id": 2,"name": "玄武门街道","description": "","county": {"id": 2,"name": "玄武区","description": "","city": {"id": 1,"name": "南京市","description": "市区","province": {"id": 1,"name": "江苏省","description": ""}}}}},"full_address": "江苏省, 南京市, 玄武区, 玄武门街道, 百子亭社区"}
]
9、总结
Django REST Framework的序列化和反序列化功能为开发RESTful API提供了极大的便利。通过定义序列化器,你可以轻松地将Python对象转换为JSON格式,并从JSON数据恢复为Python对象。同时,序列化器还提供了强大的数据验证功能,确保数据的合法性和完整性。掌握这些技能,将帮助你更高效地开发前后端分离的Web应用。
扩展知识点:在5与6章节 使用了这2个知识点,
prefetch_related
适用于“一对多”的关系,即外键和多对多关系。如果你有“多对一”或“多对多”的关系,并且你想优化查询,可以使用select_related
。在使用
prefetch_related
或select_related
时,你需要确保你的查询逻辑允许这种优化,并且你的数据库设计和索引也支持这种优化。此外,过度使用prefetch_related
和select_related
可能会导致内存使用增加,因为它们会一次性加载更多的数据到内存中。因此,在使用这些优化技术时,需要根据实际情况进行权衡。
10、前期工作
10.1 创建django项目
10.2 安装库
pip install pymysql# rest_framework
pip install djangorestframework# django后台页面美化 simpleui 非必须
pip install django-simpleui -i https://pypi.tuna.tsinghua.edu.cn/simple
10.3 配置
10.3.1 创建mysql数据库drf
略
10.3.2 配置mysql数据
DRFDemo下的__init__.py配置
import pymysql
pymysql.install_as_MySQLdb()
10.3.3 settings配置
INSTALLED_APPS = ['simpleui','django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','drf.apps.DrfConfig','rest_framework','simpleui'
]DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql', # 数据库的类型'NAME': 'drf', # 所使用的的数据库的名字'USER': 'root', # 数据库服务器的用户'PASSWORD': 'dddd', # 密码'HOST': 'IP', # 主机'PORT': '3306', # 端口}
}# 国际化配置
LANGUAGE_CODE = 'zh-hans'TIME_ZONE = 'Asia/Shanghai'USE_TZ = FalseUSE_I18N = True
10.3.4 apps.py
from django.apps import AppConfigclass DrfConfig(AppConfig):default_auto_field = 'django.db.models.BigAutoField'name = 'drf'verbose_name = '首页欢迎你'
10.3.5 DRFDemo的urls配置
from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('smart/', include('smart.urls')),]
10.3.6 drf的urls配置
在drf下新建urls.py 后续的路由在这里配置
from django.urls import path
from . import views # 假设你的视图函数定义在 views.py 中urlpatterns = [# path('', views.index, name='index'), # 定义一个根路由,指向 index 视图# 你可以在这里添加更多的路由
]
10.3.7 新建库表之后操作(非必须)
新库表这里配置就可在后台页面操作
from .models import Book
from django.contrib import admin# Register your models here.
admin.site.register(Book)
10.4 同步数据库
python manage.py makemigrations
python manage.py migrate
10.5 创建超级用户
# 输入命令
createsuperuser# 创建用户root
root# 邮箱
market@163.com#密码
123456# 再次输入密码
123456# 提示密码不安全,输入Y
y
10.6 启动服务
python manage.py runserver
10.7 访问
10.7.1 后端管理页面
http://127.0.0.1:8000/admin/
10.7.2 默认页面
http://127.0.0.1:8000/
相关文章:

【django】Django REST Framework 序列化与反序列化详解
目录 1、什么是序列化和反序列化? 2、Django REST Framework中的序列化和反序列化 3、安装与配置(第10章是从零开始) 3.1 安装 3.2 配置 4、基本使用 4.1 创建序列化器 4.2 使用序列化器(将数据序列化返回给前端ÿ…...

【Golang】Golang的Map的线程安全问题
文章目录 前言一、场景介绍二、线程安全的Map的使用四、总结 前言 在 Golang 编程中,map 是一种常用的数据结构,用于存储键值对。然而,Golang 的 map 在并发访问时是线程不安全的。如果多个 goroutine 同时读写同一个 map,可能会…...

指向指针的指针+ 值传递的理解
//17、下面的程序会出现什么结果 #include #include void getmemory(char *p) { p(char *) malloc(100); strcpy(p,”hello world”); } int main( ) { char *strNULL; getmemory(str); printf(“%s/n”,str); free(str); return 0; } // 程序崩溃,…...

CSS常用定位
一、relative 相对原先的位置进行定位 {position: relative;left: 50px; /* 相对原先位置左边的距离 */top: 100px; /* 相对原先位置上边的距离 */ } 二、absolute 绝对定位,是相对于最近有定位的父级元素进行定位 {position: absolute;righ…...

【Linux】从零开始使用多路转接IO --- select
碌碌无为,则余生太长; 欲有所为,则人生苦短。 --- 中岛敦 《山月记》--- 从零开始认识五种IO模型 1 前言2 认识多路转接select3 多路转接select等待连接4 完善代码5 总结 1 前言 上一篇文章我们讲解了五种IO模型的基本概念,并…...

ArcGIS Pro SDK (二十一)渲染
ArcGIS Pro SDK (二十一)渲染 文章目录 ArcGIS Pro SDK (二十一)渲染1 定义唯一值呈现器定义2 为最新观测值设置唯一值渲染器3 为先前的观测值设置唯一值渲染器4 设置简单的渲染器以绘制轨迹线5 检查先前的观测值和轨道线可见性6 使轨迹线和先前的观测点可见7 检索当前观测…...

FPGA在物联网边缘计算中的应用!!!
FPGA(现场可编程门阵列)在物联网边缘计算中的应用正变得越来越重要。边缘计算是一种分布式计算架构,它将数据的处理分散到网络的边缘,靠近数据源,而不是集中在数据中心处理。以下是FPGA在物联网边缘计算中的几个关键应…...

【解决】Linux环境中mysqlclient安装失败问题
问题描述 在Linux系统下安装myslclient报异常。系统为Centos 8 使用 pip install mysqlclient 报出下面的异常 error: subprocess-exited-with-error Getting requirements to build wheel did not run successfully.│ exit code: 1╰─> [30 lines of output]/bin/sh: pkg…...

✨ Midjourney中文版:创意启航,绘梦无界 ✨
Midjourney AI超强绘画 (原生态系统)用户端:Ai Loadinghttps://www.mjdiscord.com 项目详细介绍飞书文档:Docshttps://ivqklkndl4k.feishu.cn/docx/GRnMdCbcooWkwTx1RU4cZjGVnzb?fromfrom_copylk 🌐 无缝体验,中文定制…...

软件(1)
软件 常考软件 图像软件 Flash 一款二维动画处理软件 photoshop 图像处理界的“巨无霸” ACDSee ACDSee是常用的图片管理编辑软件,尽管也可以支持WAV格式的音频播放, 但目前主要是作为看图软件 音频软件 Winamp Winamp是数字媒体播放的先驱Audition Audi…...

linux perf 环境部署和基本测试(基于Ubuntu20.04)
1,linux 安装perf sudo apt-ge install linux-tools-common sudo apt-get install linux-tools-$(uname -r) linux-tools-generic -y 2 补充安装 sudo apt-get install python3-q-text-as-data 3,perf常用命令 larkubuntu:~$ perf usage: perf [--version] [--hel…...

【网络面试篇】HTTP(1)(笔记)——状态码、字段、GET、POST、缓存
目录 一、相关问题 1. HTTP请求常见的状态码和字段? (1)状态码 (2)字段 ① Host 字段 ② Content-length 字段 ③ Connection 字段 ④ Content-Type 字段 ⑤ Content-Encoding 字段 2. GET 和 POST 的区别&a…...

HTML 基础标签——分组标签 <div>、<span> 和基础语义容器
文章目录 1. `<div>` 标签特点用途示例2. `<span>` 标签特点用途示例3. `<fieldset>` 标签特点用途示例4. `<section>` 标签特点用途示例5. `<article>` 标签特点用途示例总结HTML中的分组(容器)标签用于结构化内容,将页面元素组织成逻辑区域…...

SS928V100 ISP常见问题列表
下载链接: https://download.csdn.net/download/quantum7/89948226 1 FAQ 1 1.1 ISP 1 1.1.1 如何解决整体锐度不足 1 1.1.2 如何解决图像发蒙问题,提高通透性 2 1.1.3 如何解决低照度清晰度差 2 1.1.4 如何解决图像清晰度与物体边缘白边和黑边问题…...

AI写诗:自动版大唐宫体诗
大唐学子,手拿一本小卷(类书),从中挑选过去他们(权威)认为好的词来拼接一首诗,此类诗词称作“宫体诗”,在初唐时期甚是流行。 写“宫体诗”的过程有木有那么一丝丝的熟悉?…...

Java复习31(PTA)
sdust-Java-字符串集合求并集 分数 15 全屏浏览 切换布局 作者 张峰 单位 山东科技大学 从键盘接收N个英文字符串(其中不同的字符串数量大于10),从头开始取5个不同的字符串放入一个集合S1,然后接着取5个不同的字符串放入另一个…...

【Linux系列】Linux 系统中的软连接管理
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

@layer(级联层)
在css样式表(文件)中声明layer为样式添加级联层,其意义在于可以使用它重新定义样式的叠层关系. layer后声明的级联层里面的样式将覆盖前声明的级联层里面的相同属性.在级联层外声明的样式会覆盖级联层里面的相同属性样式,同一层级里面的样式冲突,依然按照优先级来计算. 在级联层…...

nginx代理websocket服务
一、nginx代理websocket服务 一)nginx代理ws服务 在nginx中,可以通过proxy_pass指令来代理WebSocket服务。 以下是一个示例配置: map $http_upgrade $connection_upgrade {default upgrade; close; }upstream ws_backend {server 127.0.0.1:…...

第二十七章 Vue异步更新之$nextTick
目录 一、概述 二、完整代码 2.1. main.js 2.2. App.vue 一、概述 需求:编辑标题, 弹出显示编辑框自动聚焦 1. 点击编辑,显示编辑框 2. 让编辑框,立刻获取焦点 我们常规的思路可能会编写如下代码来实现: 问题:…...

【51 Pandas+Pyecharts | 深圳市共享单车数据分析可视化】
文章目录 🏳️🌈 1. 导入模块🏳️🌈 2. Pandas数据处理2.1 读取数据2.2 查看数据信息2.3 处理起始时间、结束时间2.4 增加骑行时长区间列2.5 增加骑行里程区间列 🏳️🌈 3. Pyecharts数据可视化3.1 各…...

【Clikhouse 探秘】ClickHouse 物化视图:加速大数据分析的新利器
👉博主介绍: 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主 ⛪️ 个人社区&#x…...

线程相关题(线程池、线程使用、核心线程数的设置)
目录 线程安全的什么情况用?情况下用线程安全的类? 线程池线程方面的优化 线程池调优主要涉及以下几个关键参数。 线程不安全原因? 1. 共享资源访问冲突 2. 缺乏原子操作 3. 内存可见性问题 4. 重排序问题 如何解决线程不安全的问题࿱…...

2181、合并零之间的节点
2181、[中等] 合并零之间的节点 1、问题描述: 给你一个链表的头节点 head ,该链表包含由 0 分隔开的一连串整数。链表的 开端 和 末尾 的节点都满足 Node.val 0 。 对于每两个相邻的 0 ,请你将它们之间的所有节点合并成一个节点ÿ…...

powerlaw:用于分析幂律分布的Python库
引言 幂律分布在游戏行业中非常重要。在免费游戏模式下,玩家的付费行为往往遵循幂律分布。少数“鲸鱼玩家”贡献了大部分的收入,而大多数玩家可能只进行少量或不进行付费。通过理解和应用幂律分布,游戏开发者可以更好地分析和预测玩家行为&a…...

工作管理实战指南:利用Jira、Confluence等Atlassian工具打破信息孤岛,增强团队协作【含免费指南】
如果工作场所存在超级反派,其中之一可能会被命名为“信息孤岛”,因为它们能够对公司的生产力和协作造成严重破坏。当公司决定使用太多互不关联的工具来完成工作时,“信息孤岛”就会出现,导致团队需要耗费大量时间才能就某件事情达…...

JAVA语言多态和动态语言实现原理
JAVA语言多态和动态语言实现原理 前言invoke指令invokestaticinvokespecialinvokevirtualinvokeintefaceinvokedynamicLambda 总结 前言 我们编码java文件,javac编译class文件,java运行class,JVM执行main方法,加载链接初始化对应…...

阿里云-防火墙设置不当导致ssh无法连接
今天学网络编程的时候,看见有陌生ip连接,所以打开了防火墙禁止除本机之外的其他ip连接: 但是当我再次用ssh的时候,连不上了才发现大事不妙。 折腾了半天,发现阿里云上可以在线向服务器发送命令,所以赶紧把2…...

使用WebAssembly优化Web应用性能
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 使用WebAssembly优化Web应用性能 引言 WebAssembly 简介 安装工具 创建 WebAssembly 项目 编写 WebAssembly 代码 编译 WebAssem…...

软件测试模型
软件测试模型是在软件开发过程中,用于指导软件测试活动的一系列方法和框架。这些模型帮助测试团队确定何时进行测试、测试什么以及如何测试,从而确保软件的质量和稳定性。 一 V模型 V模型是一种经典的软件测试模型,它由瀑布研发模型演变而来的测试模型…...