网站Api开发
网站API也称接口,其实与网站的URL地址是同一个原理。当用户使用GET或者POST方式访问接口时,接口以JSON或者字符串的数据内容返回给用户,这是最主要的区别。网站的URL地址主要是返回HTML网页需要的变量信息。
实际快速开发API,可以使用Django Rest Framework(简称DRF)框架实现。首先需要安装,建议使用pip进行:
pip install djangorestframework
框架安装完成后,在项目app的index中创建 serializers.py 文件,用于定义DRF的 Serializer 类。构建项目目录后,接着在settings.py 分别设置数据连接信息和DRF框架的功能设置,配置代码如下:
# 数据库连接方式
DATABASES = {
'default':
{ 'ENGINE': 'django.db.backends.mysql',
'NAME': 'MyDjango_db',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT': '3306' }
}
# Django Rest Framework 框架的配置信息
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'index',
'rest_framework',
'index.apps.IndexConfig',
]
# 分页设置 自定义设置分页的数
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10
}
上述代码中:
1. 在INSTALLED_APPS 中添加功能配置,这样能使Django在运行过程中自动加载DRF的功能。
2. 配置RF属性,属性值以字典的形式表示,用于设置DRF的分页功能。
完成 settings.py 的配置后,下一步是定义项目的数据模型。在index的models.py中别分定义模型Type和Product,代码如下:
from django.db import models
# Create your models here.
class Type(models.Model):
id = models.AutoField('id', primary_key=True)
typeName = models.CharField('产品类型', max_length=25)
def __str__(self):
return self.typeName
class Product(models.Model):
id = models.AutoField('id', primary_key=True)
name = models.CharField('名称', max_length=50)
weight = models.CharField('重量', max_length=20)
size = models.CharField('尺寸', max_length=20)
type = models.ForeignKey(Type, on_delete=models.CASCADE, verbose_name='产品类型')
def __str__(self):
return self.name # 设置返回值
定义好的模型执行数据迁移,在项目的数据库中生成对应的数据表。
上述基本配置完成后,接下来使用DRF 快速开发PI。首先在项目应用 index 的 serializers.py 中分别定义Serializer 类和 ModelSerializer 类,代码如下:
from abc import ABC
from rest_framework import serializers
from .models import Product, Type
type_name = Type.objects.values('type_name').all()
TYPE_CHOICES = [item['id'] for item in type_name] # 定义下拉内容
class MySerializer(serializers.Serializer, ABC):
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(required=True, allow_blank=False, max_length=100)
weight = serializers.CharField(required=True, allow_blank=False, max_length=100)
size = serializers.CharField(required=True, allow_blank=False, max_length=100)
type = serializers.ChoiceField(choices=TYPE_CHOICES, default=1)
def create(self, validated_data): # 重写create函数,将API数据保存在数据表中
return Product.objects.create(**validated_data)
def update(self, instance, validated_data): # 重写 update 函数,将API数据保存在数据表中
instance.name = validated_data.get('name', instance.name)
instance.weight = validated_data.get('weight', instance.weight)
instance.size = validated_data.get('size', instance.size)
instance.type = validated_data.get('type', instance.type)
instance.save()
return instance
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
# fields = ('id', 'name', 'weight', 'size', 'type')
从上述代码可以看到,Serializer 类 和ModelSerializer类与Django的表单From 类和 ModelForom 类非常相似,若想进一步了解,在Python的安装目录中查看相应的源文件(\Lib\site-packages\rest_framework)
最后在 urls.py 和 views.py 中实现API开发。以定义好的ProductSerializer 类为列子,API功能实现代码如下:
# index 的urls.py
from django.urls import path
from . import views
urlpatterns = [
# 基于类的视图
path('', views.ProductClass.as_view()),
# 基于函数的视图
path('<int:pk>', views.product_def)
]
# index 的 views.py
from .models import Product
from .serializers import ProductSerializer
# APIView 方式生成视图
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.pagination import PageNumberPagination
# Create your views here.
class ProductClass(APIView):
def get(self, request):
queryset = Product.objects.all()
pg = PageNumberPagination() # 分页查询,需要在setting.py中设置REST_FRAMEWORK 属性
page_roles = pg.paginate_queryset(queryset=queryset, request=request, view=self)
serializer = ProductSerializer(instance=page_roles, many=True)
# serializer = ProductSerializer(instance=queryset, many=True) # 全表查询
return Response(serializer.data)
@staticmethod def post(request):
serializer = ProductSerializer(data=request.data) # 获取请求数据
if serializer.is_valid(): # 数据验证
serializer.save() # 数据保存
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@staticmethod def delete(request):
serializer = ProductSerializer(data=request.data['id']) # 获取请求数据
Product.objects.filter(id=serializer).delete()
def product_def(request, pk):
if request.method == 'GET':
queryset = Product.objects.filter(id=pk).all()
serializer = ProductSerializer(instance=queryset, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = ProductSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
queryset = Product.objects.filter(id=pk).all()
queryset.delete()
return Response(data='删除成功', status=status.HTTP_204_NO_CONTENT)
def product_del(request, pk):
try:
Product.objects.filter(id=pk).all().delete()
except Exception as e:
raise e
else:
return Response(data='删除成功', status=status.HTTP_204_NO_CONTENT)
在分析上述代码之前,首先了解一下DRF实现API开发的三种方式:
1.基于类的视图
2.基于函数的视图
3. 重构 ViewSets 类
其中,重构ViewSets 类实现过程过于复杂,一般不建议采用这种实现方式。在views.py 定义的 ProductClass 类分别居于类的视图和基于函数的视图,两种使用的说明如下:
1.基于类的视图:主要通过自定义类来实现视图,自定义类可以选择基础父类APIView、mixins 或 generics类只适用于ModelSerializer 类。上述代码朱啊哟继承APIView类,并且定义GET请求和POST请求的处理函数。GET函数主要讲模型Product的数据进行分页显示,POST函数讲用户发送的数据进行验证并入库处理。
2. 基于函数的视图:使用函数的方式实现API开发是三者中最为简单的方式,从函数product_def 的定义来看,该函数与Django定于的视图函数并没有什么区别。唯一的区别在与函数需要使用装饰器 api_view 并且数据是由DRF定义的对象进行返回的。
上述代码中,若用户发送GET请求,函数参数pk作为模型Prodect的查询条件,查询结果交给ProductSerializer 类实例化对象serializer进行数据格式转换,最后由DRF的Response 对象返回给用户。若用户发送POST请求,函数讲用户发送的数据进行验证并入库处理。
Django Rest Framework 框架的使用方式总结如下:
1. 在settings.py 中添加 DRF 功能,并对工嗯呢该进行分页配置。
2. 在APP中新建 serializers.py 文件并定义 Serializer 类或 ModelSerializer 类。
3. 在 urls.py 中定义路由地址。
4. 在 views.py 中定义视图函数, 三种定义方式分别为:基于类的视图、基于函数的视图和重构 ViewSets 类。