我用Django REST框架创建了一个API

首先

在尝试Vue.js+Django REST framework之前,首先要使用Django REST framework来实现API。

开发环境

$ python --version
Python 3.5.1

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.2
BuildVersion:   18C54

创建项目

我要创建一个Django项目。

# Djagoをインストール
pip install django

# プロジェクトを作成
django-admin startproject myproject

cd myproject

# 起動
python manage.py runserver
myproject
|_ myproject
|_ manage.py
|_ db.sqlite3

请确认屏幕是否显示了 http://localhost:8000/。

screencapture-localhost-8000-2018-12-17-13_02_38.png

Django REST 框架

设定

首先需要安装Django REST框架。

pip install django-rest-framework

在先前创建的项目的settings.py文件中添加rest_framework。

...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
]
...

接下来,我们将设置API的终点。

from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url
from rest_framework import routers

router = routers.DefaultRouter()

urlpatterns = [
    path('admin/', admin.site.urls),
    url('api/', include(router.urls)),
]

我将在这里确认Django REST框架是否正常运行。
只需在http://localhost:8000/api 上执行以下页面即可。

screencapture-localhost-8000-api-2018-12-17-13_02_29.png

增加应用程序

使用以下的django-admin命令来创建应用程序。

django-admin startapp myapp
myproject
|_ myproject
   |_ __init__.py
   |_ settings.py
   |_ urls.py
   |_ wsgi.py
|_ myapp
   |_ migrations
   |_ __init__.py
   |_ admin.py
   |_ apps.py
   |_ models.py
   |_ tests.py
   |_ views.py
|_ manage.py
|_ db.sqlite3

将应用程序添加到settings.py文件中。

...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'myapp',
]
...

我们将从这里开始实施Galilei API。

模特
or
时装模特

from django.db import models


class Spot(models.Model):
    # 名前
    name = models.CharField(max_length=50)
    # カテゴリー
    category = models.CharField(max_length=5, blank=True)
    # ジャンル
    genre = models.CharField(max_length=50, blank=True)
    # 都道府県
    address_prefecture = models.CharField(max_length=10, blank=True)
    # 市区町村
    address_city = models.CharField(max_length=10, blank=True)
    # 丁目番地等
    address_street = models.CharField(max_length=100, blank=True)
    # 緯度
    latitude = models.CharField(max_length=50, blank=True)
    # 経度
    longitude = models.CharField(max_length=50, blank=True)
    # 作成日
    created_at = models.DateTimeField(auto_now_add=True)
    # 更新日
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ('created_at',)

使用以下命令进行迁移(数据库继续使用默认的SQLite)。

python manage.py makemigrations
python manage.py migrate

序列化器

from rest_framework import serializers
from .models import Spot


class SpotListSerializer(serializers.ModelSerializer):
    # 名前
    name = serializers.CharField(max_length=50)
    # カテゴリー
    category = serializers.CharField(max_length=5, allow_blank=True)
    # 都道府県
    address_prefecture = serializers.CharField(max_length=10, allow_blank=True)

    class Meta:
        model = Spot
        fields = ('id', 'name', 'category', 'address_prefecture')


class SpotSerializer(serializers.ModelSerializer):
    # 名前
    name = serializers.CharField(max_length=50)
    # カテゴリー
    category = serializers.CharField(max_length=5, allow_blank=True)
    # ジャンル
    genre = serializers.CharField(max_length=50, allow_blank=True)
    # 都道府県
    address_prefecture = serializers.CharField(max_length=10, allow_blank=True)
    # 市区町村
    address_city = serializers.CharField(max_length=10, allow_blank=True)
    # 丁目番地等
    address_street = serializers.CharField(max_length=100, allow_blank=True)
    # 緯度
    latitude = serializers.CharField(max_length=50, allow_blank=True)
    # 経度
    longitude = serializers.CharField(max_length=50, allow_blank=True)

    class Meta:
        model = Spot
        fields = (
            'name', 'category', 'genre', 'address_prefecture', 'address_city', 'address_street', 'latitude',
            'longitude')

渲染器

因为我想要以Json的形式获取,所以将该处理过程整理到renderers.py中。

import json
from rest_framework.renderers import JSONRenderer


class SpotJSONRenderer(JSONRenderer):
    charset = 'utf-8'

    def render(self, data, accepted_media_type=None, renderer_context=None):
        return json.dumps({
            'spots': data
        })

观点

from rest_framework import status
from rest_framework.generics import ListAPIView, RetrieveAPIView
from rest_framework.permissions import AllowAny
from rest_framework.response import Response

from .models import Spot
from .renderers import SpotJSONRenderer
from .serializers import SpotListSerializer, SpotSerializer


class SpotListApiView(ListAPIView):
    model = Spot
    queryset = Spot.objects.all()
    permission_classes = (AllowAny, )
    renderer_classes = (SpotJSONRenderer, )
    serializer_class = SpotListSerializer


class SpotRetrieveApiView(RetrieveAPIView):
    permission_classes = (AllowAny, )
    renderer_classes = (SpotJSONRenderer, )
    serializer_class = SpotSerializer

    def retrieve(self, request, spot_id, *args, **kwargs):
        spot = Spot.objects.get(id=spot_id)
        serializer = self.serializer_class(spot)

        return Response(serializer.data, status=status.HTTP_200_OK)

网址

定义 API 的端点。

from django.conf.urls import url
from .views import SpotListApiView, SpotRetrieveApiView

app_name = 'myapp'
urlpatterns = [
    url(r'^spots/$', SpotListApiView.as_view()),
    url(r'^spots/(?P<spot_id>\w+)/?$', SpotRetrieveApiView.as_view()),
]

我将更新myproject的urls.py文件。

from django.conf.urls import include, url
from django.contrib import admin
from django.urls import path
from rest_framework import routers
from spot import urls

router = routers.DefaultRouter()

urlpatterns = [
    path('admin/', admin.site.urls),
    url('api/', include(router.urls)),
    url('api/', include(urls, namespace='spot')),
]

为了确认目前的实施情况,暂时添加一些数据。

pip install ipyhton
python manage.py shell

In [1]: from myapp.models import Spot

In [2]: Spot.objects.create(name="秋葉原UDX", category="オフィス", genre="" , address_prefecture="東京都", address_city="千代田区", address_street="外神田4丁目14-1", latitude="35.700689", longitude="139.772498")                                                  
Out[2]: <Spot: Spot object (1)>

In [3]: Spot.objects.create(name="東京タワー", category="観光地", genre="" , address_prefecture="東京都", address_city="港区", address_street="芝公園4丁目2-8", latitude="35.658816", longitude="139.745476")                                                        
Out[3]: <Spot: Spot object (2)>

In [4]: Spot.objects.create(name="東京スカイツリー", category="観光地", genre="" , address_prefecture="東京都", address_city="墨田区", address_street="押上1丁目1-2", latitude="35.710385", longitude="139.810743")                                                  
Out[4]: <Spot: Spot object (3)>

In [5]: quit()

当您在浏览器中打开 http://localhost:8000/api/spots/2,您可以确认结果。

スクリーンショット 2018-12-17 19.20.01.png

结束

起初只是GET请求,但我认为很容易实现了API。
大家都应该用Django来实现API!

请参考以下资料

Django REST 框架
可爱猫咪网页应用 Django + VueJs — 使用 DRF 创建 REST API

bannerAds