基于类的视图的主要优点之一是它们允许您编写可重用行为的部分。REST框架通过提供许多预构建的视图来利用这一点,这些视图提供了常用的模式。
通过REST框架提供的通用视图,可以快速构建与数据库模型紧密映射的API视图。
如果泛型视图不适合自己的 API 的需求,可以使用常规类,或者重用泛型视图使用的 mixin 和基类来组合成一组可重用的泛型视图。
from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
from rest_framework import generics
from rest_framework.permissions import IsAdminUser
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [IsAdminUser]
#对于复杂的情况,可以重写视图类中的方法
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [IsAdminUser]
def list(self, request):
# Note the use of `get_queryset()` instead of `self.queryset`
queryset = self.get_queryset()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
GenericAPIView
1.提供了基础的操作和属性:
- 支持查询集(queryset)的定义,用于指定要操作的数据集合。
- 提供了序列化器类(serializer_class)的设置,用于数据的序列化和反序列化。
2.实现了常见的方法:
- get_queryset():用于获取查询集。
- get_object():用于获取单个对象。
- lookup_field
- lookup_url_kwarg
3.支持分页:可以方便地设置分页类来处理大量数据的分页展示。(pagination_class)
4.与其他扩展类结合:常与 ListCreateAPIView、RetrieveUpdateDestroyAPIView 等结合使用,快速实现常见的 CRUD 操作。
5.过滤:filter_backends, 应用于过滤查询集的过滤器后端类的列表。默认为与设置相同的值
示例代码:
from rest_framework.generics import GenericAPIView
from rest_framework import serializers
from myapp.models import MyModel
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = '__all__'
class MyView(GenericAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
def get(self, request, *args, **kwargs):
# 自定义的获取数据逻辑
pass
通过合理设置这些属性,可以更好地控制 API 处理请求和响应的数据格式,以满足不同客户端的需求。
Mixins
Mixins 为视图提供了基本的操作行为。常见的 Mixins 包括:
- ListModelMixin:提供了 list 方法,用于处理获取列表数据的请求。
- CreateModelMixin:包含 create 方法,用于处理创建新数据的请求。
- RetrieveModelMixin:提供 retrieve 方法,用于获取单个数据项。
- UpdateModelMixin:包含 update 方法,用于更新数据。
- DestroyModelMixin:提供 destroy 方法,用于删除数据。
这些 Mixins 提供的是动作方法,而不是直接定义如 get() 和 post() 这样的处理方法。这使得行为的组合更加灵活。
from rest_framework import generics
from rest_framework.mixins import ListModelMixin, CreateModelMixin
class MyResourceListCreateView(generics.GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
以下是一个使用 Mixins 在实际项目中创建一个简单的图书资源管理视图的示例代码:
from rest_framework import generics
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin
from myapp.models import Book
from myapp.serializers import BookSerializer
class BookListView(generics.GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class BookDetailView(generics.GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
在上述代码中,BookListView 处理图书列表的获取和新书的创建,BookDetailView 处理单个图书的获取、更新和删除。通过结合 Mixins 和 GenericAPIView ,实现了常见的 CRUD 操作。
在实际项目中使用 Mixins 时,以下是一些需要注意的事项:
- 方法冲突:当多个 Mixins 组合使用时,要注意可能存在的方法名冲突。确保不同 Mixins 中的方法不会相互干扰或产生不一致的行为。
- 权限控制:根据具体的业务需求,合理设置视图的权限。Mixins 本身可能不会处理权限相关的逻辑,需要开发者自行添加权限验证代码。
- 数据一致性:在使用
CreateModelMixin
、UpdateModelMixin
等进行数据操作时,要确保数据的一致性和有效性验证。例如,检查必填字段、数据格式等。 - 错误处理:为 Mixins 中的操作添加适当的错误处理机制,以便在出现异常情况时能够向客户端返回清晰和有用的错误信息。
- 文档注释:由于 Mixins 增加了代码的复杂性,确保为视图类和相关方法添加清晰的文档注释,以便其他开发者能够理解其功能和使用方式。
- 版本控制:如果 API 有不同的版本,要考虑 Mixins 的使用是否在不同版本中保持一致或需要进行相应的调整。
- 性能优化:某些复杂的 Mixins 组合或频繁的数据操作可能会影响性能,需要进行性能测试和优化。
- 测试覆盖:对使用 Mixins 的视图进行充分的单元测试和集成测试,以确保其功能的正确性和稳定性。
Concrete View Classes(具体视图类)
主要的视图类:
- CreateAPIView
- ListAPIView
- RetrieveAPIView
- DestroyAPIView
- UpdateAPIView
- ListCreateAPIView
- RetrieveUpdateAPIView
- RetrieveDestroyAPIView
- RetrieveUpdateDestroyAPIView
这些具体的通用视图类为常见的操作提供了现成的实现,除非您需要高度自定义的行为,否则通常在这个级别使用它们就可以满足需求。
例如,ListCreateAPIView 结合了获取列表(list)和创建(create)的功能,RetrieveUpdateDestroyAPIView 则涵盖了获取单个对象详情(retrieve)、更新(update)和删除(destroy)的操作。
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
from myapp.models import MyModel
from myapp.serializers import MyModelSerializer
class MyModelListCreateView(ListCreateAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
class MyModelRetrieveUpdateDestroyView(RetrieveUpdateDestroyAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
这样,无需自己编写每个操作的具体方法,大大减少了代码量并遵循了常见的设计模式。
以下是对这些具体视图类的介绍:
1.CreateAPIView:
- 功能:专门用于处理创建资源的请求,只支持 POST 方法。
- 示例:
from rest_framework.generics import CreateAPIView
from myapp.models import MyModel
from myapp.serializers import MyModelSerializer
class MyModelCreateView(CreateAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
2.ListAPIView
- 功能:用于获取资源列表,只支持 GET 方法。
- 示例:
from rest_framework.generics import ListAPIView
class MyModelListView(ListAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
3.RetrieveAPIView
- 功能:获取单个资源的详细信息,只支持 GET 方法。
- 示例:
from rest_framework.generics import RetrieveAPIView
class MyModelRetrieveView(RetrieveAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
4.DestroyAPIView
- 功能:用于删除单个资源,只支持 DELETE 方法。
- 示例:
from rest_framework.generics import DestroyAPIView
class MyModelDestroyView(DestroyAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
5.UpdateAPIView
- 功能:专门用于更新单个资源,只支持 PUT 和 PATCH 方法。
- 示例:
from rest_framework.generics import UpdateAPIView
class MyModelUpdateView(UpdateAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
6.ListCreateAPIView
- 功能:结合了获取资源列表(GET)和创建资源(POST)的功能。
- 示例:
from rest_framework.generics import ListCreateAPIView
class MyModelListCreateView(ListCreateAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
7.RetrieveUpdateAPIView
- 功能:支持获取单个资源详情(GET)以及更新资源(PUT 和 PATCH)。
- 示例:
from rest_framework.generics import RetrieveUpdateAPIView
class MyModelRetrieveUpdateView(RetrieveUpdateAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
8.RetrieveDestroyAPIView
- 功能:支持获取单个资源详情(GET)和删除资源(DELETE)。
- 示例:
from rest_framework.generics import RetrieveDestroyAPIView
class MyModelRetrieveDestroyView(RetrieveDestroyAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
9.RetrieveUpdateDestroyAPIView
- 功能:集成了获取单个资源详情(GET)、更新资源(PUT 和 PATCH)和删除资源(DELETE)的操作。
- 示例:
from rest_framework.generics import RetrieveUpdateDestroyAPIView
class MyModelRetrieveUpdateDestroyView(RetrieveUpdateDestroyAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
Mixin
类和 Concrete View Classes
有着密切的关系。
Mixin classes
提供了特定的操作方法,如创建、读取、更新、删除和列表获取等。但它们本身并不构成完整的视图类,需要与其他类(如 GenericAPIView
)结合使用来构建完整的视图功能。
Concrete View Classes
则是已经整合了 Mixin
类和必要的基础功能的完整视图类。
在选择使用时,可以考虑以下几点:
- 如果您的需求比较简单和直接,并且符合某个
Concrete View Classes
所提供的默认行为,那么直接使用相应的Concrete View Classes
会更加便捷和高效。例如,如果您只需要实现创建资源的功能,且不需要对默认行为进行太多修改,那么CreateAPIView
就是一个很好的选择。 - 如果您的视图需要更复杂的自定义逻辑,或者需要组合多个
Mixin
类的功能以满足特定需求,那么可以从GenericAPIView
开始,并结合所需的Mixin
类来自定义视图类。 - 例如,如果您需要一个视图既能获取列表又能创建新资源,且还需要添加一些额外的自定义逻辑,那么可以选择从
GenericAPIView
结合ListModelMixin
和CreateModelMixin
来实现。
总的来说,优先考虑使用 Concrete View Classes
,只有在它们无法满足需求时,再考虑使用 Mixin
类来自定义视图。
自定义通用视图(略)
from rest_framework import generics
from rest_framework.mixins import ListModelMixin, CreateModelMixin
class CustomView(generics.GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = YourModel.objects.all()
serializer_class = YourSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
在上述示例中,定义了 CustomView 类,它继承自 generics.GenericAPIView 以及 ListModelMixin 和 CreateModelMixin 。
通过设置 queryset 和 serializer_class 属性来指定数据来源和序列化器。
然后,重写了 get 方法来处理获取列表的请求,调用了 ListModelMixin 的 list 方法。重写了 post 方法来处理创建新数据的请求,调用了 CreateModelMixin 的 create 方法。