首页 > 其他 > 详细

斑马斑马-20-Django REST Framework (DRF)系列教程

时间:2020-07-05 16:10:18      阅读:52      评论:0      收藏:0      [点我收藏+]

一、RESTful

REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移。一种软件设计风格

1、RESTful API设计

  • 协议
    •   API与用户的通信协议,总是使用HTTPs协议
  • 域名
    •   尽量将API部署在专用域名之下 https://api.example.com
    •        也可以放在主域名之下  https://example.org/api
  • 版本
    •   将url版本号放入到url中 https://exmaple.com/v1/
  • 路径
    •   只能有名词,不能有动词 https://exmaple.com/v1/zoos
  • method
    •   GET(SELECT)  获取资源(一项、多项)
    •        POST (CREATE) 创建
    •        PUT(UPDATE)       在更新资源
    •        DELETE(DELETE) 删除资源
    •        PATCH(UPDATE)   更新资源(提供改变的属性)
    •        HEAD                          获取资源的元数据
    •        OPTIONS                    获取信息,关于资源的哪些属性是客户端可以改变的
  • 过滤
    •   ?limit=10:指定返回记录数量
    •        ?offset=10:偏移查询
    •        ?sortby=name:排序字段
  • 状态
    •   200 成功
    •        201 创建成功
    •        204 删除成功
    •        401 没有权限
    •   403 没有授权
    •        404 没有找到
    •        500 服务器内部错误
  • 错误处理
    •   {
    •              error:"错误信息"
    •        }
  • 返回结果
    •   json  

2、RESTful API案例

功能
请求方式
请求路径
获取所有书籍
GET
/books
创建单本书籍
POST
/books
获取单本书籍
GET
/books/{pk}
修改单本书籍
PUT
/books/{pk}
删除单本书籍
DELETE
/books/{pk}

3、创建Django项目

   1:使用MySQL数据库首先需要安装驱动程序    

pip install PyMySQL

 

  2:在Django的工程同名子目录的__init__.py文件中添加如下语句  

from pymysql import install_as_MySQLdb
install_as_MySQLdb()

  3:配置setting中的DATABASES配置信息

技术分享图片
DATABASES = {
    default: {
        ENGINE: django.db.backends.mysql,
        HOST: 39.99.213.203,  # 数据库主机
        PORT: 3306,  # 数据库端口
        USER: root,  # 数据库用户名
        PASSWORD: mysql,  # 数据库用户密码
        NAME: django_demo  # 数据库名字
    }
}
setting数据库配置

  4:在MySQL中创建数据库

create database django_demo default charset=utf8;

  5:创建应用booktest,在models.py 文件中定义模型类。

技术分享图片
from django.db import models

#定义图书模型类BookInfo
class BookInfo(models.Model):
    btitle = models.CharField(max_length=20, verbose_name=名称)
    bpub_date = models.DateField(verbose_name=发布日期)
    bread = models.IntegerField(default=0, verbose_name=阅读量)
    bcomment = models.IntegerField(default=0, verbose_name=评论量)
    is_delete = models.BooleanField(default=False, verbose_name=逻辑删除)

    class Meta:
        db_table = tb_books  # 指明数据库表名
        verbose_name = 图书  # 在admin站点中显示的名称
        verbose_name_plural = verbose_name  # 显示的复数名称

    def __str__(self):
        """定义每个数据对象的显示信息"""
        return self.btitle

#定义英雄模型类HeroInfo
class HeroInfo(models.Model):
    GENDER_CHOICES = (
        (0, female),
        (1, male)
    )
    hname = models.CharField(max_length=20, verbose_name=名称) 
    hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name=性别)  
    hcomment = models.CharField(max_length=200, null=True, verbose_name=描述信息) 
    hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name=图书)  # 外键
    is_delete = models.BooleanField(default=False, verbose_name=逻辑删除)

    class Meta:
        db_table = tb_heros
        verbose_name = 英雄
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.hname
定义模型类

  6:生成数据库  

  python manage.py makemigrations  

  python manage.py migrate

  ps:如果报django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.错误

技术分享图片

在Django的工程同名子目录的__init__.py文件中添加如下语句

技术分享图片
from pymysql import install_as_MySQLdb
import pymysql
pymysql.version_info = (1, 3, 13, "final", 0)
pymysql.install_as_MySQLdb()
__init__.py

   7:初始化数据

技术分享图片
insert into tb_books(btitle,bpub_date,bread,bcomment,is_delete) values
(射雕英雄传,1980-5-1,12,34,0),
(天龙八部,1986-7-24,36,40,0),
(笑傲江湖,1995-12-24,20,80,0),
(雪山飞狐,1987-11-11,58,24,0);
insert into tb_heros(hname,hgender,hbook_id,hcomment,is_delete) values
(郭靖,1,1,降龙十八掌,0),
(黄蓉,0,1,打狗棍法,0),
(黄药师,1,1,弹指神通,0),
(欧阳锋,1,1,蛤蟆功,0),
(梅超风,0,1,九阴白骨爪,0),
(乔峰,1,2,降龙十八掌,0),
(段誉,1,2,六脉神剑,0),
(虚竹,1,2,天山六阳掌,0),
(王语嫣,0,2,神仙姐姐,0),
(令狐冲,1,3,独孤九剑,0),
(任盈盈,0,3,弹琴,0),
(岳不群,1,3,华山剑法,0),
(东方不败,0,3,葵花宝典,0),
(胡斐,1,4,胡家刀法,0),
(苗若兰,0,4,黄衣,0),
(程灵素,0,4,医术,0),
(袁紫衣,0,4,六合拳,0);
View Code

二、功能实现 

1、利用CBV模式实现

  CBV(class base views) 就是在视图里使用类处理请求。

  1.1 项目同名的App路由中进行全局配置  

技术分享图片
from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include
from APP01 import url as app01_books_url


urlpatterns = [
    url(r^api/yango/v1/books/,include(app01_books_url))
]
url.py
api:表示接口
yango:表示项目名
v1:表示版本号
books:表示资源类
这时候会进一步进入到APP01下的url中
技术分享图片
from django.conf.urls import url
from . import views
urlpatterns=[
    url(r^info$,views.BookesAPIView.as_view()),
]
View Code

资源明细内容

info 表示获取所有

  1.2 获取所有书籍

技术分享图片
from django.shortcuts import render
from django.views import View
from .models import BookInfo
from datetime import datetime
from django.http import JsonResponse
‘‘‘
功能            请求方式    请求路径    
获取所有书籍    GET         /books
创建单本书籍    POST        /books
获取单本书籍    GET         /books/{pk}
修改单本书籍    PUT         /books/{pk}
删除单本书籍    DELETE      /books/{pk}
‘‘‘


#1,列表视图
class BookesAPIView(View):
    ‘‘‘
    查询所有屠苏,增加图书
    ‘‘‘
    def get(self,request):
        queryset=BookInfo.objects.all()
        book_list=[]
        for book in queryset:
            book_list.append({
                "id":book.id,
                "btitle":book.btitle,
                "bpub_date":book.bpub_date,
                "bread":book.bread,
                "bcomment":book.bcomment
            })
        return JsonResponse(book_list,safe=False)
View Code

  BookesAPIView中get方法,获取所有书籍数据

  技术分享图片

  1.3 完整版视图

技术分享图片
from django.shortcuts import render, HttpResponse
from django.views import View
from .models import BookInfo
from datetime import datetime
from django.http import JsonResponse
import json

‘‘‘
功能            请求方式    请求路径    
获取所有书籍    GET         /books
创建单本书籍    POST        /books
获取单本书籍    GET         /books/{pk}
修改单本书籍    PUT         /books/{pk}
删除单本书籍    DELETE      /books/{pk}
‘‘‘


# 1,列表视图
class BooksAPIView(View):
    ‘‘‘
    查询所有屠苏,增加图书
    ‘‘‘

    def get(self, request):
        """
        查询所有图书
        路由:GET /books/info/
        """
        queryset = BookInfo.objects.all()
        book_list = []
        for book in queryset:
            book_list.append({
                "id": book.id,
                "btitle": book.btitle,
                "bpub_date": book.bpub_date,
                "bread": book.bread,
                "bcomment": book.bcomment
            })
        return JsonResponse(book_list, safe=False)

    def post(self, request):
        """
        新增图书
        路由:POST /books/info/
        """
        json_bytes = request.body
        json_str = json_bytes.decode()
        book_dict = json.loads(json_str, encoding="utf-8")

        # 此处详细的校验参数省略

        book = BookInfo.objects.create(
            btitle=book_dict.get(btitle),
            bpub_date=datetime.strptime(book_dict.get(bpub_date), %Y-%m-%d).date()
        )

        return JsonResponse({
            "id": book.id,
            "btitle": book.btitle,
            "bpub_date": book.bpub_date,
            "bread": book.bread,
            "bcomment": book.bcomment
        }, status=201)


class BookAPIView(View):
    ‘‘‘
    查询所有屠苏,增加图书
    ‘‘‘

    def get(self, request, pk):
        """
        根据图书ID查询图书
        路由:GET /books/info/pk/
        """
        try:
            book = BookInfo.objects.get(id=pk)
        except BookInfo.DoesNotExist:
            return HttpResponse(status=404)

        return JsonResponse({
            "id": book.id,
            "btitle": book.btitle,
            "bpub_date": book.bpub_date,
            "bread": book.bread,
            "bcomment": book.bcomment
        }, status=201)

    def put(self, request, pk):
        """
        根据图书ID修改图书
        路由:PUT /books/info/pk/
        """
        try:
            book = BookInfo.objects.get(id=pk)
        except BookInfo.DoesNotExist:
            return HttpResponse(status=404)
        json_bytes = request.body
        json_str = json_bytes.decode()
        book_dict = json.loads(json_str)

        book.btitle = book_dict.get("btitle")
        book.save()

        return JsonResponse({
            "id": book.id,
            "btitle": book.btitle,
            "bpub_date": book.bpub_date,
            "bread": book.bread,
            "bcomment": book.bcomment
        })

    def delete(self, request, pk):
        """
        根据图书ID删除图书
        路由:DELETE /books/info/pk/
        """
        try:
            book = BookInfo.objects.get(id=pk)
        except BookInfo.DoesNotExist:
            return HttpResponse(status=404)
        book.delete()
        return JsonResponse({
            "id": book.id,
            "btitle": book.btitle,
            "bpub_date": book.bpub_date,
            "bread": book.bread,
            "bcomment": book.bcomment
        }, status=204)
view.py

  1.4 测试(Postman) 

1)获取所有图书数据 http://127.0.0.1:8000/api/yango/v1/books/info

技术分享图片
[
    {
        "id": 1,
        "btitle": "射雕英雄传",
        "bpub_date": "1980-05-01",
        "bread": 12,
        "bcomment": 34
    },
    {
        "id": 2,
        "btitle": "天龙八部",
        "bpub_date": "1986-07-24",
        "bread": 36,
        "bcomment": 40
    },
    {
        "id": 3,
        "btitle": "笑傲江湖",
        "bpub_date": "1995-12-24",
        "bread": 20,
        "bcomment": 80
    },
    {
        "id": 4,
        "btitle": "雪山飞狐",
        "bpub_date": "1987-11-11",
        "bread": 58,
        "bcomment": 24
    },
    {
        "id": 5,
        "btitle": "白马啸西风",
        "bpub_date": "2020-02-02",
        "bread": 0,
        "bcomment": 0
    },
    {
        "id": 7,
        "btitle": "连城诀",
        "bpub_date": "2020-02-02",
        "bread": 0,
        "bcomment": 0
    }
]
返回结果

2)获取单一图书数据 http://127.0.0.1:8000/api/yango/v1/books/info/1

技术分享图片
{
    "id": 1,
    "btitle": "射雕英雄传",
    "bpub_date": "1980-05-01",
    "bread": 12,
    "bcomment": 34
}
返回结果

3)新增图书数据 http://127.0.0.1:8000/api/yango/v1/books/info

技术分享图片
{
    "btitle":"连城诀",
    "bpub_date":"2020-02-02"
}
请求数据
技术分享图片
{
    "id": 7,
    "btitle": "连城诀",
    "bpub_date": "2020-02-02",
    "bread": 0,
    "bcomment": 0
}
返回结果

4)修改图书数据 http://127.0.0.1:8000/api/yango/v1/books/info/6/

技术分享图片
{
    "btitle":"白马啸西风1"
}
请求数据
技术分享图片
{
    "id": 6,
    "btitle": "白马啸西风1",
    "bpub_date": "2020-02-02",
    "bread": 0,
    "bcomment": 0
}
返回结果

5)删除图书数据 http://127.0.0.1:8000/api/yango/v1/books/info/6/

技术分享图片
{
    "id": null,
    "btitle": "白马啸西风1",
    "bpub_date": "2020-02-02",
    "bread": 0,
    "bcomment": 0
}
返回结果

三、代码上传 

可参考  集腋成裘-21-git使用-03进阶篇   2.4 多人开发

斑马斑马-20-Django REST Framework (DRF)系列教程

原文:https://www.cnblogs.com/YK2012/p/13227046.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!