我尝试使用Django REST Framework创建API

这个问题的背景信息

在以前,我们考虑将前端框架如React和Flutter与Django的Web应用程序开发相结合。这次,我们学习了使用Django REST Framework来实现前端和后端之间的交互,通过RESTful API的方式完成记录。

借此机会,我借鉴了先人们的智慧,并感激不尽地解决了一些问题。非常抱歉,作为个人备忘,我会将这些总结记录在这里。

首先

我参考了チグサさん的博客《チグサウェブ》的文章,利用Django REST Framework创建了RESTful API。它非常简明易懂,强烈推荐给即将学习此方面知识的人。

这次与Chigusa小姐的文章不同,我们省略了在docker中构建环境以及在Django中使用的数据库的更改。

以下是所使用环境的版本:

Windows 11 Pro 22H2
Python 3.12.0
Django 4.2.6
Django REST Framework 3.14.0
SQLite 3.43.1

 

API 的意思是什么?

应用程序编程接口的简称。
我们要创建的是能够通过HTTP或HTTPS通信进行数据交换的Web API。

Django REST Framework是什么?

Django REST Framework(DRF)是专门用于开发RESTful API的Django框架。使用DRF可以创建更加RESTful的Web应用程序。

使用Django REST Framework,能够轻松地在Django框架中实现API,它遵循REST原则的HTTP调用接口。在实现后端API服务器时非常方便。

 

1. 构建Python虚拟环境

使用venv在Python环境中创建虚拟环境。(假设已经搭建好了Python执行环境。)
执行以下命令。

python -m venv venv
请自行指定第二个“venv”的虚拟环境名称。
rootvenvIncludeLibScriptspyvenv.cfg

使用以下命令启用虚拟环境。

cd venv\Scripts
activate.bat

# rootディレクトリに戻る
(venv) cd ../..

使用下面的命令来升级pip。

(venv) python -m install --upgrade pip

2. Django的安装

用以下指令安装Django。

(venv) pip install django

 

创建Django项目

通过以下命令,我们创建一个Django项目。
最后一个点(.)表示在同一层级创建项目文件。

(venv) django-admin startproject djangoApiApp .
请自由指定“djangoApiApp”作为项目名称。
rootdjangoApiApp  # 追加
__pycache____init__.pyasgi.pysettings.pywsgi.pyvenvIncludeLibScriptspyvenv.cfg
db.sqlite3
manage.py

4. Django 数据库设置

由于sqlite3已经被默认指定,所以这次我们将继续使用它。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
要将MySQL或PostgreSQL更改为Django,请查阅Django官方文档。

我将修改语言和时区设置。

LANGUAGE_CODE = 'ja'       # 修正

TIME_ZONE = 'Asia/Tokyo'   # 修正
设定文件中包含着诸如SECRET_KEY和数据库连接信息等机密信息。将其直接推送到GitHub等公开仓库中是非常危险的。

这次,我们将使用方便的django-environ作为管理这些工具的工具。

安装 django-environ

因为django-environ是一个外部模块,所以需要安装它。
在Python环境中运行Django应用程序时,请执行以下命令。

(venv) pip install django-environ

安装仅需这一步骤。

 

创建和描述.env文件

在与manage.py同一层目录(在本次配置中为django项目的根目录)下创建名为“.env”的文件。

rootdjangoApiApp__pycache____init__.pyasgi.pysettings.pywsgi.pyvenvIncludeLibScriptspyvenv.cfg
.env              # 追加
db.sqlite3
manage.py

将环境变量等机密信息分离到这个文件中。

SECRET_KEY=django-insecure-*************************************
DEBUG=True

DATABASE_ENGINE=django.db.backends.sqlite3  # 使用するDBのエンジン(sqlite3ならdjango.db.backends.sqlite3)
DATABASE_DB=db.sqlite3                      # データベース名(sqlite3ならdb.sqlite3)
DATABASE_USER=django_user                   # defaultのままで可
DATABASE_PASSWORD=password                  # defaultのままで可
DATABASE_HOST=localhost                     # defaultのままで可
DATABASE_PORT=5432                          # defaultのままで可

在中文中请注意,在 = 前后加入半角空格或用单引号括住字符串都会导致错误。

除此之外,我们还要注意不要将不应该被他人知道的信息,如API密钥等,包含在源代码中。

在settings.py中调用环境变量。

在settings.py文件中调用.env文件中的环境变量。

import os                       # 追加
import environ                  # 追加
 
env = environ.Env()             # 追加
env.read_env('.env')            # 追加
 
SECRET_KEY = env('SECRET_KEY')  # 修正
DEBUG = env('DEBUG')            # 修正
 
DATABASES = {
    'default': {
        'ENGINE': env.get_value('DATABASE_ENGINE', default='django.db.backends.sqlite3'),      # 修正
        'NAME': env.get_value('DATABASE_DB', default=os.path.join(BASE_DIR, 'db.sqlite3')),    # 修正
        'USER': env.get_value('DATABASE_USER', default='django_user'),                         # 追加
        'PASSWORD': env.get_value('DATABASE_PASSWORD', default='password'),                    # 追加
        'HOST': env.get_value('DATABASE_HOST', default='localhost'),                           # 追加
        'PORT': env.get_value('DATABASE_PORT', default='5432'),                                # 追加
    }
}

这个就是!

安装 Django REST Framework

在运行Django应用程序的Python环境中安装Django REST框架。

(venv) pip install djangorestframework

6.添加和设置应用

使用以下命令,将应用程序添加到Django项目中。
我们将实现一个以产品主控为基础的应用程序,并开发API。

(venv) python manage.py startapp products
rootdjangoApiApp__pycache____init__.pyasgi.pysettings.pywsgi.pyproducts       # 追加
__pycache__migtarions__init__.pyadmin.pyapps.pymodels.pytests.pyviews.pyvenvIncludeLibScriptspyvenv.cfg
.env
db.sqlite3
manage.py

在Django项目的settings.py文件中,添加应用程序。

INSTALLED_APPS = [
...
    'rest_framework',  # 追加
    'products',        # 追加
]
为了使用Django REST Framework,需要指定”rest_framework”。

创建模型和表。

根据表格定义创建适配的模型。
本次我们假设了一个商品模型。

# 以下を追加
class Product(models.Model):

    name = models.CharField(max_length=200)
    price = models.IntegerField()

使用以下命令创建迁移文件。

(venv) python manage.py makemigrations products

以下的文件将自动创建。

# Generated by Django 4.0.3 on 2022-04-06 13:44

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Product',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=200)),
                ('price', models.IntegerField()),
            ],
        ),
    ]

使用以下命令来执行迁移并创建表。

(venv) python manage.py migrate

在管理页面上进行检查

我们先从Django的管理界面进行确认。
首先,我们要创建一个用于登录管理界面的用户。

执行以下命令。

(venv) python manage.py createsuperuser
请提供您的用户名、电子邮件地址和密码,根据您的意愿进行任意设定。

使用以下命令启动开发服务器。

(venv) python manage.py runserver

请访问以下网址。

http://localhost:8000/admin/
スクリーンショット 2023-10-07 210240.png
スクリーンショット 2023-10-07 181116.png

为了能够编辑本次创建的商品主数据表,需要修改以下文件。

from django.contrib import admin

# Register your models here.

from .models import Product   # 追加

admin.site.register(Product)  # 追加
スクリーンショット 2023-10-07 181303.png
スクリーンショット 2023-10-07 181410.png
スクリーンショット 2023-10-07 181428.png

为了显示姓名,我们将修改模型。

from django.db import models

# Create your models here.

class Product(models.Model):

    name = models.CharField(max_length=200)
    price = models.IntegerField()

    # 以下を追加
    def __str__(self):
        return self.name
スクリーンショット 2023-10-07 181538.png
您可以通过管理界面来确认API的运行情况。

创建一个名为Serializer的类。

为了在API中进行数据交换,需要设置一个叫做Serializer(序列化器)的东西,可以创建以下文件。

# 以下を追加
from rest_framework import serializers
from .models import Product


class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['name', 'price']
rootdjangoApiApp__pycache____init__.pyasgi.pysettings.pywsgi.pyproducts__pycache__migtarions__init__.pyadmin.pyapps.pymodels.pyserializers.pytests.pyviews.pyvenvIncludeLibScriptspyvenv.cfg
.env
db.sqlite3
manage.py

Django REST Framework的最大特点就是其Serializer,这一点并非夸大其词。
关于Serializer的说明,请参考”Django REST Framework的特点(Serializer)”部分。

 

9. 创建视图

使用ViewSet来实现API的处理。
通过这样做,例如可以处理获取列表或详细数据、新建、更新、删除等操作。

在这里,使用ModelViewSet来实现如下。

# 以下を上書き
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer


class ProductViewSet(viewsets.ModelViewSet):

    queryset = Product.objects.all()
    serializer_class = ProductSerializer

ModelViewSet提供以下选项:

list()
retrieve()
create()
update()
partial_update()
destroy()

10. 网址的添加 de

将调用API所需的URL添加到应用程序的urls.py中。
将ViewSet注册到路由器中。

# 以下を追加
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ProductViewSet

router = DefaultRouter()
router.register('products', ProductViewSet)

urlpatterns = [
    path('', include(router.urls)),
]
rootdjangoApiApp__pycache____init__.pyasgi.pysettings.pywsgi.pyproducts__pycache__migtarions__init__.pyadmin.pyapps.pymodels.pyserializers.pytests.pyurls.py        # 追加
views.pyvenvIncludeLibScriptspyvenv.cfg
.env
db.sqlite3
manage.py

在django项目的urls.py中进行添加,路径可以任意指定。本例中我们将路径指定为“products/”。

from django.contrib import admin
from django.urls import path, include  # includeを追加

urlpatterns = [
    path('admin/', admin.site.urls),

    # API
    path('products/', include('products.urls')),  # 追加
]

11. 确认 API

API界面

如果尚未启动,请使用以下命令启动开发服务器。

(venv) python manage.py runserver

点击下面的链接。

http://localhost:8000/products/
スクリーンショット 2023-10-07 183500.png
在这个画面上可以进行API的确认,非常方便。

通过curl命令或其他方式访问API时,可以了解到在实际使用中可以获取到JSON格式的数据。

(venv) curl http://localhost:8000/products/

# {"products":"http://localhost:8000/products/products/"}

数据编辑

访问用于显示列表的URL。

http://localhost:8000/products/products/
スクリーンショット 2023-10-07 183609.png

访问URL以显示详细信息(在末尾指定ID)。

http://localhost:8000/products/products/1/
スクリーンショット 2023-10-07 183658.png
这些屏幕上可以进行的操作也可以通过API来实现。

利用最少的代码实现了处理列表、详细信息、新建、编辑和删除的API。

关于ViewSet。

API视图

可以创建不与模型相关联的视图。
这是使用APIView类实现返回虚拟数据的API的示例。

from rest_framework.views import APIView      # 追加
from rest_framework.response import Response  # 追加

...
# 以下を追加
class ProductDummyApiView(APIView):

    def get(self, request, format=None):
        return Response({"name": "DUMMY!"})   # ダミーデータを返却
在继承APIView的类中,需要定义get或者post方法。
当通过HTTP的GET访问时,会调用get方法。

我要添加一个URL。

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ProductViewSet, ProductDummyApiView  # ProductDummyApiViewを追加

router = DefaultRouter()
router.register('products', ProductViewSet) 

urlpatterns = [
    path('', include(router.urls)),

    path("dummy/", ProductDummyApiView.as_view()),  # 追加
]

请访问以下的URL链接。

http://localhost:8000/products/dummy/
スクリーンショット 2023-10-07 183851.png

API视图

以下是基于函数的api_view的实现示例,用于显示模型数据列表。

from rest_framework.decorators import api_view  # 追加

...
# 以下を追加
@api_view(['GET'])
def product_list(request):

    if request.method == 'GET':
        products = Product.objects.all()
        serializer = ProductSerializer(products, many=True)
        return Response(serializer.data)

我们可以使用Model和Serializer来处理返回列表的操作,就像ModelViewSet一样。

添加URL。

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ProductViewSet, ProductDummyApiView, product_list  # product_listを追加

router = DefaultRouter()
router.register('products', ProductViewSet)

urlpatterns = [
    path('', include(router.urls)),
    path("dummy/", ProductDummyApiView.as_view()),

    path('list/', product_list),  # 追加
]

请访问以下网址。

http://localhost:8000/products/list/
スクリーンショット 2023-10-07 184221.png
有多种方法可以选择,但是实施起来非常简单,非常方便。
另外还有其他功能,请查阅官方网站的文档。

这次的源代码已经提交到GitHub了。

 


请以中文为母语的方式重新表述以下内容,只需提供一个选项:

参考资料

 


(编辑后记)

这次我尝试使用Django REST Framework(DRF)来创建一个RESTful的API。实现起来很简单,而且通过界面可以方便地进行确认,非常用户友好。
在创建后端API时,我发现DRF是一个很好的选择之一。

根据这些步骤,我将继续使用Django来创建Web应用程序。
希望对大家有所帮助。

我想在今后的工作中,开始开发结合React或Flutter的前端Web应用程序。但是我在选择其中一种时还在犹豫,因此我希望在仔细考虑它们的优缺点后做出决定。

bannerAds