使用之前的FCM项目做练习

1 通用类视图

django-rest-framework 针对各种类型的资源操作,提供了对应的通用类视图,这些通用类视图主要包括:

  • CreateAPIView:用于创建资源的 POST 请求。
  • ListAPIViewRetrieveAPIView:用于访问资源列表和单个资源的 GET 请求。
  • DestroyAPIView:用于删除资源的 DELETE 请求。
  • UpdateAPIView:用于更新资源的 PUT(全量更新)和 PATCH(部分更新)请求。

    2 视图集

    使用视图集的一个更大的好处,就是可以配合 django-rest-framework 提供的路由器(router),自动生成 API 的 URL,不需要我们再手工将 URL 模式和视图函数绑定了。所以大部分情况下,即使对资源只有一种操作,我们一般也会使用视图集。

所有视图集都要继承视图集的基类。视图集也有 2 个基类:ViewSet 和 GenericViewSet,前者是最基本的视图集类,后者拓展自前者,拓展了很多 Web 开发中的通用逻辑。

要注意一点的是,视图集基类提供的是除资源操作以外的通用逻辑(例如 HTTP 请求预处理、HTTP 响应后处理、认证、鉴权等),而对于资源的操作(如序列化、更新、删除资源等)则放在相应的 Mixin 混入类里。django-rest-framework 提供了资源操作的 5 个混入类,分别对应资源的创建、查询、更新、删除。

  • CreateModelMixin:提供 create 方法用于创建资源
  • ListModelMixin 和 RetrieveModelMixin:提供 list 和 retrieve,分别用于获取资源列表和单个资源
  • UpdateModelMixin:提供 update 方法用于更新资源
  • DestroyModelMixin:提供 destroy 方法用于删除资源

使用案例

查询inventory表中所有信息
models.py

  1. from django.db import models
  2. class Inventory(models.Model):
  3. """库存类"""
  4. type = models.CharField(max_length=125)
  5. m_number = models.CharField(max_length=125)
  6. m_name = models.CharField(max_length=125)
  7. m_cate = models.CharField(max_length=125)
  8. kuwei = models.CharField(max_length=125)
  9. quantity = models.IntegerField()
  10. limit = models.IntegerField()
  11. life_time = models.IntegerField()
  12. batch_number = models.IntegerField()
  13. price = models.IntegerField()
  14. total_price = models.IntegerField()
  15. supply_period = models.IntegerField()
  16. scarp = models.CharField(max_length=125)
  17. parts_classlification = models.CharField(max_length=125)
  18. person = models.CharField(max_length=125)
  19. comments = models.CharField(max_length=125)
  20. def __str__(self):
  21. return self.m_number
  22. class Meta:
  23. # 增加ordering,否则分页查询时出现warning
  24. # ordering = ['id']
  25. # 定义表名
  26. db_table = 'inventory'
  27. # 定义在管理后台显示的名称
  28. verbose_name = '库存'
  29. @classmethod
  30. def get_all(cls):
  31. return cls.objects.all()

serializers.py

  1. from rest_framework import serializers
  2. from inventory.models import Inventory
  3. class InventorySerializer(serializers.ModelSerializer):
  4. class Meta:
  5. model = Inventory
  6. fields = '__all__'

views.py

  1. from rest_framework import viewsets
  2. from inventory.models import Inventory
  3. from inventory.serializers import InventorySerializer
  4. class InventoryViewSet(viewsets.ModelViewSet):
  5. serializer_class = InventorySerializer
  6. queryset = Inventory.objects.all()

项目的urls.py

  1. from django.contrib import admin
  2. from django.urls import path,include
  3. urlpatterns = [
  4. path('admin/', admin.site.urls),
  5. path('', include('inventory.urls')),
  6. ]

应用的urls.py

  1. from rest_framework.routers import DefaultRouter
  2. from inventory.views import InventoryViewSet
  3. app_name = 'inventory'
  4. router = DefaultRouter()
  5. router.register(r'inventories', InventoryViewSet, basename='inventory')
  6. urlpatterns = router.urls

访问:http://127.0.0.1:8000/inventories/ 出现所有信息;同时,路由会自动增加一个 /inventories/:pk/ 的 URL 模式,其中 pk 为inventory表中主键 id。访问此 API 接口可以获得指定inventory id 的资源。
image.png


register() 方法有两个强制参数:

  • prefix - 用于此组路由的URL前缀。
  • viewset - 处理请求的viewset类。

还可以指定一个附加参数(可选):

  • base_name - 用于创建的URL名称的基本名称。如果不设置该参数,将根据视图集的queryset属性(如果有)来自动生成基本名称。注意,如果视图集不包括queryset属性,那么在注册视图集时必须设置base_name。

注意: base_name 参数用于指定视图名称模式的初始部分。在上面的例子中就是指 inventories


补充:路由器实例上的.urls属性只是一个URL模式的标准列表。对于如何添加这些URL,有很多不同的写法。
(1)例如,你可以将router.urls附加到现有视图的列表中…

  1. from rest_framework.routers import DefaultRouter
  2. from inventory.views import InventoryViewSet
  3. app_name = 'inventory'
  4. router = DefaultRouter()
  5. router.register(r'inventories', InventoryViewSet, basename='inventory-list')
  6. # urlpatterns = router.urls
  7. urlpatterns = [
  8. # 其他
  9. ]
  10. urlpatterns += router.urls

(2)你可以使用Django的include函数,像这样…

  1. from django.urls import path, include
  2. from rest_framework.routers import DefaultRouter
  3. from inventory.views import InventoryViewSet
  4. app_name = 'inventory'
  5. router = DefaultRouter()
  6. router.register(r'inventories', InventoryViewSet, basename='inventory-list')
  7. urlpatterns = [
  8. path('',include(router.urls)),
  9. ]