آموزش django rest framework به همراه ساخت یک API
فریمورک Django REST (DRF) یک ابزار قدرتمند و انعطافپذیر برای ساخت API های وب است. در این آموزش django rest framework، نحوه ساختن یک CRUD API را تنها در 15 دقیقه با استفاده از چارچوب Django REST یاد خواهیم گرفت.
برای ساختن نمونه برنامه لیست کارها، کار را با راهاندازی فریمورک Django REST در پروژه جنگو شروع میکنیم و به دنبال آن یک آموزش کامل در مورد نحوه ایجاد یک CRUD REST API با چارچوب Django REST خواهیم داشت. قبل از اینکه به آموزش django rest framework بپردازیم ابتدا با مفاهیم پایه شروع میکنیم و مختصر آنها را بررسی میکنیم.
جنگو چیست؟
جنگو یک چارچوب وب رایگان، منبع باز و مبتنی بر پایتون است که از الگوی معماری Model-View-Template (MVT) پیروی میکند. این فریمورک دردسر توسعه وب را کاهش میدهد تا بتوانید اپلیکیشن های مبنی بر وب انعطافپذیرتری بسازید.
REST API چیست؟
اگر بخواهی خیلی ساده این مفهوم را تعریف کنیم باید گفت که REST عبارت است از راهکارها و روشهایی که با به کاربردن آنها میتوان به انتقال و دریافت داده از طریق شبکه پرداخت. یا به عبارتی، REST راهکاری مؤثر و ساده بهمنظور سازماندهی تعاملات بین سیستمهای مجزا است.
حال ممکن است که تعجب کنید که چرا واژه API با این مفهومِ بهکاربرده شده است؟
API درواقع از عبارت Application Programming Interface گرفتهشده است که به معنای به کاربردن متدها و روشهایی است که ارتباط با لایبراری و اپلیکیشن ها را فراهم میکند.
اگر این دو اصطلاح در کنار همدیگر قرار بگیرند مفهومی تحت عنوان RESTful API شکل میگیرد، منظور ازآن ارائه سازوکارهایی برای ارتباط با سایر سرویسها با استفاده از معماری خاصی است. درواقع RESTful یک معماری است که ویژگیهای خاص خودش را دارد.
چرا فریمورک Django REST؟
فریمورک Django REST (DRF) یک ابزار قدرتمند و منعطف برای ساخت API های وب است. مزیت اصلی آن این است که سریال سازی را بسیار آسان میکند.
فریمورک Django REST مبتنی بر نماهای کلاس محور جنگو است، بنابراین اگر با جنگو آشنایی دارید، این فریمورک گزینه بسیار خوب و سریعی برای توسعه برنامههای وب شما است. این برنامه پیادهسازیهایی مانند نماهای مبتنی بر کلاس، فرمها، اعتبارسنجی مدل، QuerySet و موارد دیگر را به کار میگیرد. در این آموزش django rest framework به ارائه یک مثال عملی از این فریمورک خواهیم پرداخت.
ویژگیهای فریمورک Django REST
فریمورک Django REST یک ابزار قدرتمند و منعطف برای ساخت API های وب است.
- برخی از دلایلی که ممکن است بخواهید از چارچوب REST استفاده کنید:
- API قابل مرور وب یک مزیت بزرگ در قابلیت استفاده مجدد برای توسعهدهندگان است.
- خطمشیهای احراز هویت شامل بستههای OAuth1a و OAuth2 است.
- سریال سازی که از منابع داده ORM و غیر ORM پشتیبانی میکند.
- کاملاً قابل تنظیم و سفارشیسازی است.
- اسناد گسترده و پشتیبانی عالی جامعه از آن
- مورداستفاده و اعتماد شرکتهای معتبر بینالمللی ازجمله Mozilla، Red Hat، Heroku و Eventbrite.
- بهطور سنتی، جنگو برای بسیاری از توسعهدهندگان بهعنوان یک چارچوب وب MVC شناخته میشود، اما میتوان از آن برای موارد مرتبط با Backend نیز استفاده کرد که در این مورد یک API است. ما در این آموزش django rest framework خواهیم دید که چگونه میتوانیم با آن یک وظیفه Backend بسازیم.
آموزش django rest framework
در این بخش ماجرا به سراغ اصل کار یعنی آموزش django rest framework خواهیم رفت و با استفاده از آن یک اپلیکیشن خواهیم ساخت.
در حالت ایده آل، ما باید یک محیط مجازی برای جداسازی وابستگیها ایجاد کنیم ولی این کار یک امر اختیاری است. برای ایجاد محیط مجازی دستور python -m venv django_env را از داخل پوشه پروژههای خود باید اجرا کنیم. سپس منبع./django_env/bin/activate را اجرا کنیم.
به خاطر داشته باشید که در هر بار که روی پروژه کار میکنیم باید ترمینال جدید باید محیط مجازی خود را دوباره فعال کنیم. سپس بقیه مراحل بهصورت زیر خواهد بود:
در قدم اول آموزش django rest framework:
باید به یک پوشه خالی در ترمینال خود برویم و فریمورک جنگو و جنگو REST را با دستورات زیر در پروژه خود نصب کنیم:
با دستور زیر یک پروژه جنگو به نام todo ایجاد میکنیم:
django-admin startproject todo
سپس با دستور زیر وارد پروژه ساختهشده todo خواهیم رفت و یک برنامه جدید برای API خود ایجاد میکنیم:
django-admin startapp todo_api
حال در مرحله بعد باید rest_framework و todo را به INSTALLED_APPS داخل فایل todo/todo/settings.py اضافه کنیم:
# 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’
]
همچنین باید یک فایل serializers.py و urls.py در todo/todo_api ایجاد کنیم و پَروَنجاهای جدید را همانطور که در ساختار دایرکتوری زیر پیکربندیشده است اضافه کنیم:
باید مطمئن شویم که rest_framework و URL ها را همانطور که در زیر نشان دادهشده است در فایل اصلی urls.py خود قرار دادهایم:
# 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)),
]
در مرحله بعد، باید یک superuser ایجاد کنیم. با دستور زیر در ترمینال
python manage.py createsuperuser
RESTful structure: GET, POST, PUT, and DELETE methods
در یک API RESTful، نقاط پایانی ساختار و استفاده را با متدهای GET، POST، PUT و DELETE HTTP تعریف میکنند. ما باید این روشها را بهصورت منطقی سازماندهی کنیم.
در این آموزش django rest framework برای نشان دادن نحوه ساخت یک برنامه RESTful با چارچوب Django REST، یک نمونه API برای انجام کار ایجاد میکنیم. همانطور که در جدول زیر نشان دادهشده است، از دونقطه پایانی با روشهای HTTP مربوطه استفاده خواهیم کرد:
ایجاد مدل برای برنامه جنگو ما
حال در این مرحله از آموزش django rest framework بیایید با ایجاد مدل برای لیست کارهای خود شروع کنیم: دستورات زیر را باید در داخل فایل مدل بریزیم.
# 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
پس از ایجاد مدل، آن را به پایگاه داده منتقل میکنیم.
python manage.py makemigrations
python manage.py migrate
سریال ساز مدل در آموزش django rest framework
برای تبدیل شی Model به فرمت مناسب API مانند JSON، فریمورک Django REST از کلاس ModelSerializer برای تبدیل هر مدلی به اشیای سریالی JSON استفاده میکند: پس در فایل Serializer دستور زیر قرار خواهد گرفت.
# 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”]
ایجاد Views API در جنگو
در این بخش از آموزش django rest framework، نحوه ایجاد دو نمای API، نمای لیست (list view) و نمای جزئیات (detail view) را توضیح خواهیم داد.
list view
اولین کلاس نمای API با نقطه پایانی todos/api/ سروکار دارد که در آن GET را برای فهرست کردن همه کارهای یک کاربر درخواستی معین و POST را برای ایجاد یک کار جدید مدیریت میکند. توجه داشته باشید که ما permission_classes را اضافه کردهایم که فقط به کاربران تأییدشده اجازه میدهد:
# 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)
متد ()GET ابتدا تمام اشیاء را از مدل با فیلتر کردن با شناسه کاربر درخواستی واکشی میکند. سپس، از شی مدل به یک شی سریالی JSON سریال میشود. سپس، پاسخ را با دادههای سریال و وضعیت 200_OK برمیگرداند.
متد POST () دادههای درخواستی را واکشی میکند و شناسه کاربر درخواستی را در دیکشنری داده اضافه میکند. سپس یک شیء سریالی ایجاد میکند و در صورت معتبر بودن آن را ذخیره میکند. اگر معتبر باشد، serializer.data را برمیگرداند که یک شی جدید ایجادشده با وضعیت 201_CREATED است. در غیر این صورت، serializer.errors را با وضعیت 400_BAD_REQUEST برمیگرداند.
حال در این مرحله از آموزش django rest framework باید یک نقطه پایانی برای نمای کلاس محور بالا باید ایجاد کنیم:
# 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()),
]
حال باید سرور جنگو را با دستور زیر اجرا کنیم:
python manage.py runserver
اکنون، ما برای اولین آزمایش اپلیکیشن خود آماده هستیم. باید به آدرس http://127.0.0.1:8000/api/todos/ بروییم. همچنین باید مطمئن شویم که با اطلاعات کاربری سوپر یوزری که در بالا ساختیم وارد شویم:
با ارسال کد زیر میتوانید یک کار جدید ایجاد کنیم:
{
“task”: “New Task”,
“completed”: false
}
نمایش جزئیات
اکنونکه با آموزش django rest framework اولین نمای نقطه پایانی خود را با موفقیت ایجاد کردیم، اجازه دهید نمای پایانی دوم todos/api/<int:todo_id> API را ایجاد کنیم.
در این کلاس view API، همانطور که در بالا توضیح داده شد، باید سه روش برای مدیریت متدهای HTTP مربوطه، GET، PUT و DELETE ایجاد کنیم: پس داخل فایل views کدهای زیر قرار خواهند گرفت.
# todo/api/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from todo.models import Todo
from .serializers import TodoSerializer
from rest_framework import permissions
class TodoDetailApiView(APIView):
# add permission to check if user is authenticated
permission_classes = [permissions.IsAuthenticated]
def get_object(self, todo_id, user_id):
”’
Helper method to get the object with given todo_id, and user_id
”’
try:
return Todo.objects.get(id=todo_id, user = user_id)
except Todo.DoesNotExist:
return None
# 3. Retrieve
def get(self, request, todo_id, *args, **kwargs):
”’
Retrieves the Todo with given todo_id
”’
todo_instance = self.get_object(todo_id, request.user.id)
if not todo_instance:
return Response(
{“res”: “Object with todo id does not exists”},
status=status.HTTP_400_BAD_REQUEST
)
serializer = TodoSerializer(todo_instance)
return Response(serializer.data, status=status.HTTP_200_OK)
# 4. Update
def put(self, request, todo_id, *args, **kwargs):
”’
Updates the todo item with given todo_id if exists
”’
todo_instance = self.get_object(todo_id, request.user.id)
if not todo_instance:
return Response(
{“res”: “Object with todo id does not exists”},
status=status.HTTP_400_BAD_REQUEST
)
data = {
‘task’: request.data.get(‘task’),
‘completed’: request.data.get(‘completed’),
‘user’: request.user.id
}
serializer = TodoSerializer(instance = todo_instance, data=data, partial = True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# 5. Delete
def delete(self, request, todo_id, *args, **kwargs):
”’
Deletes the todo item with given todo_id if exists
”’
todo_instance = self.get_object(todo_id, request.user.id)
if not todo_instance:
return Response(
{“res”: “Object with todo id does not exists”},
status=status.HTTP_400_BAD_REQUEST
)
todo_instance.delete()
return Response(
{“res”: “Object deleted!”},
status=status.HTTP_200_OK
)
متد ()GET ابتدا شیء را با شناسه todo_id و کاربر را بهعنوان کاربر درخواستی از مدل to-do واکشی میکند. اگر شی درخواست شده در دسترس نباشد، پاسخ را با وضعیت 400_BAD_REQUEST برمیگرداند. در غیر این صورت، شی مدل را به یک شیء سریالی JSON سریال میکند و پاسخ را با serializer.data و وضعیت بهعنوان 200_OK برمیگرداند.
متد ()PUT شیء کار را در صورت موجود بودن در پایگاه داده واکشی میکند، دادههای آن را با دادههای درخواستی بهروز میکند و دادههای بهروز شده را در پایگاه داده ذخیره میکند.
متد DELETE () شیء کار را در صورت موجود بودن در پایگاه داده واکشی میکند، آن را حذف میکند و به آن یک پاسخ میدهد.
urls.py API را همانطور که در زیر نشان دادهشده است باید به صورت زیر بهروز کنیم:
# todo/api/urls.py : API urls.py
from django.conf.urls import url
from django.urls import path, include
from .views import (
TodoListApiView,
TodoDetailApiView
)
urlpatterns = [
path(‘api’, TodoListApiView.as_view()),
path(‘api/<int:todo_id>/’, TodoDetailApiView.as_view()),
]
اکنون، اگر به آدرس http://127.0.0.1:8000/todos/api/<id>/ برویم، صفحه نمای API جزئیات را نشان میدهد. پس اگر ما مراحل بالا را بهخوبی و بهدرستی پیش رفته باشیم همهچیز باید بهخوبی کار کند.
نتیجهگیری
آموزش django rest framework ما به پایان رسید. ما توانستیم با موفقیت اولین CRUD Django REST API کاملاً کاربردی خود را بسازیم. ساختن یک API RESTful میتواند پیچیده باشد، اما چارچوب Django REST بهخوبی پیچیدگی را مدیریت میکند.