【Django】REST 常用类
ModelSerializer
serializers.ModelSerializer
是 Django REST framework(DRF)里的一个强大工具,它能极大简化序列化和反序列化 Django 模型实例的流程。下面从多个方面详细介绍它:
1. 基本概念
序列化是把 Django 模型实例转化为 Python 原生数据类型(像字典、列表等),进而能方便地转换为 JSON、XML 等格式用于传输;反序列化则是将接收到的数据转换回 Django 模型实例。ModelSerializer
会自动依据模型的字段定义来生成序列化器的字段,减少了手动编写序列化器字段的工作量。
2. 基本用法
假设你有一个简单的 Django 模型 Book
:
from django.db import modelsclass Book(models.Model):title = models.CharField(max_length=100)author = models.CharField(max_length=100)published_date = models.DateField()def __str__(self):return self.title
可以创建一个对应的 ModelSerializer
:
from rest_framework import serializers
from .models import Bookclass BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ['id', 'title', 'author', 'published_date']
在上述代码里,Meta
类的 model
属性指定要序列化的模型,fields
属性指定要包含在序列化结果中的字段。
3. 常用属性和方法
Meta
类属性
model
:指定要序列化的 Django 模型。fields
:指定要包含在序列化结果中的字段,可以是字段名的列表或字符串'__all__'
(表示包含模型的所有字段)。exclude
:指定要排除的字段,不能与fields
同时使用。read_only_fields
:指定只读字段,这些字段在反序列化时会被忽略。extra_kwargs
:用于为特定字段提供额外的参数,例如设置字段的required
、write_only
等属性。
示例:
class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = '__all__'read_only_fields = ['id']extra_kwargs = {'title': {'required': True},'author': {'write_only': True}}
序列化方法
data
:返回序列化后的 Python 原生数据类型。
book = Book.objects.first()
serializer = BookSerializer(book)
print(serializer.data)
is_valid()
:验证反序列化的数据是否有效。
data = {'title': 'New Book', 'author': 'John Doe', 'published_date': '2023-01-01'}
serializer = BookSerializer(data=data)
if serializer.is_valid():book = serializer.save()
else:print(serializer.errors)
save()
:保存反序列化后的数据,创建或更新模型实例。
4. 自定义序列化行为
可以通过重写序列化器的方法来自定义序列化和反序列化行为。
重写 to_representation
方法
class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = '__all__'def to_representation(self, instance):data = super().to_representation(instance)data['title'] = data['title'].upper()return data
重写 create
和 update
方法
class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = '__all__'def create(self, validated_data):# 自定义创建逻辑return Book.objects.create(**validated_data)def update(self, instance, validated_data):# 自定义更新逻辑instance.title = validated_data.get('title', instance.title)instance.author = validated_data.get('author', instance.author)instance.published_date = validated_data.get('published_date', instance.published_date)instance.save()return instance
5. 优点
- 代码简洁:自动生成序列化器字段,减少了手动编写的工作量。
- 一致性:序列化器的字段与模型的字段保持一致,方便维护。
- 验证功能:自动提供基本的验证功能,确保数据的有效性。
总之,serializers.ModelSerializer
是 Django REST framework 中非常实用的工具,能让你更高效地处理 Django 模型的序列化和反序列化。
在 Django REST framework(DRF)里,ModelSerializer
中的 update
方法主要用于处理更新现有模型实例的逻辑。当你使用序列化器来更新一个已存在的模型对象时,update
方法会被调用。下面为你详细介绍它的作用、工作机制以及使用示例。
作用
update
方法的核心作用是接收经过验证的数据,把这些数据应用到已有的模型实例上,并且保存更新后的实例。它是序列化器在处理 PUT
或者 PATCH
请求时的关键部分,能够帮助你定制模型实例更新的具体逻辑。
工作机制
- 当你调用序列化器的
save
方法并且传入一个已存在的模型实例时,序列化器会自动调用update
方法。 update
方法接收两个参数:instance
:代表要更新的模型实例。validated_data
:是一个字典,包含经过验证的要更新的数据。
- 在
update
方法内部,你可以从validated_data
里提取数据,把这些数据赋给instance
的相应字段,然后调用instance.save()
方法保存更新后的实例。
示例代码
下面是一个简单的示例,展示了如何在 ModelSerializer
中重写 update
方法:
from rest_framework import serializers
from .models import Bookclass BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ['id', 'title', 'author', 'published_date']def update(self, instance, validated_data):# 更新实例的字段instance.title = validated_data.get('title', instance.title)instance.author = validated_data.get('author', instance.author)instance.published_date = validated_data.get('published_date', instance.published_date)# 保存更新后的实例instance.save()return instance
代码解释
instance.title = validated_data.get('title', instance.title)
:这行代码尝试从validated_data
中获取title
字段的值,如果validated_data
中存在title
字段,就将其赋值给instance.title
;如果不存在,就保持instance.title
的原有值。instance.save()
:调用save
方法将更新后的实例保存到数据库中。return instance
:返回更新后的实例。
自定义更新逻辑
你可以在 update
方法中添加自定义的更新逻辑,例如在更新某些字段时执行额外的操作,或者根据特定条件更新不同的字段。
def update(self, instance, validated_data):if 'title' in validated_data:# 在更新标题时执行额外的操作new_title = validated_data['title'].upper()instance.title = new_titleif 'author' in validated_data:# 检查作者是否合法if len(validated_data['author']) > 5:instance.author = validated_data['author']instance.published_date = validated_data.get('published_date', instance.published_date)instance.save()return instance
在这个例子中,当更新 title
字段时,会将新标题转换为大写;更新 author
字段时,会检查作者名字的长度是否大于 5。
综上所述,update
方法为你提供了一种灵活的方式来定制模型实例的更新逻辑,以满足特定的业务需求。
ForeignKey
在 Django 中,models.ForeignKey
是一个非常重要的字段类型,用于在模型之间创建多对一(Many-to-One)的关联关系。下面将从多个方面对其进行详细介绍。
1. 基本概念
多对一关系表示一个模型的多个实例可以关联到另一个模型的一个实例。例如,在一个博客应用中,多篇文章(Article
)可以属于同一个作者(Author
),那么文章和作者之间就是多对一的关系。models.ForeignKey
就是用来在 Django 模型中定义这种关系的。
2. 基本语法
from django.db import modelsclass Author(models.Model):name = models.CharField(max_length=100)def __str__(self):return self.nameclass Article(models.Model):title = models.CharField(max_length=200)author = models.ForeignKey(Author, on_delete=models.CASCADE)def __str__(self):return self.title
在上述代码中,Article
模型中的 author
字段是一个 ForeignKey
,它指向 Author
模型。这意味着每篇文章都关联到一个作者。
3. 参数说明
to
- 作用:指定关联的模型。可以是模型类本身,也可以是模型类的字符串表示(如
'app_label.ModelName'
)。 - 示例:
author = models.ForeignKey('myapp.Author', on_delete=models.CASCADE)
on_delete
- 作用:定义当关联的对象被删除时,当前对象应该如何处理。这是一个必需的参数。
- 常见选项:
models.CASCADE
:级联删除。当关联的对象被删除时,与之关联的所有对象也会被删除。例如,当一个作者被删除时,他所写的所有文章都会被删除。models.PROTECT
:保护模式。如果有关联的对象存在,不允许删除关联的对象,会抛出ProtectedError
异常。models.SET_NULL
:将关联字段设置为NULL
。前提是该字段必须允许为空(null=True
)。例如,当一个作者被删除时,他所写的文章的author
字段会被设置为NULL
。models.SET_DEFAULT
:将关联字段设置为默认值。前提是该字段必须有默认值(default=...
)。models.SET()
:将关联字段设置为指定的值或调用指定的函数返回的值。models.DO_NOTHING
:不做任何处理。可能会导致数据库中的外键约束错误。
related_name
- 作用:定义从关联模型反向查询时使用的名称。默认情况下,Django 会自动生成一个反向查询的名称,格式为
modelname_set
(例如,article_set
)。使用related_name
可以自定义这个名称。 - 示例:
class Article(models.Model):title = models.CharField(max_length=200)author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='articles')
现在可以通过 author.articles.all()
来获取该作者的所有文章。
null
- 作用:指定该字段是否可以为空。如果设置为
True
,则允许该字段在数据库中存储NULL
值。 - 示例:
author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True)
blank
- 作用:指定在表单验证时该字段是否可以为空。如果设置为
True
,则在表单中该字段可以不填写。 - 示例:
author = models.ForeignKey(Author, on_delete=models.CASCADE, blank=True)
4. 反向查询
通过 ForeignKey
建立的关联关系,可以进行反向查询。例如,有了上述的 Article
和 Author
模型,可以这样进行反向查询:
author = Author.objects.get(name='John Doe')
articles = author.article_set.all() # 如果没有指定 related_name
# 或者
articles = author.articles.all() # 如果指定了 related_name='articles'
5. 数据库层面
在数据库中,ForeignKey
字段会被存储为一个整数,这个整数是关联模型实例的主键值。例如,Article
表中的 author
字段会存储对应的 Author
实例的 id
。
6. 注意事项
- 当使用
ForeignKey
时,要确保on_delete
参数设置合理,避免出现数据不一致的问题。 - 频繁的级联删除可能会导致数据丢失,使用时要谨慎。
综上所述,models.ForeignKey
是 Django 中实现多对一关系的重要工具,通过合理使用其参数,可以灵活地管理模型之间的关联。
ModelViewSet
在 Django REST framework(DRF)里,viewsets.ModelViewSet
是一个强大且实用的工具,它简化了基于 Django 模型构建 RESTful API 的过程。下面我会详细讲解 viewsets.ModelViewSet
及其相关的 viewsets
模块。
1. viewsets
模块概述
viewsets
模块是 Django REST framework 提供的一组视图集类,它们把不同的视图逻辑(如列表视图、详情视图、创建视图、更新视图、删除视图等)组合在一起,让你能够以一种更简洁、高效的方式构建 API。视图集可以根据不同的 HTTP 请求方法(如 GET
、POST
、PUT
、DELETE
等)自动处理对应的操作。
2. ModelViewSet
简介
ModelViewSet
是 viewsets
模块中的一个核心类,它继承自多个不同的混合类(如 CreateModelMixin
、RetrieveModelMixin
、UpdateModelMixin
、DestroyModelMixin
、ListModelMixin
),这些混合类为 ModelViewSet
提供了完整的 CRUD(创建、读取、更新、删除)操作功能。
3. 基本用法
假设你有一个简单的 Django 模型 Book
:
from django.db import modelsclass Book(models.Model):title = models.CharField(max_length=100)author = models.CharField(max_length=100)published_date = models.DateField()def __str__(self):return self.title
你可以创建一个对应的 ModelViewSet
来处理这个模型的 API 操作:
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializerclass BookViewSet(viewsets.ModelViewSet):queryset = Book.objects.all()serializer_class = BookSerializer
这里的 BookSerializer
是一个序列化器,用于将 Book
模型实例序列化为 JSON 数据,以及将 JSON 数据反序列化为 Book
模型实例。以下是一个简单的序列化器示例:
from rest_framework import serializers
from .models import Bookclass BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ['id', 'title', 'author', 'published_date']
4. 路由配置
为了让 BookViewSet
能够响应 HTTP 请求,需要进行路由配置。Django REST framework 提供了 routers
模块来简化路由配置:
from rest_framework import routers
from .views import BookViewSetrouter = routers.DefaultRouter()
router.register(r'books', BookViewSet)urlpatterns = router.urls
这样,BookViewSet
就会自动处理以下几种类型的请求:
GET /books/
:获取所有书籍的列表。POST /books/
:创建一本新的书籍。GET /books/{id}/
:获取指定 ID 的书籍详情。PUT /books/{id}/
:更新指定 ID 的书籍的所有字段。PATCH /books/{id}/
:部分更新指定 ID 的书籍的字段。DELETE /books/{id}/
:删除指定 ID 的书籍。
5. 方法和属性
queryset
:指定要处理的模型实例集合,通常是一个查询集(QuerySet)。serializer_class
:指定用于序列化和反序列化的序列化器类。get_queryset()
:可以重写这个方法来动态地返回不同的查询集,例如根据用户权限过滤数据。
class BookViewSet(viewsets.ModelViewSet):serializer_class = BookSerializerdef get_queryset(self):# 只返回已发布的书籍return Book.objects.filter(published=True)
perform_create()
:可以重写这个方法来在创建新实例时执行额外的操作,例如记录日志。
class BookViewSet(viewsets.ModelViewSet):queryset = Book.objects.all()serializer_class = BookSerializerdef perform_create(self, serializer):# 在创建书籍时记录日志print(f"Creating a new book: {serializer.validated_data['title']}")serializer.save()
6. 优点
- 代码简洁:通过继承
ModelViewSet
,可以用很少的代码实现完整的 CRUD 操作,减少了重复代码。 - 可维护性高:将不同的视图逻辑封装在一个类中,使得代码结构更加清晰,易于维护和扩展。
- 自动生成路由:结合
routers
模块,可以自动生成 API 的路由,简化了路由配置。
综上所述,viewsets.ModelViewSet
是 Django REST framework 中一个非常实用的工具,能够帮助你快速、高效地构建功能完整的 RESTful API。