آشنایی با رست فریمورک جنگو (Django Rest FrameWork)

تو این پست نگاهی خواهیم داشت به Django Rest FrameWork یا به اختصار DRF داخل پست قبلی توضیحاتی در رابطه با این که API چی هست دادم که میتونید قبل از خوندن این پست نگاهی بهش بندازید.خوب برای شروع بهتره که اول یه سری بزنیم به سایت اصلی DRF https://www.django-rest-framework.orgیه سری توضیحات اولیه داده در مورد web api ها و اینکه چرا و کجا استفادشون میکنیم و بعد پکیج های لازم برای اینکه بتونیم در واقع DRF رو روی پروژه جنگو خودمون پیاده کنیم رو معرفی کرده که اینجوری میتونید نصبش کنید :1-پایتون و pip رو حتما باید اول نصب کنید2-نصب پکیج های زیر :pip install djangopip install djangorestframework و یه سری پکیج دیگه که بر حسب نیاز در ادامه باید نصب کنید اما , اصلا به چه دردی میخوره این DRF :)بزارید یه مثال ساده بزنم فرض کنید چند مدت پیش اومدید و برای خودتون با استفاده از جنگو (یا هر فریمورک دیگه ای ) یه سایت زدید اما حالا قصد دارید که برای همون سایتتون اپ اندروید هم بزنید ، خوب کار معقولانه اینه که شما بتونید همه اطلاعاتی که روی دیتابیس سایتتون هست رو از یه طریقی داخل اپ اتون نشون بدید برای این کار میاید و یک سری API تنظیم میکنید تا بتونید هر سری با درخواست دادن به اون اطلاعات مورد نیازتون رو داخل اپ اندروید داشته باشید . بنابراین شما بدون نیاز به اینکه دیتابیس جدیدی برای اپ اندرویدتون داشته باشید میتونید تمامی اطلاعات سایتتون رو داخل اون نمایش بدید.تصویر زیر رو ببینید اطلاعات شما داخل یک دیتابیس قرار گرفته ولی در تمامی نسخه های نرم افزاری میتونید ازش استفاده کنیدبنابراین وقتی مثلا داخل وبسایت شما تغییری در دیتابیس ایجاد میشود همین تغییرات درنسخه اندروید نیز ایجاد خواهد شد ، بنابراین API ابزاری هست که اطلاعات رو بر حسب نیاز ما از دیتابیس استخراج میکند و به ما ارائه میدهد و یا اطلاعات جدیدی را به دیتابیس اضافه میکند.خوب ، یواش یواش بریم سراغ اینکه داخل یه پروژه عملی نحوه ساختن api هارو در رست فریمورک جنگو ببینیم اگر قبلا با جنگو کار کرده باشید قطعا میدونید که modelچی هست اگرهم نه که بخوام ساده توضیح بدم شما برای این که جدول های داخل دیتابیس رو در جنگو آماده سازی کنید لازم نیست که مستقیما کد های دیتابیس بزنید و میتوانید با استفاده از مدل ها ساختار جدول هاتون و فیلد هاش رو مشخص کنید و با استفاده از دستور migrate خود پایتون اون هارو مستقیما به کد دیتابیس که به صورت پیش فرض در جنگو دیتابیس sqlite هست تبدیل میکند .توضیحات بیشتر models در اینجااگر جنگو را روی دستگاه خودتون نصب داشته باشید با استفاده از دستور زیر در cmd میتونید پروژه خودت رو ایجاد کنید django-admin startproject project_nameسپس میتونید وارد پوشه پروژه تون بشید و با دستور زیر یک اپلیکیشن ایجاد کنید python manage.py startapp app_nameاینجا براتون در رابطه با ساخت پروژه جنگو بیشتر توضیح داده :)باید برای این که بتونیم از DRF استفاده کنیم اپ rest_framework را هم به همراه اپی که در بالا ساختیم در فایل settings.py به قسمت INSTALLED_APPS اضافه کنیم در ادامه لازمه که مدل خودمون(جدول های دیتابیس ) رو آماده کنیم تا بعد بتونیم برای همین دیتابیس API های دلخواهمون رو بنویسیم من نمونه کد هارو از قسمت هایی از پروژه ای که این روز ها درگیرش هستم برای آشنایی بیشتر شما میارم :فایل models.pyهمینطور که میبیند مدل Group دارای 4 فیلد هست که یکی از اون ها به صورت manytomany هست که باز اگر خواستید بیشتر باهاش آشنا بشید به اینجا سر بزنید این مدل بعد از migrate شدن یک جدول از دیتابیس خواهد شد و من میتونم از طریق پنل ادمین اطلاعات خودم را داخلش ذخیره کنمبعد از اینکه یک مدل رو ساختیم باید براش serializer بسازیم توضیح ساده اش اینه که بتونیم مکانیزمی را فراهم کنیم که اطلاعات مدل های ایجاد شده در جنگو را به فرمتی در بیاریم که به راحتی قابل استفاده باشند مثل JSON و بالعکس.برای اینکار یک فایل serializers.py در هر اپلیکیشنی که در واقع میخواید مدل های اون رو serialize کنید ،ایجاد کنید موارد زیر را به اون اضافه کنید from rest_framework import serializers from .models import Group #مدلی که میخواهید سریالایز کنیددر ادامه یک کلاس GroupSerializer ایجاد میکنیم و داخل اون مدل و فیلد هایی که میخواهیم سریالایز شود را اضافه میکنیم میتوانیم تنها فیلد های دلخواهمون رو اضافه کنیم به صورت زیر :بعد از این مرحله باید داخل فایل Views.py بریم و موارد زیر را اضافه کنیم:from rest_framework.decorators import api_view # GET PUT POST , ..... نوع در خواست from rest_framework.response import Response #ارسال پاسخ ها from rest_framework import status #مشخص کردن وضعیت یک درخواستfrom .models import Group#مدل هایی که میخواهیم سریالایز کنیمfrom .serializers import GroupSerializer # سریالایز که در مرحله قبل نوشتیمدر مثال بالا نوع درخواست ارسال شده به سمت سرور GET می باشد از مدل Group تمام اطلاعاتش را دریافت میکنیم وداخل متغیر groups میریزیماطلاعات را به سریالایزر میدهیم و خروجی که شامل دیتای مناسب برای پاسخ هست را ارسال میکنیماز status.HTTP_200_OK به معنای درست بودن وضعیت استفاده میکنیم لیست همه استاتوس هارو اینجا میتونید ببیند و لیست متد های HTTP رو هم در تصویر زیر میتونید ببیند لیست متدهای HTTPبعد از این مرحله باید url های لازم رو ایجادکنیم داخل فایل urls.py از path زیر استفاده میکنیم و متد get_groups که داخل فایل views نوشته شده را اینجا اضافه میکنیم : path('get-groups',views.get_groups)***بعضی جا ها شما نمیخواهید که این APIها در اختیار عموم قرار بگیرد و تنها کسی که مثلا لاگین کرده باشد و یا ادمین سایت باشد بتواند به این ها دسترسی داشته باشد برای این که بتوانید این محدودیت هارا قائل شوید باید از permission های مربوط به rest استفاده کنید که اینجا میتوانید اطلاعات بیشتری از permission ها کسب کنید برای نمونه من فقط به کسانی که داخل سایت لاگین کرده اند و یا ادمین هستند این اجازه را میدهم برای این کار داخل فایل settings.py از دستورات زیر استفاده میکنمدر بعضی مواقع خود شما هم میتوانید میتوانید permission های شخصی سازی شده خودتون رو بنویسید برای این کار هم یک فایل permissions.py داخل اپ مورد نظرتون ایجاد کنید و به صورت زیر دسترسی های شخصی سازی شده رو اعمال کنید من در این فایل یک Permission با نام IsOwner میسازم :فایل permissions.pyو سپس داخل view هایی که قبلا نوشته اید IsOwner رو به صورت زیر اضافه کنید :خوب در نهایت برای دیدن نحوه کار کردن این API ها هم میتوانید از خوده محیطی که جنگو برای rest فراهم کرده استفاده کنید و هم از نرم افزار معروف Postmanبرای شروع پروژه خودتون رو ران کنید python manage.py runserverاز local host استفاده کنید که به صورت 127.0.0.1:8000 هستاگر آدرس زیر رو بزنید داخل مرورگر در ابتدا چون لاگین صورت نگرفته و permission داده نشده به چیزی که میبنیم به این صورت است http://127.0.0.1:8000/elmi/get-groupsاما پس از لاگین کردن خروجی به صورت JSON است که اطلاعات تمام گروه هارا نشان میدهد***این یک مثال اولیه و ساده بود از Django RestFramework و بیشتر جنبه آشنایی داشت و پست آموزشی نبود و امیدوارم کلیت کار دستتون اومده باشه و بتونید با سرچ زدن و استفاده از داکیومنت های اصلی خود DRF پروژه های خوبی رو داشته باشید :)خوب سلام دوباره، بکم آپدیت :)توی داکیومنت های جدید djando rest framework میتونید در مورد Generic View ها و viewset ها بیشتر بخونید ، چون خیلی سرعت توسعه با این روش ها بیشتر و بهتر شده و به نظرم واجبه که در موردشون مطالعه داشته باشیدمن سعی میکنم در ادامه یه نمونه از Concrete View Classes رو براتون توضیح بدم باشد که رستگار شوید : مدلی که برای این مثال داریم به صورت زیره :class Post(models.Model): author = models.ForeignKey(User,on_delete=models.CASCADE) title = models.CharField(max_length=250) content = models.TextField() status = models.BooleanField() category = models.ForeignKey(&quotCategory&quot,on_delete=models.SET_NULL,null=True) created_date = models.DateTimeField(auto_now_add=True) updated_date = models.DateTimeField(auto_now=True) def __str__(self): return self.titleبیاید به این چند خط کد در فایل views.py نگاه کنید تا بعدش توضیح بدم چه اتفاقی میفته :from rest_framework.permissions import IsAuthenticated,IsAuthenticatedOrReadOnly from rest_framework.views import APIViewfrom rest_framework.generics import ListAPIView,RetrieveUpdateAPIView,ListCreateAPIView,DestroyAPIView,UpdateAPIView,CreateAPIView,RetrieveUpdateDestroyAPIView from .permissions import IsOwnerOrReadOnly from django_filters.rest_framework import DjangoFilterBackend from rest_framework.filters import SearchFilter,OrderingFilterclass PostList(ListCreateAPIView): permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = PostSerializer queryset = Post.objects.all() filter_backends = [DjangoFilterBackend,SearchFilter,OrderingFilter] filterset_fields = { &quotcategory&quot: [&quotin&quot, &quotexact&quot] } search_fields = ['title','content'] ordering_fields = ['created_date']class PostDetail(RetrieveUpdateDestroyAPIView): permission_classes = [IsOwnerOrReadOnly] queryset = Post.objects.filter(status = True) serializer_class = PostSerializerخوب همینطور که میبینید در وهله اول نوشتن view ها خیلی راحت تر شده و یه سری ویژگی های خوب دیگه مثل filters , search, ordering قابل استفاده استدر واقع شما برحسب نیاز خودتون باید اون class view مناسب رو انتخاب کنید و ازش ارث بری داشته باشید، فقط همین، بقیه موارد رو خود django کنترل میکنه .توی فایل url تون حواستون باشه که برای حالت get,update,delete که برای یک object هست حتما مقدار pk را در url ارسال کنید .path('post-list/',views.PostList.as_view(),name='post-list'), path('post-detail/<int:pk>/',views.PostDetail.as_view(),name='post-detail')در نهایت باز تاکید میکنم حتما داکیومنت اصلی خود django و django rest رو بخونید، این مقاله صرفا جهت دید اولیه شماست .اگر تجربه استفاده از rest رو داشته اید و یا منبع خوبی برای آموزش میشناسید این زیر معرفی کنید برای بقیه :)