【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.Serializerserializers.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_lengthmin_lengthrequired等)来进行数据验证。此外,你还可以定义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.PrimaryKeyRelatedFieldserializers.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.PrimaryKeyRelatedFieldmany=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_relatedselect_related 时,你需要确保你的查询逻辑允许这种优化,并且你的数据库设计和索引也支持这种优化。此外,过度使用 prefetch_relatedselect_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/

 

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

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

相关文章

三周精通FastAPI:27 使用使用SQLModel操作SQL (关系型) 数据库

官网文档&#xff1a;https://fastapi.tiangolo.com/zh/tutorial/sql-databases/ SQL (关系型) 数据库 FastAPI不需要你使用SQL(关系型)数据库。 但是您可以使用任何您想要的关系型数据库。 这里我们将看到一个使用SQLModel的示例。 SQLModel是在SQLAlchemy和Pydantic的基础…

C++中使用seekg函数进行随机读写

seekg&#xff08;off type offset, ios::seekdir origin ); //作用:设置输入流的位置 这个函数有俩个参数&#xff0c;第一个是表示偏移量&#xff0c;第二个是表示相对位置 infile.seekg(-50, infile.end);//表示从文件结尾开始&#xff0c;向文件开头方向读50个字节 参数 …

2-137 基于matlab的sigmoid函数的变步长自适应语音信号增强

基于matlab的sigmoid函数的变步长自适应语音信号增强&#xff0c;与传统LMS相对比&#xff0c;比较不同的变步长函数去噪效果&#xff0c;并基于较好的去噪算法分析不同变步长中参数变化对降噪的影响。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&#xff1a;2-13…

有效利用关键词研究工具提升网站流量的策略

内容概要 在当前信息泛滥的时代&#xff0c;关键词研究工具的重要性愈发突出。它们不仅能帮助我们识别和分析用户搜索行为&#xff0c;还能够精准地为网站内容定位&#xff0c;确保我们能够吸引并留住目标受众。关键词研究工具通过提供大量的数据&#xff0c;帮助站长和营销策…

探索全托的自闭症学校:打造个性化成长场所

文章详情&#xff1a;http://www.zibizhengwang.com/page35.html 在广州这座充满活力的城市里&#xff0c;有一个特别的地方&#xff0c;它以独特的教育理念和深切的关怀之心&#xff0c;为自闭症儿童提供了一个温暖的避风港。这个地方就是星贝育园自闭症儿童寄宿制学校&#…

使用RabbitMQ实现微服务间的异步消息传递

使用RabbitMQ实现微服务间的异步消息传递 RabbitMQ简介 安装RabbitMQ 在Ubuntu上安装RabbitMQ 在CentOS上安装RabbitMQ 配置RabbitMQ 创建微服务 生产者服务 安装依赖 生产者代码 消费者服务 消费者代码 运行微服务 消息模式 直接模式 生产者代码 消费者代码 扇出模式 生产…

Yolo V4详解

Yolo V4&#xff08;You Only Look Once version 4&#xff09;是一种先进的目标检测系统&#xff0c;于2020年推出。作为Yolo系列算法的最新版本&#xff0c;Yolo V4继承了其前代版本的优点&#xff0c;并在此基础上进行了多项改进&#xff0c;使得其性能得到了显著提升。本文…

Pandas数据结构之Series对象

文章目录 1. DataFrame对象1.1 创建DataFrame对象1.2 DataFrame对象常用属性和方法1.3 布尔值列表获取DataFrame对象中部分数据1.4 DataFrame对象的运算 1. DataFrame对象 DataFrame是一个表格型的结构化数据结构&#xff0c;它含有一组或多组有序的列&#xff08;Series&…

Tomcat 11 下载/安装 与基本使用

为什么要使用Tomcat&#xff1f; 使用Apache Tomcat的原因有很多&#xff0c;以下是一些主要的优点和特点&#xff1a; 1. 开源与免费 Tomcat是一个完全开源的项目&#xff0c;任何人都可以免费使用。它由Apache软件基金会维护&#xff0c;拥有一个活跃的社区&#xff0c;这…

换热器换热面积计算

1 容积式水加热器换热面积计算 式中Q—设计小时耗热量&#xff08;W&#xff09; ε—由于水垢、热媒分布不均匀等影响传热效率的系数&#xff0c;一般采用0.8~0.6 K—传热系数[W/(m2ˑ℃)]&#xff0c;K值对加热器换热影响很大&#xff0c;主要取决于热媒种类和压力、热媒和…

幸福宝宝起名器

这段代码是一个简单的“幸福宝宝取名器”网页应用&#xff0c;主要功能是根据用户输入的姓氏、性别和生成数量&#xff0c;随机生成宝宝的名字。以下是代码的主要组成部分和功能简介&#xff1a; 1. HTML 结构 - 文档类型和语言&#xff1a;使用 <!DOCTYPE html> 声明文…

BLG与T1谁会赢?python制作预测程序,结果显示,BLG将打败T1

决赛预测 2024英雄联盟全球总决赛 2024年英雄联盟全球总决赛&#xff0c;今天晚上&#xff08;2024年11月2日22点&#xff09;就要开始了&#xff01;今年的总决赛的队伍是BLG与T1。当然一些老的lol玩家&#xff0c;现在可能对于lol关注不多&#xff0c;并不清楚这两个队伍。…

Spring Boot 3.x 整合 Druid 数据库连接池(含密码加密)

Spring Boot 3.x 整合 Druid 数据库连接池&#xff08;含密码加密&#xff09; 1. 为什么需要数据库连接池&#xff1f; 在传统的数据库连接中&#xff0c;每一次与数据库连接都会消耗大量的系统资源和时间。数据库连接池会提前创建一定数量的数据库连接保存在池中&#xff0…

完美解决“找不到MSVCR110.dll无法继续执行代码

msvcr110.dll是一个动态链接库&#xff08;Dynamic Link Library&#xff0c;简称DLL&#xff09;文件&#xff0c;它是Microsoft Visual C 2012 Redistributable Package的一部分。这个库文件包含了大量预先编写的函数和资源&#xff0c;用于支持那些使用Visual C 2012或与之兼…

C++【string的模拟实现】

在前文我们讲解了string类接口使用&#xff08;C【string类的使用】(上),C【string类的使用】&#xff08;下&#xff09;&#xff09;&#xff0c;本片文章就来模拟实现string类。 注&#xff1a;本文实现的是string的部分重点内容&#xff0c;目的是为了更好的了解string&…

新能源汽车充电设施在储充电站的应用

0引言 全球能源和环境问题促使新能源汽车受到关注&#xff0c;但其推广受充电设施和能源供应限制。光伏站、储能站和电动汽车充放电站作为可再生能源利用和储存方式&#xff0c;具有巨大潜力。本研究旨在探索新能源汽车充电设施与这些站点的融合模式&#xff0c;以支持新能源汽…

uniapp开发小程序【简单的实现点击下拉选择性别功能】

一、展示效果 二、代码 <template><view><view class="form_box"><view class="item"

Git 基础详解

1. 基本概念 Git是一个免费、开源的 分布式版本控制系统&#xff0c;可以高效处理小到大型的各种项目。 1.1 版本控制 版本控制&#xff1a;它是一种用于追踪和记录文件、目录、项目或软件的变化&#xff0c;以便将来查阅、比较、修订不同版本文件的系统 版本控制系统&…

Yarn介绍 | 组成 | 工作流程

1、理论 Apache YARN&#xff08;Yet another Resource Negotiator的缩写&#xff09;是Hadoop集群的资源管理系统&#xff0c;负责为计算程序提供服务器计算资源&#xff0c;相当于一个分布式的操作系统平台&#xff0c;而MapReduce等计算程序则相当于运行于操作系统之上的应用…

uniapp开发【选择地址-省市区功能】,直接套用即可

一、效果展示 二、代码 <template><view><view class="user_info"><view class="item"