<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Parsa Rezaei</title>
        <link>https://virgool.io/feed/@ParsaRezaei</link>
        <description>یه برنامه نویس ساده که جنگو کار میکنه و جدیدا هم تصمیم گرفته راه دواپس رو پیش ببره:)</description>
        <language>fa</language>
        <pubDate>2026-06-16 06:41:16</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/2968058/avatar/B8ZLkq.jpg?height=120&amp;width=120</url>
            <title>Parsa Rezaei</title>
            <link>https://virgool.io/@ParsaRezaei</link>
        </image>

                    <item>
                <title>مدیریت تغییرات خودکار با استفاده از Django Signal</title>
                <link>https://virgool.io/@ParsaRezaei/%D9%85%D8%AF%DB%8C%D8%B1%DB%8C%D8%AA-%D8%AA%D8%BA%DB%8C%DB%8C%D8%B1%D8%A7%D8%AA-%D8%AE%D9%88%D8%AF%DA%A9%D8%A7%D8%B1-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-django-signal-byeonnemshbt</link>
                <description>فرض کنید که شما یک مدل دارید به اسم Workspace و فیلدی دارید که owner نام داره. یک مدل دیگه ای دارید که Memberships هستش که ارتباط بین کاربران و Workspace رو مدیریت میکنه و نقش کاربر هارو مثل owner, admin یا member رو ذخیره میکنه.میخوایم کدی رو پیاده سازی کنیم که وقتی تغییر مالکیت workspace از کاربری به کاربر دیگه ای انتقال پیدا کرد، فیلد owner در مدل workspace هم آپدیت بشه.مشکلی که اینجا وجود داره، زمانی که نقش مالکیت تغییر بکنه، در مدل workspace فیلد owner آپدیت نمیشه و همچنان مالک قبلی رو نشون میده. توی چنین موقعیتی میتونیم از سیگنال ها استفاده کنیم. این امکان رو برای ما فراهم میکنه که به نوعی، به تغییرات مدل ها واکنش نشون بدیم مثل بعد از ذخیره شدن شیء(post_save)مدل ها به این صورت هستند:سیگنال رو طوری تعریف می کنیم که که هر زمان یک Membership با نقش owner ذخیره شد، فیلد owner در مدل Workspace هم آپدیت بشه.فایل &quot;signals.py&quot; به این صورت هستش:ما توی این بخش  از سیگنال post_save استفاده کردیم که به صورت خودکار هر زمان که یک Membership ذخیره بشه، کدی رو اجرا می‌کنه. سیگنال post_save  این امکان رو میده که بعد از ذخیره موفقیت‌آمیز یک شیء در دیتابیس، به تغییرات واکنش نشان بدیم.این کد میاد هر بار که یک Membership با نقش owner ذخیره بشه، فیلد owner در مدل Workspace رو به‌روزرسانی می‌کنه. به این صورت که اگر کاربری به عنوان مالک جدید تعیین بشه، سیگنال به صورت خودکار مالک فعلی رو تغییر می‌ده و تغییرات رو در دیتابیس ذخیره می‌کنه. این کار باعث می‌شه داده‌ها همیشه هماهنگ باشن و نیازی به به‌روزرسانی دستی در جاهای مختلف نباشه.برای اتصال سیگنال هم باید تغییراتی داخل فایل apps.py انجام بدیم:حالا وقتی بخوایم تغییر مالکیت انجام بدیم، فیلد owner در مدل Workspace هم به صورت خودکار آپدیت میشه و دچار ناسازگاری در دیتا نمیشیم.</description>
                <category>Parsa Rezaei</category>
                <author>Parsa Rezaei</author>
                <pubDate>Sun, 15 Dec 2024 04:09:41 +0330</pubDate>
            </item>
                    <item>
                <title>Django Transactions</title>
                <link>https://virgool.io/@ParsaRezaei/django-transactions-h4b6poskzczg</link>
                <description> توی این قسمت، راجب Transaction atomic گفته شد، این سری تصمیم گرفتم که جزئیات بیشتری رو راجب Transaction بخونم و بیام توضیحاتی رو راجع بهش بنویسم و به همراه مثال:)۱- مفهوم ATOMIC_REQUESTSیکی از ویژگی های جنگو، استفاده از ATOMIC_REQUESTS هستش که بعد از هر درخواست HTTP به طور خودکار داخل یک تراکنش قرار میگیره. این یعنی اینکه اگه درخواست بدون خطا انجام بشه،‌تغییرات روی دیتابیس commit میشه و اگه خطا رخ بده، همه تغییرات rollback میشن. این ویژگی تضمین میکنه که تغییرات به صورت atomic انجام بشن و از بروز خطا دیتا جلوگیری بشه.مثال: اول از همه نیازه که ATOMIC_REQUESTS رو داخل تنظیمات پروژه فعال کنیم:یک ویو ساده براش بخوایم در نظر بگیریم:توی این مثال اگه خطایی رخ بده همه تغییرات به طور خودکار بازگردانی میشن.۲- استفاده از atomic()اگه بخوایم تمرکز و دقت بیشتری روی جزئیات تراکنش ها داشته باشیم میتونیم از atomic decorator استفاده کنیم. بهمون کمک میکنه که بخشی از کدمون رو اتمیک پیش ببریم به این معنی که اگه کد بدون مشکل اجرا شد تغییرات ذخیره بشن و اگه خطایی پیش اومد rollback بخوره.بلوک های atomic میتونن تو در تو باشن. یعنی میتونیم چندین سطح از تراکنش های اتمیک داشته باشیم ولی اگه بلوک بیرونی خطا رخ بده، حتی اگه بلوک داخلی به درستی پیش رفته باشه همه تغییرات rollback میخورن.۳- مفهوم on_commit()گاهی اوقات تصمیم میگیریم که بعد از اینکه commit با موفقیت انجام شد کار خاصی انجام بشه. به طور مثال میخوایم که در صورت ذخیره موفق اطلاعات، یک ایمیل بفرستیم.  اینجاست که on_commit() بهمون کمک میکنه:۴- مفهوم savepointگاهی پیش میاد که تصمیم بگیریم که داخل یک تراکنش بزرگ،‌فقط بخشی از تغییرات rollback بشن، نه کل تراکنش. اینجاست که میتونیم از savepoint استفاده کنیم.با ایجاد یک savepoint در یک تراکنش هروقت بخوایم میتونیم به همون نقطه برگردیم، بدون اینکه کل تراکنش rollback بشه. وقتی که atomic() به صورت تو در تو استفاده بشه، به صورت خودکار یک savepoint ایجاد میکنه  تا امکان commit یا rollback جزئی فراهم بشه.
داخل این مثال اگه تصمیم بگیرین که b رو نگه ندارین،‌میتونین تنها به نقطه savepoint برگردین و بقیه تراکنش ها دست نخورده باقی بمونن.اگه داخل یک بلوک atomic() از savepoint استفاده کنین و خطایی رخ بده، کل بلوک rollback میخورهمیتونین با get_rollback() و set_rollback() کنترل بیشتری روی رفتار rollback داشته باشین.امیدوارم که براتون مفید بوده باشه:)داکیومنت Django</description>
                <category>Parsa Rezaei</category>
                <author>Parsa Rezaei</author>
                <pubDate>Mon, 18 Nov 2024 15:15:27 +0330</pubDate>
            </item>
                    <item>
                <title>Kong API Gateway</title>
                <link>https://virgool.io/@ParsaRezaei/kong-api-gateway-h0iryqdenl6c</link>
                <description>سلام،توی این قسمت من توضیح کوتاهی بابت Keycloak داده بودم و قراره که این مقاله راجب Reverse Proxy صحبت کنم که من توی پروژه ای که کار میکردم اومدم این دو رو باهم integrate کردم.مدیریت ترافیک API ها با Kong API Gateway  بهتون کمک میکنه که نظارت خوبی روی درخواستی هاتون داشته باشید. امتیازات خیلی خوبی داره این ابزار مثل Rate Limiting, احراز هویت، CORS و همچنین لاگ گرفتن از درخواست هایی که سمت شما میاد. حالا ترکیب شدنش با Keycloak چه کمکی میکنه؟اول از همه یه مثال عامیانه ای بابت اینکه چرا از keycloak و kong استفاده کردم میگم که یه جورایی متوجه قضیه بشیم که چه اتفاقاتی توی پروژه میوفته:)فرض کنید یه شهر بزرگ داریم که چندین مغازه (میکروسرویس‌ها) توش فعالیت می‌کنن. هر کدوم از این مغازه‌ها وظیفه خاص خودش رو داره؛ یکی فروش مواد غذاییه، یکی کتاب می‌فروشه، و یکی لباس. حالا اگه مردم بخوان وارد این مغازه‌ها بشن، یه ورودی اصلی توی شهر هست که هم جلوی شلوغی و ترافیک رو می‌گیره و هم کنترل می‌کنه که کی وارد شهر بشه. این ورودی اصلی همون Kong API Gateway هست.- وظیفه Kong حالا چیه؟ مثل دروازه ورودی اصلی شهره. وظیفه داره که:کنترل کنه کی وارد شهر می‌شه: یعنی ترافیک درخواست‌ها رو مدیریت کنه. هر کسی که می‌خواد وارد یه مغازه (میکروسرویس) بشه، باید اول از این دروازه عبور کنه.محدودیت تعداد بازدیدکننده‌ها: اگه یه مغازه خیلی شلوغ بشه و ترافیک سنگین واردش بشه، Kong می‌تونه بگه: &quot;صبر کن، تو فعلاً نمی‌تونی وارد بشی تا ترافیک کمتر بشه.&quot; این همون Rate Limiting هست.امنیت: Kong می‌تونه قبل از اینکه کسی وارد بشه چک کنه که این آدم اجازه ورود به مغازه رو داره یا نه. اینجا هست که Keycloak وارد می‌شه.- حالا فرض کنید که همون شهر یه نگهبان امنیتی (Keycloak) داریم که در واقع کارت شناسایی همه آدم‌ها رو نگه می‌داره. اگه کسی بخواد وارد یه مغازه خاص بشه (یعنی درخواست استفاده از یه میکروسرویس خاص رو بده)، Kong می‌ره پیش این نگهبان (Keycloak) و می‌پرسه: &quot;این فرد اجازه ورود داره؟&quot; Keycloak کارت شناسایی طرف رو چک می‌کنه و اگه اجازه داشت، اجازه ورود به اون مغازه رو می‌ده.(اینجا کارت شناسایی میشه توکنی که به هر شخص اختصاص داده میشه)چنین ابزار هایی خیلی میتونن کمک بکنن روی پروژه ای که قرار هست میکروسرویس باشه، و قرار هستش که با درخواست های به شدت زیادی مواجه بشین و نخواین بار سنگینی روی دوش Django بذارید.رفرنس های خوبی من بابتش پیدا کردم که پایین میذارم و اگر منابع بهتری پیدا کردم، پست رو آپدیت میکنم.این نیمچه مقاله رو برای این نوشتم که بخوام شما هم با این ابزار آشنا بشید و امیدوارم به کارتون بیاد;)تلاشمو میکنم که یک داکیومنت خوبی بابت راه اندازی  Keycloak و Kong داخل پروژه  Django بنویسم . گیت هاب Kong API Gatewayگیت هاب Securing APIs with Kong and Keycloak</description>
                <category>Parsa Rezaei</category>
                <author>Parsa Rezaei</author>
                <pubDate>Mon, 30 Sep 2024 17:05:25 +0330</pubDate>
            </item>
                    <item>
                <title>Aggregation in Django</title>
                <link>https://virgool.io/@ParsaRezaei/aggregation-in-django-v5xjqgv21kjj</link>
                <description>سلام، امیدوارم که حالتون خوب باشه.موضوعی که قرار هست راجبش صحبت کنم یکی از مسائل در کوئری جنگو هستش..Aggregation.چون قرار هست که طبق داکیومنت پیش بریم پس از خود مثال داکیومنت جلو میرم:خب، فرض کنید که شما میخواید میانگین کل قیمت کتاب هارو حساب کنید...چون برای حساب کل QuerySet قرار هست محاسبه صورت بگیره، Aggregate به کمکتون میاد.&gt;&gt;&gt; from django.db.models import Avg
&gt;&gt;&gt; Book.objects.aggregate(Avg(&amp;quotprice&amp;quot))
{&#039;price__avg&#039;: 34.35}نکته قابل توجه این هستش که خروجی aggregate به صورت دیکشنری هستش و key از ترکیب نام فیلد شما که مثلا price هستش به همراه نام متد تشکیل میشه. اگر بخواید نام به خصوص براش مشخص کنید میتونین به صورت کد زیر این کار رو انجام بدید:Book.objects.aggregate(average_price=Avg(&amp;quotprice&amp;quot))راه دوم برای محاسبه و کار روی annotate, object  نام داره. حالا چه زمانی از annotate استفاده میکنیم؟ زمانی که بخوایم روی یک کوئری خاص کار کنیم بر خلاف aggregate که روی یک عالمه نتیجه متمرکز میشیم.به طور مثال، فرض کنید که حالا که لیست کتاب هارو دارید، میخواید بدونید که هر کدوم از کتاب ها،  تعداد نویسنده هاش که مشارکت داشتن رو حساب کنید:# Build an annotated queryset
&gt;&gt;&gt; from django.db.models import Count
&gt;&gt;&gt; q = Book.objects.annotate(Count(&amp;quotauthors&amp;quot))
# Interrogate the first object in the queryset
&gt;&gt;&gt; q[0]
&lt;Book: The Definitive Guide to Django&gt;
&gt;&gt;&gt; q[0].authors__count
2
# Interrogate the second object in the queryset
&gt;&gt;&gt; q[1]
&lt;Book: Practical Django Projects&gt;
&gt;&gt;&gt; q[1].authors__count
1همونطور که میبینید، خروجی ما به صورت QuerySet هستش و مثل aggregate، به صورت دیفالت شما باید از نام فیلد و نام متد استفاده بکنین تا خروجی بگیرید. اگر بخواید میتونین نام رو خودتون مشخص بکنید:&gt;&gt;&gt; q = Book.objects.annotate(num_authors=Count(&amp;quotauthors&amp;quot))
&gt;&gt;&gt; q[0].num_authors
2
&gt;&gt;&gt; q[1].num_authors
1به طور خلاصه تعریف این دو رو به بخوام داخل جدول قرار بدیم میشه(ممنون از AI):این یک توضیح کوچیک از تعریف این دو روش برای کار روی object هامون بودش که خب جزئیات زیادی بابتشون هستش که نیاز هست حتما داکیومنت رو با دقت بخونین؛)امیدوارم که براتون مفید بوده باشه.لینک داکیومنت این بخش:https://docs.djangoproject.com/en/5.0/topics/db/aggregation/</description>
                <category>Parsa Rezaei</category>
                <author>Parsa Rezaei</author>
                <pubDate>Sat, 04 May 2024 14:46:24 +0330</pubDate>
            </item>
                    <item>
                <title>Database Transactions in Django(Atomic)</title>
                <link>https://virgool.io/@ParsaRezaei/database-transactions-in-django-wrxpiszdhrbk</link>
                <description>سلام، این سناریو رو فرض کنید: کاربر کیف پولش رو به فرض شارژ کرده و میخواد محصولی رو بخره. به هر دلیلی به خطا میخوره و با وجود اینکه از کیف پولش کسر شده، ولی محصول به حسابش اضافه نشده. چه راهکاری برای هندل کردن چنین موقعیتی وجود داره بابت برگردوندن پول به حسابش؟این سوالی بود که در مصاحبه تکنیکال ازم پرسیده شد،‌ پیشنهادی که من دادم celery بود ولی گفتن هزینه بالایی برمیداره و نمیخوایم برنامه درگیر celery task بشه.یکی از راه حل های خوب این ماجرا،‌ Django transaction atomic بود.حالا به اصطلاح اتمی بودن چه کمکی میکنه؟ جنگو چک میکنه زمانی که تمام عملیات های کدی که سمت تراکنش نوشتید، موفقیت آمیز باید باشه و وقتی که مشکلی نبود، تغییرات در دیتابیس اعمال میشه. اگر به هر دلیلی exception اجرا شد جنگو roll back میزنه و تمامی تغییراتی که قرار بود انجام بشه رو کنسل میکنه و برمیگرده به حالت سابق خودش.اتمی بودن میتونه به نوعی تودرتو(nested) باشه. یعنی اگه محیط داخلی کدتون(block code) موفقیت آمیز بود ولی بلاک خارجی به خطا خورد، باز به طور کلی جلوی تغییرات رو میگیره.باعث میشه پرفورمنس حفظ بشه و بار اضافی سمت دیتابیس نباشهارور هندلینگ رو ساده تر میکنه و کمک میکنه که ارور ها راحتتر از حالت عادی بررسی بشنتمامیت دیتابیس حفظ میشه و جلوی تغییرات جزئی که باعث میشه اطلاعات به خطر بیوفتن رو تا حدی میگیرهاز طرفیباید مراقب lock شدن دیتابیس باشید خطای exception که قرار هست بنویسید با دقت روش کار کنید و خطای مناسبی سمت کاربر هدایت بشهتست هایی که قرار هست براش بنویسید باید تمامی سناریو ها رو تست بکنه و خطا رو بررسی کامل بکنهاز نکات خوبی بود که دوست داشتم بابتش یک توضیح کوتاهی داده باشم و امیدوارم براتون مفید بوده باشه.منبع: داکیومنت transaction جنگو</description>
                <category>Parsa Rezaei</category>
                <author>Parsa Rezaei</author>
                <pubDate>Mon, 29 Apr 2024 22:54:31 +0330</pubDate>
            </item>
                    <item>
                <title>Keycloak</title>
                <link>https://virgool.io/@ParsaRezaei/keycloak-nmzhciewtcnw</link>
                <description>سلام،قرار بود ادامه این موضوع رو بگم که خب متاسفانه به کل یادم رفته بود:) بریم سر وقتش.خب بحث این بود که چه راهی هست اگر تصمیمون این باشه که خارج از جنگو و دیتابیسمون دیتا کاربران ذخیره بشه؟ یکی از گزینه های روی میزمون Keycloak هستش.یک نرم افزار متن باز که برای مدیریت هویت و دسترسی (IAM)  استفاده قراره بشه. کاربرا مسیرشون از مسیر برنامه کامل جدا میشه در عوض توکن کاربر سمت برنامتون میره و بعد اجازه دسترسی بهش داده میشه. همچنین از پروتکل هایی مثل OpenID استفاده میکنه.یکسری اصطلاحات مهمش رو توضیح میدم که نیازه آشناییت کوچیکی ازشون داشته باشیم ولی چون جزئیاتش زیاد هستش پیشنهاد میدم که داکیومنت خودش رو مطالعه کنید:-- مورد اول بخش Users هستش که ویژگی های خاص خودشون رو دارن و میتونیم کاربران رو داخل یک گروه اختصاصی خودشون قرار بدیم مثل کارمندان شرکت آمازون.-- مورد دوم Authentication, Authorization هستش که خب مسئولیت اعتبارسنجی و دسترسی دادن به کاربر رو داره.-- مورد سوم Roles: نقش کاربرا مشخص میشه(کارمند،مدیر فروش،..)-- مورد چهارم User Role Mapping: این مورد رو میتونین داخل توکن مشخص کنید و برنامه میاد بر اساس دسترسی و نقشی که کاربرا دارن بهشون دسترسی میده. مثلا برای مدیر فروش فقط مواردی که نیاز هست رو میتونه دسترسی داشته باشه، نمیتونه به امتیازات کارمندای دیگه مثل برنامه نویسای شرکت رو بخواد دسترسی پیدا کنه. -- مورد پنجم Groups: تعدادی از کاربران رو میتونیم داخل یک گروه قرار بدیم مثلا تیم IT میتونن یک گروه باشن و امتیازات اون گروه رو استفاده کنند.-- مورد ششم Credentials: اعتبارنامه رو میشه مشخص کرد که تاییدیه هویت کاربر به چه صورت انجام بشه(گذرواژه، گواهی دیجیتال،رمز یک بار مصرف،...)-- مورد هفتم Authentication Flows: راهی که کاربر باید هنگام تعامل با جنبه های خاصی از سیستم  انجام دهد. این جریان ها مشخص می کنند که کاربر باید چه اطلاعاتی را وارد  کند و آیا چیزی همانند reCAPTCHA باید استفاده شود  یا خیر . همچنین سیاست هایی برای تغییر رمز عبور (بازنشانی) صورت می گیرد.-- مورد هشتم Realms: یک Realm و مجموعه از کاربران ، اعتبارنامه ها(Credentials)، نقش ها و  گروه ها را مدیریت می کند. کاربر به یک Realm تعلق دارد و وارد آن می شود.مواردی که بالا گفتم بخش کوچیکی از چنین سیستمی هستش، حالا اگر قرار باشه یک سناریو ازش بگم به این صورت هستش که شخص کارمند آمازون میخواد وارد سیستم برنامه ای که قراره ازش استفاده کنن بشه. بعد از احراز هویت، وارد Realm که مختص به شرکت آمازون میشه و بر اساس نقشی که داره، به برنامه دسترسی پیدا میکنه و کارش رو انجام میده. طبیعتا نمیتونه وارد Realm اپل بشه چون دیتایی از کارمند آمازون جای دیگه ای به غیر از Realm خودش استفاده نشده.امیدوارم براتون مفید بوده باشه:)لینک گیتهاب Keycloak</description>
                <category>Parsa Rezaei</category>
                <author>Parsa Rezaei</author>
                <pubDate>Thu, 25 Apr 2024 16:54:13 +0330</pubDate>
            </item>
                    <item>
                <title>پیدا کردن طولانی ترین زیر رشته(substring) غیر تکراری</title>
                <link>https://virgool.io/@ParsaRezaei/%D9%BE%DB%8C%D8%AF%D8%A7-%DA%A9%D8%B1%D8%AF%D9%86-%D8%B7%D9%88%D9%84%D8%A7%D9%86%DB%8C-%D8%AA%D8%B1%DB%8C%D9%86-%D8%B2%DB%8C%D8%B1-%D8%B1%D8%B4%D8%AA%D9%87substring-%D8%BA%DB%8C%D8%B1-%D8%AA%DA%A9%D8%B1%D8%A7%D8%B1%DB%8C-rd0taqnqgm0b</link>
                <description> سلام،یه مدت پیش مصاحبه فنی داشتم که یکی از سوالای الگوریتم که بهم دادن سوال خیلی خوبی بود که حتی داخل leetcode هم سوالش قرار داده شده، دوست داشتم راه حلی که بابتش سر و کار داشتم رو هم اینجا قرار بدم امیدوارم براتون مفید باشه.خط یک: خب ما فرض می کنیم که یک رشته ای داریم که &quot;abcabcbb&quot; هستش و میخوایم حساب کنیم که اندازه طولانی ترین substring غیر تکراری چقدر هستش.خط دو: یک متغیری به نام char_set مینویسیم و متد set() رو براش تعریف میکنیمخط سوم و چهارم: متغیر های max_length, left هم با مقدار صفر تعریفشون میکنیمخط پنجم که شروع سناریو کد ما هستش، به کمک متغیر right میایم بر اساس len رشتمون حلقه میندازیم. که خب میاد بر حسب هر المان بررسی میکنه آیا right[0] در متغیر char_set قرار گرفته یا نه و اگر نبود میره به بخش خط نهم و اون رشته رو به متغیر char_set اضافه میکنه. این کار تا آخرین المان رشتمون ادامه پیدا میکنه و به فرض وقتی با رشته ای برخورد کرد که داخل char_set قرار داشت، میاد از char_set اون رشته رو حذف میکنه و به متغیر left یکی اضافه میکنه و دوباره میره از اول، همون متغیری که حذف کرده بود رو دوباره اضافش میکنه و همین فرمون ادامه پیدا میکنه تا آخرین المان.که خب خروجی ما که میشه همون &quot;abc&quot; و اندازش میشه ۳.شما همینطور با دیباگر میتونین گام به گام بررسی کنین این کد رو که چطوری پیش میبره کار رو و تمام.... خیلی مختصر تموم شد، در آخر این رو هم اضافه کنم که تابحال تجربه توضیح دادن این چنینی یک سوال الگوریتمی رو نداشتم و اگر نظری دارید بابت اینکه توضیح بهتری ارائه داده بشه ممنون میشم که بهم بگید ممنونم:)</description>
                <category>Parsa Rezaei</category>
                <author>Parsa Rezaei</author>
                <pubDate>Fri, 19 Apr 2024 18:35:56 +0330</pubDate>
            </item>
                    <item>
                <title>معرفی Django Tenant به زبان ساده</title>
                <link>https://virgool.io/@ParsaRezaei/%D9%85%D8%B9%D8%B1%D9%81%DB%8C-%D8%AC%D9%86%DA%AF%D9%88-%D8%AA%D9%86%D9%86%D8%B3%DB%8C-%D8%A8%D9%87-%D8%B2%D8%A8%D8%A7%D9%86-%D8%B3%D8%A7%D8%AF%D9%87-pyfksjvxzojn</link>
                <description>سلام!یکی از تجربیات جالبی که داشتم Django-Multi-Tenant هستش..یعنی چی؟به طور ساده بخوام بگم: یک کد بیس شما دارید که میتونید خدماتی رو به مشتریاتون ارائه بدید، ولی قرار نیست همه مشتری ها داخل یک گروه قرار بگیرن! به فرض شما با شرکت آمازون قرارداد دارید که خدماتی بهشون ارائه بدید، کارمند های آمازون داخل یک tenant مجزا قرار میگیرن و هیچ کاربر دیگه ای نمیتونه به دیتای این tenant دسترسی داشته باشه و شخص کارمند آمازون با وارد کردن اطلاعاتش، وارد tenant خودش میشه. به صورت کلی هر tenant دیتا مجزایی داره ولی داخل یک پایگاه داده قرار میگیرن.حالا تفاوت بین یک سیستم multi tenant و single tenant چیه؟همونطور که داخل عکس میبینید، مشخص هستش که یک پروژه single tenant به عبارتی ساده تر هستش پیاده سازیش..که خب هدف شما اگر تنها یک گروه خاصی از افراد یا یک سازمان باشه میتونه گزینه خوبی باشه ولی یک مشکل اساسی داره! اونم اینه که تمام دیتاها داخل یک جا قرار میگیرن. خلاصه که امنیتش رو باید خوب حواستون باشه.و Multi tenant پیاده سازیش سخت تر هستش هم هزینه بیشتری رو احتمال داره که شما باهاش برخورد کنید. هر سازمان به صورت جدا از هم داخل tenant خودشون قرار میگیرن و خب برای نگهداری دیتاهاشون باید ساختار خوبی رو در نظر بگیرید. از لحاظ امنیت هم مزیت بالاتری داره در مقابل single tenant.در آخر تا یک قسمتی میتونیم امنیت رو بالا ببریم..دروغ چرا:)منابع خوبی بابت tenant هستش که میتونین استفاده کنین و بخونین هم بابت این معماری هم اینکه چطوری میشه داخل جنگو استفاده کرد:داکیومنت برای پیاده سازی Django tenantداکیومنت IBM برای Multi tenantسوال آخردیتا سازمان ها و کاربر ها داخل جنگو و دیتابیسی که ساخته شده قرار هست ذخیره بشه، اگه هدف این باشه که جنگو فقط نقش API request داشته باشه و دیتاها توی سیستم دیگه ای خارج از جنگو باشن چطور؟تلاشمو میکنم یکی از راه حل هاشو بزودی براتون پست بذارم.امیدوارم که این پست براتون مفید بوده باشه و اگر تجربه یا راه حل بهتری بابت این مسئله داشتید، خوشحال میشم که منم همراه تجربیاتتون بشم:) </description>
                <category>Parsa Rezaei</category>
                <author>Parsa Rezaei</author>
                <pubDate>Tue, 19 Mar 2024 04:43:51 +0330</pubDate>
            </item>
                    <item>
                <title>بیشتر از Postman و اجرای سناریو و تست بدونیم</title>
                <link>https://virgool.io/@ParsaRezaei/%D8%A8%DB%8C%D8%B4%D8%AA%D8%B1-%D8%A7%D8%B2-postman-%D9%88-%D8%A7%D8%AC%D8%B1%D8%A7%DB%8C-%D8%B3%D9%86%D8%A7%D8%B1%DB%8C%D9%88-%D9%88-%D8%AA%D8%B3%D8%AA-%D8%A8%D8%AF%D9%88%D9%86%DB%8C%D9%85-pztnuwhpq4vz</link>
                <description>سلام، امیدوارم که حالتون خوب باشه.به عنوان اولین پست، خواستم در مورد موضوعی که خودم باهاش اخیرا درگیر شدم رو باهاتون به اشتراک بذارم امیدوارم مفید باشه واستون:)اول از همه اینکه من از Postman فقط به عنوان داکیومنت API برای پروژه استفاده میکردم و اونقدر عمیق نشده بودم بهش که استفاده بیشتری ازش بکنم تا اینکه توی پروژه آخری که کار کردم به عنوان تست نویس برای پروژه Back-End(Node.js)، تجربه نوشتن تست داخل Postman و سناریو محور بودن API ها رو کسب کردم.خب ما فرض می کنیم که سه تا API داریم که قراره موقع اجرای سناریو داخل Postman با همدیگه هندل بشناین اولین API که POST req هست که قراره به عنوان JSON body ازش استفاده بکنیم و هدف این هستش که objectId رو از ریسپانس برداریم و به env اضافه بکنیم که از این id بخوایم برای GET req استفاده کنیم.طبیعتا نمیتونیم از Pre-request script استفاده بکنیم چون میخوایم از ریسپانس id رو بگیریم و اون رو به env اضافه کنیم، پس اون رو داخل فیلد تست اضافه میکنیم:طبق خط یک از Postman میخوایم که یک متغیر به نام objectId داخل env اضافه بکنه و value متغیر رو از objectId که ریسپانس داده برداره و بهش اضافه بکنه.بعد از send request این فیلد اعمال میشهحالا میرسیم به بخش دوم که ما میخوایم جزئیات id که ساخته شد رو داخل GET req مشاهده بکنیم.پ.ن: چون قرار هستش که تست ها به ترتیب و بر اساس سناریو هایی که انجام میشن بررسی بشه قرار هست اینکارو بکنیمحالا رسیدیم سر وقت Pre-request Script، اگه بخوام یک توضیح کوچیکی از این فیلد بکنم کاری که میکنه و از اسمش هم مشخص هستش اسکریپتی رو که شما نوشتین قبل از اجرای درخواست رکوئست براتون اجراش میکنه.خط اول یک متغیر نوشتن به اسم objectId و ازش میخوام که value متغیر objectId که داخل env مشخص کردم رو برش داره و توی خط ۴ خواستم url رو برای اجرای درخواست مشخص بکنم که در آخر id رو بهش اضافه میکنه که بتونم جزئیاتشو داخل ریسپانس ببینم.در آخر بعد از اجرای این اسکریپت ریسپانس بادی اون id مورد نظرمو میتونم ببینم.میرسیم به بخش سوم APIفرض کنین دوتا مدل داریم که به هم وابسته هستن، شما یک مدل دارید به نام Plan و یک مدل به نام Post که شما برای ایجاد Post داخل Plan مورد نظرتون، id پلن رو باید داشته باشید درسته؟ و شما حین اجرای سناریو نمیتونین دستی این کار رو انجام بدید که تست مراحل خودش رو پیش ببره و وقت گرفته میشه.در اینجا شما داخل فیلد objectId یک متغیر به همین نام مشخص میکنید و تنها قدم بعدیتون این هستش که داخل Pre-request یک خط اسکریپت بنویسید و ازش بخواین که objectId ست شده در env رو که id پلن هستش رو برداره و در داخل JSON body قرارش بده. به همین سادگی این ۳ API رو بخواید باهمدیگه اجراش بکنین و تستتون رو اجرا بکنین و فقط با ۳ ۴ خط اسکریپت میتونین از دستی تست کردن API فاصله بگیرید:)امیدوارم که براتون مفید بوده باشه و کمک کرده باشه بهتون=)</description>
                <category>Parsa Rezaei</category>
                <author>Parsa Rezaei</author>
                <pubDate>Thu, 29 Feb 2024 00:42:04 +0330</pubDate>
            </item>
            </channel>
</rss>