Django - RESTful使用指南

Django - RESTful使用指南

按照 Django 的常規(guī)方法當(dāng)然也可以實現(xiàn)REST,但有一種更快捷、強(qiáng)大的方法,那就是 Django REST framework.它是python的一個模塊,通過在 Django 里面配置就可以把 app 的 models 中的各個表實現(xiàn) RESTful API。具體實現(xiàn)方法如下:

安裝配置

# 實現(xiàn)restful的模塊
pip install djangorestframework==3.4.6
# 實現(xiàn)restful過濾功能的模塊
pip install django-filter

注意:這里使用的是3.4.6版本的 djangorestframework ,不同版本之間的 djangorestframework 有所不同,可以故意打錯版本號來查看 djangoframework 來查看有哪些版本。

安裝完畢以上兩個模塊后,還需要將 rest_framework 作為 APP 添加到 settings.py 文件中。

INSTALLED_APPS = [
    ....
    'rest_framework',
]

創(chuàng)建model

在 stu APP中創(chuàng)建兩張表,學(xué)生表和學(xué)生拓展信息表:

from django.db import models


# Create your models here.


class Student(models.Model):
    s_name = models.CharField(max_length=10)
    s_tel = models.CharField(max_length=11)

    class Meta:
        db_table = 'stu'


class StudentInfo(models.Model):
    i_addr = models.CharField(max_length=50)
    sid = models.OneToOneField(Student)

    class Meta:
        db_table = 'stu_info'

創(chuàng)建序列化類(Serializer)

創(chuàng)建序列化類的作用就是從你傳入的參數(shù)中提取出你需要的數(shù)據(jù),并把它轉(zhuǎn)化為 json 格式返回。這里在stu文件夾下創(chuàng)建serializers.py,并添加如下內(nèi)容:

from rest_framework import serializers
from stu.models import Student


class studentserializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ['id', 's_name', 's_tel']

    def to_representation(self, instance):
        data = super().to_representation(instance)
        try:
            data['i_addr'] = instance.studentinfo.i_addr
        except:
            data['i_addr'] = ''
        return data

添加url路由

創(chuàng)建一個能夠獲取學(xué)生模型中數(shù)據(jù)的 API 接口路由:

from django.conf.urls import url
from rest_framework.routers import SimpleRouter

from stu import views

# 創(chuàng)建一個一個Simplerouter對象
routers = SimpleRouter()

# 注冊獲取數(shù)據(jù)的API接口路由,執(zhí)行的視圖為'views.showallstu'
routers.register(r'student', views.showallstu)
urlpatterns = []

# 將注冊路由添加到django路由系統(tǒng)中
urlpatterns += routers.urls

url視圖處理

對于普通的url請求我們是在views.py中定義的一個函數(shù),但是對于RESTful是定義一個類,定義的showallstu類如下:

from django.shortcuts import render
from rest_framework import mixins, viewsets

# Create your views here.
from stu.models import Student
from stu.serializers import studentserializer


class showallstu(mixins.CreateModelMixin,  # 用于創(chuàng)建數(shù)據(jù)
                 mixins.DestroyModelMixin,  # 用于刪除數(shù)據(jù)
                 mixins.UpdateModelMixin,   # 用于更新數(shù)據(jù)
                 mixins.RetrieveModelMixin, # 用于顯示單個數(shù)據(jù)
                 mixins.ListModelMixin, # 用于顯示所有數(shù)據(jù)
                 viewsets.GenericViewSet):
    # 設(shè)置要返回的內(nèi)容queryset
    queryset = Student.objects.all()
    # 指定序列化類,將返回的內(nèi)容序列化為json格式       
    serializer_class = studentserializer

到這里一個支持對學(xué)生表進(jìn)行增、刪、查、改的數(shù)據(jù)接口就做好了,我們可以使用接口調(diào)試神器POSTMAN來進(jìn)行測試。

結(jié)果如下圖:

postman調(diào)試結(jié)果

<hr />

其他

自定義返回的json格式

通常對于一個請求,無論是否成功,我們都應(yīng)該返回一些東西來告知其請求的結(jié)果,對于上面的這種如果沒有數(shù)據(jù),那么返回的便是一個空列表,因此我們需要自定義JSONRenderer。

自定義JSONRenderer的方法很簡單,通過創(chuàng)建一個類去繼承JSONRenderer,并重構(gòu)其render方法,然后在settings.py文件中修改默認(rèn)使用的renderer類為我們自定義的類即可。

在項目目錄下創(chuàng)建文件夾utils,在utils目錄下創(chuàng)建rendererresponse.py文件,添加如下代碼自定義返回的json數(shù)據(jù):

# 導(dǎo)入控制返回的JSON格式的類
from rest_framework.renderers import JSONRenderer


class customrenderer(JSONRenderer):
    # 重構(gòu)render方法
    def render(self, data, accepted_media_type=None, renderer_context=None):
        if renderer_context:
            # 獲取需要返回的msg和code信息,沒有則賦值
            if isinstance(data, dict):
                msg = data.pop('msg', '請求成功')
                code = data.pop('code', 0)
            else:
                msg = '請求成功'
                code = 0
            # 重新構(gòu)建返回的JSON字典
            ret = {
                'msg': msg,
                'code': code,
                'data': data,
            }
            # 返回JSON數(shù)據(jù)
            return super().render(ret, accepted_media_type, renderer_context)
        else:
            return super().render(data, accepted_media_type, renderer_context)

settings.py文件中,修改默認(rèn)renderer類:

REST_FRAMEWORK = {

    # 修改默認(rèn)返回JSON的renderer的類
    'DEFAULT_RENDERER_CLASSES': (
        'utils.rendererresponse.customrenderer',
    ),
}

返回的json數(shù)據(jù)格式為:

自定義返回json格式

異常處理

自定義異常處理,一定需要繼承from rest_framework.exceptions import APIException 中的APIException,在編寫自己的異常處理的方法:

異常處理

空值處理

除了對異常錯誤的處理之外,我們還要對傳入數(shù)據(jù)是否是空值做處理。因為傳入空值服務(wù)器會返回錯誤,如下圖:

傳入空值報錯

如上圖,如果傳入的數(shù)據(jù)時空值的話,那么服務(wù)器就會返回一個 "This field may not be blank." 的報錯。這時候我們需要在serializer中定義s_name的序列化,指定錯誤的信息,為空的話,提示響應(yīng)的錯誤信息。

修改傳入空值后返回結(jié)果

實現(xiàn)分頁

通常用戶獲取的數(shù)據(jù)可能是有很多條的,我們是不可能所有的數(shù)據(jù)一起返回給用戶的,明顯那是不理智的,所以我們還需要對返回的數(shù)據(jù)做分頁處理。

用 restful 實現(xiàn)分頁很簡單,只需要在settings.py中設(shè)置默認(rèn)分頁的類和分頁的每頁顯示的條數(shù)即可:

REST_FRAMEWORK = {

    # 自定義返回的json格式
    'DEFAULT_RENDERER_CLASSES': (
        'utils.rendererresponse.customrenderer',
    ),

    # 設(shè)置分頁(固定表達(dá)式)
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',

    # 設(shè)置分頁每頁顯示的信息數(shù)
    'PAGE_SIZE': 3,
}

分頁后效果:

分頁

注意: ' count ' 表示總存在的信息的條數(shù), ' next '表示下一頁的地址,' pervious ' 表示上一頁的地址,null表示沒有上一頁??梢酝ㄟ^這幾個參數(shù)知道是否還有下一頁上一頁。

數(shù)據(jù)過濾

通常在用戶進(jìn)行搜索和獲取數(shù)據(jù)的時候都需要對數(shù)據(jù)進(jìn)行過濾,在 restful 中要實現(xiàn)數(shù)據(jù)的過濾其實也很簡單。先創(chuàng)建一個數(shù)據(jù)過濾的類,將可能用到的過濾方法都放到這個類下面,然后修改settings.py文件,添加默認(rèn)過濾規(guī)則,然后修改視圖函數(shù)指定過濾的類。

1.創(chuàng)建過濾的類

在utils目錄下創(chuàng)建filters.py文件,并添加如下內(nèi)容:

import django_filters
from rest_framework import filters
from stu.models import Student

class studentfilter(filters.FilterSet):
    # 表示以模糊搜索student表s_name中包含傳入的name參數(shù)中的數(shù)據(jù)
    name = django_filters.CharFilter('s_name', lookup_expr='icontains')

    # 在s_tel字段中精確搜索傳過來的tel參數(shù)的值,返回符合條件的結(jié)果
    tel = django_filters.CharFilter('s_tel')

    # 范圍搜索
    max_yuwen = django_filters.NumberFilter('s_yuwen', lookup_expr='lte')
    min_yuwen = django_filters.NumberFilter('s_yuwen', lookup_expr='gte')

    class Meta:
        model = Student
        fields = ['id', 's_name', 's_tel', 's_yuwen']
2.修改配置文件

修改settings.py配置,設(shè)置默認(rèn)過濾規(guī)則:

REST_FRAMEWORK = {
    # 設(shè)置過濾(固定寫法)
    'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',
                                'rest_framework.filters.SearchFilter',),
}

注意:在修改配置文件或者重構(gòu)rest_framework的這些操作的時候,一定要注意單詞拼寫一定要正確,這些很多都是固定寫法,如果寫錯了就可能導(dǎo)致不能運行出想要的結(jié)果。

3.修改視圖文件

修改視圖處理類,為其制定默認(rèn)過濾的類,也可以指定排序規(guī)則:

from django.shortcuts import render
from rest_framework import mixins, viewsets

# Create your views here.
from stu.models import Student
from stu.serializers import studentserializer
from utils.filters import studentfilter


class showallstu(mixins.CreateModelMixin,
                 mixins.DestroyModelMixin,
                 mixins.UpdateModelMixin,
                 mixins.RetrieveModelMixin,
                 mixins.ListModelMixin,
                 viewsets.GenericViewSet):
    queryset = Student.objects.all()
    # 定義序列化的類
    serializer_class = studentserializer
    # 定義過濾的類
    filter_class = studentfilter

    # 指定排序規(guī)則
    def get_queryset(self):
        query = self.queryset
        return query.order_by('-id')
練習(xí):

1.查名字中包含王的學(xué)習(xí)信息:

http://127.0.0.1:8000/stu/student/?name=

王姓的學(xué)生信息

2.查找電話號碼為911的學(xué)生信息:

http://127.0.0.1:8000/stu/student/?tel=911

電話查詢結(jié)果

3.查找語文成績小于60的所有學(xué)生信息:

http://127.0.0.1:8000/stu/student/?max_yuwen=60

成績小于60學(xué)生信息

4.查找語文成績在70到90之間的學(xué)生信息:

http://127.0.0.1:8000/stu/student/?min_yuwen=70&max_yuwen=90

成績在70-90分的學(xué)生信息

5.查找語文成績在70到90之間并姓王的學(xué)生信息:

http://127.0.0.1:8000/stu/student/?name=王&min_yuwen=70&max_yuwen=90

成績在70-90之間的王姓學(xué)生
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 切換到創(chuàng)建項目的目錄 cd C:\Users\admin\Desktop\DjangoProject創(chuàng)建名為pr...
    在努力中閱讀 3,541評論 2 3
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,838評論 18 399
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 4,033評論 0 11
  • 說起來很是荒謬,已近深夜,我竟固執(zhí)地不愿睡去。仿佛是睡了這一覺,這一生便也就結(jié)束了。 我在害怕,害怕睡著后一無所知...
    萌土豆閱讀 197評論 2 0
  • 我經(jīng)常打趣我媽讀書少,不愛讀書。她也經(jīng)?;貜?fù):“我年輕時候怎么不愛看?就是記不住啊。” 一回車上閑聊,她說起我們娘...
    海石一閱讀 1,818評論 15 13

友情鏈接更多精彩內(nèi)容