Django DRF接口开发

网站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 类。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,561评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,218评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,162评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,470评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,550评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,806评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,951评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,712评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,166评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,510评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,643评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,306评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,930评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,745评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,983评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,351评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,509评论 2 348

推荐阅读更多精彩内容