Django REST框架創建REST API

Django REST框架(DRF Django REST framework)是一個強大而靈活的工具包,用於構建Web API。在本教程中,我們將學習如何在短短15分鐘內使用Django REST框架構建CRUD API。

什麼是Django?

Django是一個免費的、開源的、基於Python的Web框架,它遵循模型-視圖-模板(MVT Model-View-Template)架構模式。它減少了網絡開發的麻煩,因此你可以專注於編寫你的應用程序,而不是重新發明車輪。

什麼是REST API?

REST API是系統暴露有用功能和數據的一種流行方式。REST是表示狀態轉移的意思,它可以由一個或多個資源組成,這些資源可以通過給定的URL訪問,並以各種格式返回,如JSON、圖片、HTML等。

Django REST框架

Django REST框架(DRF)是一個強大而靈活的工具包,用於構建Web APIs。它的主要優點是序列化更加容易。

Django REST框架是基於Django的基於類的視圖,所以如果你熟悉Django,它是一個很好的選擇。它採用了基於類的視圖、表單、模型驗證器、QuerySet等實現。

環境準備

# pip install django
# pip install django_rest_framework
$ django-admin startproject todo
$ django-admin startapp todo_api
$ python manage.py migrate

在todo/todo/settings.py文件內的INSTALLED_APPS中加入rest_framework和todo。

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

在todo/todo_api中創建serializers.py和urls.py文件,並按照下面的目錄結構配置添加新的文件。

├── todo
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
├── db.sqlite3
├── manage.py
└── todo_api
    ├── admin.py
    ├── serializers.py
    ├── __init__.py
    ├── models.py
    ├── urls.py
    └── views.py

請確保在你的 urls.py 文件中包含 rest_framework 和 URLs,如下所示。

# todo/todo/urls.py : Main urls.py
from django.contrib import admin
from django.urls import path, include
from todo_api import urls as todo_urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api-auth/', include('rest_framework.urls')),
    path('todos/', include(todo_urls)),
]

# todo/todo_api/urls.py : API urls.py
from django.conf.urls import url
from django.urls import path, include
from .views import (
    TodoListApiView,
)

urlpatterns = [
    path('api', TodoListApiView.as_view()),
]

# todo/todo_api/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework import permissions
from .models import Todo
from .serializers import TodoSerializer

class TodoListApiView(APIView):
    # add permission to check if user is authenticated
    permission_classes = [permissions.IsAuthenticated]

    # 1. List all
    def get(self, request, *args, **kwargs):
        '''
        List all the todo items for given requested user
        '''
        todos = Todo.objects.filter(user = request.user.id)
        serializer = TodoSerializer(todos, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    # 2. Create
    def post(self, request, *args, **kwargs):
        '''
        Create the Todo with given todo data
        '''
        data = {
            'task': request.data.get('task'), 
            'completed': request.data.get('completed'), 
            'user': request.user.id
        }
        serializer = TodoSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


# todo/todo_api/models.py
from django.db import models
from django.contrib.auth.models import User

class Todo(models.Model):
    task = models.CharField(max_length = 180)
    timestamp = models.DateTimeField(auto_now_add = True, auto_now = False, blank = True)
    completed = models.BooleanField(default = False, blank = True)
    updated = models.DateTimeField(auto_now = True, blank = True)
    user = models.ForeignKey(User, on_delete = models.CASCADE, blank = True, null = True)

    def __str__(self):
        return self.task


# todo/todo_api/models.py
from django.db import models
from django.conf import settings

class Todo(models.Model):
    task = models.CharField(max_length = 180)
    timestamp = models.DateTimeField(auto_now_add = True, auto_now = False, blank = True)
    completed = models.BooleanField(default = False, blank = True)
    updated = models.DateTimeField(auto_now = True, blank = True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete = models.CASCADE, blank = True, null = True)

    def __str__(self):
        return self.task

# todo/todo_api/serializers.py
from rest_framework import serializers
from .models import Todo
class TodoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Todo
        fields = ["task", "completed", "timestamp", "updated", "user"]

$ python manage.py makemigrations
$ python manage.py migrate

接下來,創建一個超級用戶。我們稍後會再來討論這個問題。


python manage.py createsuperuser

完整代碼下載:django-REST-demo.zip: (訪問密碼: 2274) 無需註冊,點擊普通下載就好。

RESTful結構:GET、POST、PUT和DELETE方法

在RESTful API中,端點用GET、POST、PUT和DELETE等HTTP方法定義結構和用法。

參考資料

演示

#   curl POST
$ curl  -d '{"task":"hello","completed":false}'  -H "Content-Type: application/json" http://localhost:8008/todos/api
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   162  100   128  100    34   9922   2635 --:--:-- --:--:-- --:--:-- 13500{"task":"hello","completed":false,"timestamp":"2023-02-14T07:21:42.196527Z","updated":"2023-02-14T07:21:42.196527Z","user":null}

#   curl GET
$ curl http://localhost:8008/todos/api
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   416  100   416    0     0  96924      0 --:--:-- --:--:-- --:--:--  135k[{"id":1,"task":"New Task","completed":false,"timestamp":"2023-02-14T07:01:18.488881Z","updated":"2023-02-14T07:01:18.488881Z","user":null},{"id":2,"task":"my_login4","completed":false,"timestamp":"2023-02-14T07:08:24.215626Z","updated":"2023-02-14T07:08:24.215626Z","user":null},{"id":3,"task":"hello","completed":false,"timestamp":"2023-02-14T07:21:42.196527Z","updated":"2023-02-14T07:21:42.196527Z","user":null}]

$ curl http://localhost:8008/todos/api/3/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   135  100   135    0     0  25153      0 --:--:-- --:--:-- --:--:-- 27000{"id":3,"task":"hello","completed":false,"timestamp":"2023-02-14T07:21:42.196527Z","updated":"2023-02-14T07:21:42.196527Z","user":null}


上面content部分可以輸入如下內容

{
    "task": "New Task",
    "completed": false
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章