https://blog.csdn.net/weixin_46451496/article/details/105285132
一 下载djangorestframework
pip install djangorestframework
二 创建应用
在django中创建应用api
python manage.py startapp api
此时项目结构:
mysite/manage.pymysite/__init__.pysettings.pyurls.pyasgi.pywsgi.pyapi/__init__.pyadmin.pyapps.pymigrations/__init__.pymodels.pytests.pyviews.py
三 配置
在项目的settings.py中将创建的应用api以及rest_framework添加到INSTALLED_APPS 中:
INSTALLED_APPS = [...'api','rest_framework',...]
四 创建模型类
在应用api/models.py中添加如下代码:
from django.db import modelsclass Inventory(models.Model):"""库存类"""type = models.CharField(max_length=125)m_number = models.CharField(max_length=125)def __str__(self):return self.m_numberclass Meta:db_table = 'inventory'verbose_name = '库存'@classmethoddef get_all(cls):return cls.objects.all()
4.1 执行数据库迁移
前提是将模型api添加到INSTALLED_APPS中,否则迁移不成功
python manage.py makemigrationspython manage.py migrate

此时数据库创建了对应的数据表(apiproinfo)—>数据库表命名是django默认命名方式:应用名模型类名小写
4.2 将测试数据插入数据库表中
五 新建Serializer
DRF框架支持两种实现数据接口的方式,一种是FBV(基于函数的视图),另一种是CBV(基于类的视图)。我们先看看*CBV的方式如何实现数据接口
首先我们要定义一些序列化程序。我们创建一个名为 api/serializers.py的文件,来用作我们的数据表示。
api/serializers.py
from rest_framework import serializersfrom inventory.models import Inventoryclass InventorySerializer(serializers.ModelSerializer):class Meta:model = Inventoryfields = ('type')
- fields里面是要显示的字段
- Serializer 实现继承HyperlinkedModelSerializer
请注意!!!
在这个例子中我们用到了超链接关系,使用 HyperlinkedModelSerializer。也可使用ModelSerializer,但超链接是好的RESTful设计。
上述代码是指定显示部分字段,如果显示全部字段:
from rest_framework import serializersfrom inventory.models import Inventoryclass InventorySerializer(serializers.ModelSerializer):class Meta:model = Inventoryfields = '__all__'
重要的是要记住,ModelSerializer类并不会做任何特别神奇的事情,它们只是创建序列化器类的快捷方式:
- 一组自动确定的字段。
- 默认简单实现的create()和update()方法。
注意:当使用HyperlinkedModelSerializer的时候不能使用 fields = '__all__',不然会报错,错误信息如下:
Could not resolve URL for hyperlinked relationship using view name "proinfo-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
解决办法:
(方法一)不使用HyperlinkedModelSerializer,而使用ModelSerializer,
(方法二)当要显示所有字段时,全部写在fields里面
六 基于类的视图(CBV)
使用基于类的视图
views.py
from inventory.serializers import InventorySerializerclass InventoryList(APIView):def get(self,request,format = None):snippets = Inventory.objects.all()serializer = InventorySerializer(snippets, many=True)return Response(serializer.data)def post(self,request,format=None):serializer = InventorySerializer(data=request.data)if serializer.is_valid():serializer.save()return Response(serializer.data, status=status.HTTP_201_CREATED)return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
应用的urls.py
from inventory import viewsurlpatterns = [path('',views.InventoryList.as_view(),name='inventory_list'),]
serializers.py
from rest_framework import serializersfrom inventory.models import Inventoryclass InventorySerializer(serializers.ModelSerializer):class Meta:model = Inventoryfields = '__all__'
使用混合(mixins)
使用基于类视图的最大优势之一是它可以轻松地创建可复用的行为。
到目前为止,我们使用的创建/获取/更新/删除操作和我们创建的任何基于模型的API视图非常相似。这些常见的行为是在REST框架的mixin类中实现的。
views.py
from inventory.models import Inventoryfrom inventory.serializers import InventorySerializerfrom rest_framework import status, mixins, genericsclass InventoryList(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView):queryset = Inventory.objects.all()serializer_class = InventorySerializerdef get(self, request, *args, **kwargs):return self.list(request, *args, **kwargs)def post(self, request, *args, **kwargs):return self.create(request, *args, **kwargs)
使用通用的基于类的视图
通过使用mixin类,我们使用更少的代码重写了这些视图,但我们还可以再进一步。REST框架提供了一组已经混合好(mixed-in)的通用视图,我们可以使用它来简化我们的views.py模块。
from rest_framework import genericsclass InventoryList(generics.ListCreateAPIView):queryset = Inventory.objects.all()serializer_class = InventorySerializer
如此简洁。我们可以使用很多现成的代码,让我们的代码看起来非常清晰、简洁,地道的Django。
用于查询数据库中数据
打开api/views.py
from rest_framework import viewsetsfrom .models import ProInfofrom .serializers import ProInfoSerializer# Create your views here.class ProInfoViewSet(viewsets.ModelViewSet):queryset = ProInfo.objects.all()[:10] # 查询数据表前10条信息# 指定序列化对应的类serializer_class = ProInfoSerializer
其中:
queryset指定数据源serializer_class指定要序列化的类,即上面自定义的序列化类:ProInfoSerializer
7 启动项目
python manage.py runserver
输入:http://127.0.0.1:8000/inventory/ 可以看到当前应用inventory下面的所有的数据接口(如果写了多个的话)
8 补充:基于函数的视图(FBV)
api/serializers.py
from rest_framework import serializersfrom inventory.models import Inventoryclass InventorySerializer(serializers.ModelSerializer):class Meta:model = Inventoryfields = '__all__'
api/views.py
from django.http import HttpResponsefrom django.views.decorators.csrf import csrf_exemptfrom rest_framework import statusfrom rest_framework.decorators import api_viewfrom rest_framework.parsers import JSONParserfrom rest_framework.response import Responsefrom inventory.models import Inventoryfrom inventory.serializers import InventorySerializer@api_view(['GET','POST'])def inventory_list(request):"""列出所有的code inventory,或创建一个新的inventory。"""if request.method == 'GET':snippets = Inventory.objects.all()serializer = InventorySerializer(snippets, many=True)return Response(serializer.data)elif request.method == 'POST':serializer = InventorySerializer(data=request.data)if serializer.is_valid():serializer.save()return Response(serializer.data, status=status.HTTP_201_CREATED)return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
项目的/urls.py
from django.contrib import adminfrom django.urls import path,includeurlpatterns = [path('admin/', admin.site.urls),path('inventory/', include('inventory.urls')),]
应用的/urls.py
from django.urls import pathfrom inventory import viewsapp_name = 'inventory'urlpatterns = [path('',views.inventory_list,name='inventory_list'),path('<str:pk>/', views.inventory_detail,name='inventory_detail'),]
访问:http://127.0.0.1:8000/inventory/
9 请求与响应
https://q1mi.github.io/Django-REST-framework-documentation/tutorial/2-requests-and-responses_zh/
九 RESTful架构和DRF进阶
9.1 分页
在使用GET请求获取资源列表时,我们通常不会一次性的加载所有的数据,除非数据量真的很小。大多数获取资源列表的操作都支持数据分页展示,也就说我们可以通过指定页码(或类似于页码的标识)和页面大小(一次加载多少条数据)来获取不同的数据。我们可以通过对QuerySet对象的切片操作来实现分页,也可以利用Django框架封装的Paginator和Page对象来实现分页。使用DRF时,可以在Django配置文件中修改RESTFRAMEWORK并配置默认的分页类和页面大小来实现分页,如下所示。
**_settings.py**
REST_FRAMEWORK = {# 一页十条'PAGE_SIZE': 10,'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination'}
效果:
