مشکل ثبت مجدد فرم با رفرش

. توی کد زیر بعد از ثبت کردن فرم اگر صفحه را رفرش کنیم همان فرم دوباره ثبت میشود.

مشکل در فروم جنگو این جوری توضیح داده شده است:

یعنی بعد از POST موفق باید فرم را redirect کنیم که با این کار صفحه جدید با GET فراخوانی میشود در نتیجه اگر رفرش کنیم باز هم در خواست GET ارسال میگردد. یعنی کد را به شکل زیر تغییر میدهیم.

serializer توی Django Rest Framework با دیتای ورودی چیکار میکنه؟

بهترین روش یادگیری یه فریم ورک خوندن کد خود فریم ورک و داکیومنت توی خود کد هست. برای serializer توی جنگو یک کامنت هست توی rest_framework/serializer.py که:

خیلی خوب توضیح میده که اگر به serializer پارامتر data رو پاس داده باشیم تابع is_valid قابل استفاده است. و initial_data هم در دسترس هست که همون دیتایی هست که به API پاس داده شده. بعد از is_valid این داده ورودی به valid شده تبدیل میشه که میتونیم توی validated_data ببینیم. مثلا اگر Id به object مربوطه تبدیل میشه. و errors و data هم در دسترس خواهد بود. data درواقع اون رکورد جدیدی هست که ایجاد شده است.

مثال زیر رو ببینید:

میبینید که بعد serializer.is_valid() مقادیر مربوطه رو پرینت کردم.

مثال خروجی هم در ادامه میبینید:

باگ توی اضافه کردن EventListener

در کد زیر باگ نهفته ای وجود دارد. یک دکمه حذف یک ردیف از جدول وجود دارد که وقتی روی آن کلیک میکنیم. eventListener به آن اضافه میشود. باگ به این شکل از که به هر تعداد کلیک بر روی این دکمه EventListener اضافه میشود. تا زمانی که صفحه رفرش شود. این باگ موجب میشود که در نهایت به تعداد eventListener ها درخواست به سرور ارسال میشود.

برای حل این مشکل باید هر وقت خواستیم EventListener اضافه کنیم، قبلی را پاک کنیم.

چرا Promise و کاربردهاش

برای حل مشکل Asynchronous توی جاوااسکریپت. قبل از Promise برنامه نویس ها از callback استفاده میکردند که مشکلات زیادی داشته از جمله callback hell

کد بالا رو در نظرم بگیرید. توی هر مرحله باید callback تودرتو نوشت که باعث میشه. کد کثیف و اگر توی کد داخلی باگی پیدا بشه پیدا کردن و فیکس کردنش سخته.

توی Promise میتونیم به صورت زنجیروار همه عملیاتها رو مدیریت کرد بجای ساختار تودرتو. گارانتی شده که یا عملیات موفق میشه و تابع resolve اجرا میشه یا عملیات ناموفق خواهد بود و تابع reject اجرا میشه. یعنی به راحتی میتونی تمامی حالات رو با تابع then و catch مدیریت کنیم. حتی اگر عملیات به دلیل کندی زیاد طول بکشه.

مثال بالا رو میتونیم زنجیری مدیریت کنیم

یکی از کاربردهاش API call هست

توی مثال زیر حتی چندین API با هم صدا زده میشه و میبینیم که چقدر خوانا و راحت نوشته میشه:

Promise چیه؟

Promise یک آبجکت هست که یک تسک Asynchronous رو توی جاواساکریپت اجرا می کنه. این آبجکت تو تابع داره resolve و reject که این آبجکت گارانتی میکنه که یکی از این دو قطعا اجرا میشه. بخاطر همین بهش میگن Promise. یعنی گارانتی میکنه که این تسک یا موفق میشه یا نه و خارج از این دو حالت نیست.

با صدا زدن یه Promise شما از دو تابع میتونید استفاده کنید. then و catch اولی وقتی که تسک موفق بشه خروجی رو میگیره و دومی وقتی که

توی کد بالا موارد زیر اتفاق میوفته:

  1. Promise درجا اجرا میشه
  2. دو ثانیه برنامه می ایستد
  3. resolve اجرا میشه
  4. then اجرا میشه

اگر بجای resolve تابع reject رو اجرا کنیم. توی مرحله 4 بجای then تابع catch اجرا میشه.

بازنویسی serializer توی Django Rest Framework

توی serializer های DRF گاهی لازمه وقتی متد list() اون صدا زده میشه باید قبلش دیتایی که ازش گرفته میشه تغییری بدیم برای این کار از متد to_representaion استفاده میکنیم.

یک باگ ساده و یک راه حل ساده تر

کد زیر یک باگ جالب داره.

در صورتی که branch انتخاب نشده باشه cleaned_data.get(“branch”).name این اکسپشن میده. برای اصلاحش باید یه تغییر ساده بدیم

اپراتورهای rest و spread در جاوااسکریپت

امروز با کد زیر مواجه شدم و فهمش برام جذاب بود:

با مفهوم اپراتورهای rest و spread آشنا شدم که از ES6 به بعد به جاوااسکریپت اضافه شدن.

کد زیر رو در نظر بگیرید»

خروجی کد بالا [3, 2, 4] است. حالا کد زیر رو ببینید:

حالا خروجی کد بالا برابر با 4 است. یعنی اپراتور spread که همون … است آرایه رو به المانهای توش پخش میکنه و نتیجه اون اپراتور میشه Math.max(4,2,3)

اپراتور دیگه ای وجود داره به اسم rest:

یک سری مثال در جاوااسکریپت و react

دپلوی React و Django در Docker

برای دپلوی کردن یک پروژه Django و React در داکر با کانفیگ زیر کار میکنیم:

فایل بالا compose است و فایل backend/shiftsupervisor/Dockerfile

و فایل frontend/shiftfront/Dockerfile

و فایل nginx/nginx.conf

در ضمن تنظیمات مهم برای settings.py

فایل axiosConfig.jsx

و فایل vite.config.js

معماری Message Queue

Message Queue مفهومی در زمینه برنامه نویسی Async است. فرض کنید بعد از انجام یک عملیات مثل پرداخت باید یک پیامک یا ایمیل ارسال شود. در این صورت عملیات پرداخت نباید به ارسال ایمیل وابسته باشد. در واقع این عملیات های باید Async باشند. پرداخت انجام میشود و یک Task به اسم ایمیل در صف پرداخت قرار میگیرد که در اولین فرصت ایمیل ارسال شود. در مورد اینکه چرا باید از این معماری استفاده کرد یا مزایا یا معایب آن چیست صحبتی ندارم و میشود در اینترنت این موارد را جست.

اینجا معماری کلی آن را میبینیم که در اینترنت ممکن است مورد مفهومی دیده نشود.

عکس بالا رو ببینید:

اول از همه یک سری Task داریم. مثلا گزارش ماهانه مالی، ارسال ایمیل، تهیه thumbnail از عکس بارگزاری شده و.. اینها مثالهایی از تسک هایی هستند که باید Async انجام بشه. گزارش ماهانه که قراره سر ماه نصب شب آماده بشه که فردا صبح کارمندان ازش استفاده کنن باید مستقل از نرم افزار باشه و به صورت تسکی ماهانه انجام بشه.

این تسک ها توی یک صف قرار میگیرند که به ترتیب انجام شن. این صف رو Rabbit MQ یا Redis براموان فراهم میکنن.

بعد تسک ها به ترتیب به Worker هایی داده میشن. در واقع worker ها این تسک ها رو انجام میدن. توی پایتون از celery استفاده میشه معمولا. خود Task ها هم توابعی هستند که به Celery داده میشن.

بعد از اینکه تسک انجام شد ممکنه بخوایم خروجیش رو نگه داریم معمولا Redis گزینه خوبیه. اگر بخواهیم که به صورتی دایمی داشته باشیم خروجی رو توی یک دیتابیس باید ذخیره کنیم.

گفتیم مثلا اگر پرداخت انجام شد باید ایمیل ارسال بشه. خوب مشخصه توی این مثال بعد از انجام پرداخت تسک ارسال ایمیل فراخوانی میشه. اما بعضی تسک ها خود به خود توی بازه های زمانی خاصی باید انجام بشه. اینجا به Schedualer نیاز داریم. Celery قابلیتی داره به اسم Beat که برنامه ریزی با اون انجام میشه و تسک ها رو خودش triger میکنه.