REST framework-通用视图[Generic views]

Django's generic views... were developed as a shortcut for common usage patterns... They take certain common idioms and patterns found in view development and abstract them so that you can quickly write common views of data without having to repeat yourself.

基于类的视图的主要优点之一是它们允许您编写可重用行为的部分。REST框架通过提供许多预构建的视图来利用这一点,这些视图提供了常用的模式。

通过REST框架提供的通用视图,可以快速构建与数据库模型紧密映射的API视图。

如果泛型视图不适合自己的 API 的需求,可以使用常规类,或者重用泛型视图使用的 mixin 和基类来组合成一组可重用的泛型视图。

python 复制代码
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, 应用于过滤查询集的过滤器后端类的列表。默认为与设置相同的值
    示例代码:
python 复制代码
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 包括:

  1. ListModelMixin:提供了 list 方法,用于处理获取列表数据的请求。
  2. CreateModelMixin:包含 create 方法,用于处理创建新数据的请求。
  3. RetrieveModelMixin:提供 retrieve 方法,用于获取单个数据项。
  4. UpdateModelMixin:包含 update 方法,用于更新数据。
  5. DestroyModelMixin:提供 destroy 方法,用于删除数据。

这些 Mixins 提供的是动作方法,而不是直接定义如 get() 和 post() 这样的处理方法。这使得行为的组合更加灵活。

python 复制代码
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 在实际项目中创建一个简单的图书资源管理视图的示例代码:

python 复制代码
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 时,以下是一些需要注意的事项:

  1. 方法冲突:当多个 Mixins 组合使用时,要注意可能存在的方法名冲突。确保不同 Mixins 中的方法不会相互干扰或产生不一致的行为。
  2. 权限控制:根据具体的业务需求,合理设置视图的权限。Mixins 本身可能不会处理权限相关的逻辑,需要开发者自行添加权限验证代码。
  3. 数据一致性:在使用 CreateModelMixinUpdateModelMixin 等进行数据操作时,要确保数据的一致性和有效性验证。例如,检查必填字段、数据格式等。
  4. 错误处理:为 Mixins 中的操作添加适当的错误处理机制,以便在出现异常情况时能够向客户端返回清晰和有用的错误信息。
  5. 文档注释:由于 Mixins 增加了代码的复杂性,确保为视图类和相关方法添加清晰的文档注释,以便其他开发者能够理解其功能和使用方式。
  6. 版本控制:如果 API 有不同的版本,要考虑 Mixins 的使用是否在不同版本中保持一致或需要进行相应的调整。
  7. 性能优化:某些复杂的 Mixins 组合或频繁的数据操作可能会影响性能,需要进行性能测试和优化。
  8. 测试覆盖:对使用 Mixins 的视图进行充分的单元测试和集成测试,以确保其功能的正确性和稳定性。

Concrete View Classes(具体视图类)

主要的视图类:

  • CreateAPIView
  • ListAPIView
  • RetrieveAPIView
  • DestroyAPIView
  • UpdateAPIView
  • ListCreateAPIView
  • RetrieveUpdateAPIView
  • RetrieveDestroyAPIView
  • RetrieveUpdateDestroyAPIView

这些具体的通用视图类为常见的操作提供了现成的实现,除非您需要高度自定义的行为,否则通常在这个级别使用它们就可以满足需求。

例如,ListCreateAPIView 结合了获取列表(list)和创建(create)的功能,RetrieveUpdateDestroyAPIView 则涵盖了获取单个对象详情(retrieve)、更新(update)和删除(destroy)的操作。

python 复制代码
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 方法。
  • 示例:
python 复制代码
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 方法。
  • 示例:
python 复制代码
from rest_framework.generics import ListAPIView

class MyModelListView(ListAPIView):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

3.RetrieveAPIView

  • 功能:获取单个资源的详细信息,只支持 GET 方法。
  • 示例:
python 复制代码
from rest_framework.generics import RetrieveAPIView

class MyModelRetrieveView(RetrieveAPIView):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

4.DestroyAPIView

  • 功能:用于删除单个资源,只支持 DELETE 方法。
  • 示例:
python 复制代码
from rest_framework.generics import DestroyAPIView

class MyModelDestroyView(DestroyAPIView):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

5.UpdateAPIView

  • 功能:专门用于更新单个资源,只支持 PUT 和 PATCH 方法。
  • 示例:
python 复制代码
from rest_framework.generics import UpdateAPIView

class MyModelUpdateView(UpdateAPIView):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

6.ListCreateAPIView

  • 功能:结合了获取资源列表(GET)和创建资源(POST)的功能。
  • 示例:
python 复制代码
from rest_framework.generics import ListCreateAPIView

class MyModelListCreateView(ListCreateAPIView):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

7.RetrieveUpdateAPIView

  • 功能:支持获取单个资源详情(GET)以及更新资源(PUT 和 PATCH)。
  • 示例:
python 复制代码
from rest_framework.generics import RetrieveUpdateAPIView

class MyModelRetrieveUpdateView(RetrieveUpdateAPIView):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

8.RetrieveDestroyAPIView

  • 功能:支持获取单个资源详情(GET)和删除资源(DELETE)。
  • 示例:
python 复制代码
from rest_framework.generics import RetrieveDestroyAPIView

class MyModelRetrieveDestroyView(RetrieveDestroyAPIView):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

9.RetrieveUpdateDestroyAPIView

  • 功能:集成了获取单个资源详情(GET)、更新资源(PUT 和 PATCH)和删除资源(DELETE)的操作。
  • 示例:
python 复制代码
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 结合 ListModelMixinCreateModelMixin 来实现。

总的来说,优先考虑使用 Concrete View Classes ,只有在它们无法满足需求时,再考虑使用 Mixin 类来自定义视图。

自定义通用视图(略)

python 复制代码
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 方法。
相关推荐
好学近乎知o1 小时前
正则表达式(学习Django过程中可能涉及的)
学习·正则表达式·django
0zxm2 小时前
08 Django - Django媒体文件&静态文件&文件上传
数据库·后端·python·django·sqlite
0zxm20 小时前
06 - Django 视图view
网络·后端·python·django
凡人的AI工具箱1 天前
每天40分玩转Django:Django国际化
数据库·人工智能·后端·python·django·sqlite
isSamle2 天前
使用Vue+Django开发的旅游路书应用
前端·vue.js·django
╰つ゛木槿2 天前
Spring Boot与Django对比:哪个更适合做为Web服务器框架?
前端·spring boot·django
Null箘2 天前
从零创建一个 Django 项目
后端·python·django
江上挽风&sty2 天前
【Django篇】--动手实践Django基础知识
数据库·django·sqlite
云和数据.ChenGuang2 天前
Django 应用安装脚本 – 如何将应用添加到 INSTALLED_APPS 设置中 原创
数据库·django·sqlite
LuiChun3 天前
Django 模板分割及多语言支持案例【需求文档】-->【实现方案】
数据库·django·sqlite