نکتههای جنگویی - رسپی کرفس و جنگو
فرض کنید داخل تلگرام برای دوستتون پیام فرستادین و بعد از چند لحظه تاخیر برای دوستتون ارسال میشه، و باعث میشه که درخواست شما در نهایت به انجام برسه. در ادامهی نکتههای جنگویی کار کردن با celery رو بهطور خلاصه یاد میگیریم.
حالا بهطور ساده میخوایم نحوهی ارسال داستان بدون اینکه درخواستمون از بین بره رو انجام بدیم. (در ادامه که خواستیم Djang Rest Framework رو هم یاد بگیریم این celery خیلی بیشتر کاربرد خودشو نشون میده).
برای Message Broker از RabbitMQ استفاده خواهم کرد و برای همین نیازه که RabbitMQ رو نصب کنید. صفحهی دانلود RabbitMQ. این هم برای کسانی که لینوکس دارن.
بعد از نصب RabbitMQ نوبت به نصب کتابخونهی celery میرسه:
pip3 install celery
برای اینکه پروژهی جنگوی ما celery رو بشناسه، نیازه که کارهایی که در ادامه میاد رو انجام بدیم:
A ├── asgi.py ├── celery.py ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py
فایل celery.py رو به A که بخش تنظیمات پروژه هست اضافه میکنم و کدهای زیر رو مینویسم:
import os from celery import Celery os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'A.settings') celery_story_app = Celery('A') celery_story_app.config_from_object('django.conf:settings', namespace='CELERY') celery_story_app.autodiscover_tasks()
نکته: در خط:
celery_story_app = Celery('[PROJ-NAME]')
در واقع بهجای A باید اسم پروژه خودتون رو بنویسید. که اسم پروژهی من A هست و برای همین A گذاشتم!
بعد از انجام مرحلهی بالا فایل .init__py__ رو در همون دایرکتوری تنظیمات پروژه به شکل زیر تغییر میدم:
from .celery import celery_story_app
در واقع اپی که برای celery ساختم رو بهش اضافه کردم.
حالا فایل به A/settings.py تنظیمات Message Broker رو اضافه میکنم:
# CELERY CONFIGURATIONS CELERY_BROKER_URL = 'amqp://guest:guest@localhost' CELERY_RESULT_BACKEND = 'rpc://'
celery خیلی تنظیمات دیگه هم داره که با گشتوگذار داخل داکیومنتش و برحسب نیازتون میتونید از تنظیمات مختلفش استفاده کنید.
تنظیمات لازم برای شناسایی سلری توسط پروژهی جنگو انجام شد.
stories ├── admin.py ├── apps.py ├── forms.py ├── __init__.py ├── models.py ├── tasks.py ├── templates │ └── stories │ ├── add.html │ ├── detail.html │ └── index.html ├── tests.py ├── urls.py └── views.py
به اپ stories یک فایل به اسم tasks.py اضافه کردم. tasks.py فایلیه که خود سلری بهطور اتوماتیک در تمام اپها اونو شناسایی میکنه و taskهای داخلش رو اجرا میکنه.
به tasks.py کدهای اضافه کردن یک داستان جدید رو اضافه میکنم:
from celery import shared_task from .models import Story from django.contrib.auth.models import User @shared_task def create_story_task(user, title, slug, body): get_user = User.objects.get(id=user) Story.objects.create(user=get_user, title=title, slug=slug, body=body) return 1
حالا در stories/views.py اول taskی که ساختم رو وارد میکنم و view اضافه کردن داستانی که در قسمت واحد زیباسازی فرم اضافه کردم رو به شکل زیر تغییر میدم:
from .tasks import create_story_task
@login_required def add_story(request): if request.method == 'POST': if request.user.is_superuser: form = StoryForm(request.POST) if form.is_valid(): cd = form.cleaned_data title = cd.get('title') body = cd.get('body') result = create_story_task.delay(user=request.user.id, slug=get_random_string(length=10), title=title, body=body) if result.get() == 1: return redirect('stories:add_story') else: form = StoryForm() return render(request, 'stories/add.html', {'form': form})
دو ترمینال نیاز دارم که داخل یکیش celery رو اجرا کنم و داخل یکی دیگهش پروژه رو. اجرای celery. (بخش بولد شده):
(.venv) ➜ A git:(master) ✗ celery -A A worker -l info
اجرای پروژه هم که:
(.venv) ➜ A git:(master) ✗ ./manage.py runserver
میبینیم که create_story_task رو شناخته [دیدن تصویر]. و اگر به localhost:8000/add بریم و یه داستان جدید اضافه کنیم. میبینیم که 1 در خروجی آمده و داستان جدید ما باموفقیت به دیتابیس اضافه شده [دیدن تصویر].
پ.ن. ۱: پایهی این نکات جنگویی.
پ.ن. ۲: این نکاتی که گفته میشه، قطعا کامل نیستن. و صرفا حاصل جستجوها و مطالعهی خودمه که برای دید گرفتن کلی فکر میکنم خوب باشه و به داکیومنت خوندن کمک میکنه. اما بههیچوجه با خوندن این پست نه من و نه کس دیگه به جنگو و سلری و ... مسلط نمیشه.
پ.ن. ۳: اگر این مطالب بهتون کمک میکنه و اگر که فکر میکنید مطالب خوبی هستن، بقیه رو هم در دیدن این مطالب سهیم کنید :).
و خیلی سریع و جمع و جور به پایان آشپزی جنگویی رسیدیم و غذای ما آمادهست :))
پایان./