جنگولرن
3.78K subscribers
287 photos
74 videos
31 files
554 links
آموزش Django و بستگان
Download Telegram
جنگولرن
db_ali.pdf
orm_ali.pdf
691.6 KB
پیاده سازی انواع Relation ها با استفاده از Django ORM

از لینکدین علی بیگدلی

تو پست قبلی با توضیحات کلی مدل های ارتباطی آشنا شدیم و در این پست می خوایم این ارتباطات رو در قالب کلاس های مدل تشریح کنیم. باید در نظر داشته باشید که سناریو ها برای پیاده سازی در هر پروژه ممکنه متفاوت باشن و منتهی مراتب از لحاظ عملکرد یکی هستن. نکته ای که اهمیت داره دیدگاه و جوانب اون هستش که چطور به یک مسئله نگاه میشه در طراحی، گاهی اوقات مدل های طراحی تقریبا یکی به نظر میان ولی اسم گذاری هاشون فرق دارن و برای همین که منطق متفاوتی رو علاوه بر تشابه میرسونن.
در کل باید سعی کنیم تا بیشتری میزان اطلاعات رو توی بخش طراحی کسب کنیم تا در پروژه های بزرگتر قدرت تصمیم گیری بیشتری پیدا کنیم.
از جمله مواردی که به نظر من می تونه خیلی بهتون درک عمیق بده و شاید خیلی درگیرش نباشید Generic Relation و استفاده از Through هستش که خودم در زمانی که باهاشون آشنا نبودم دنبال راه حل های مشابهی میگشم که در نهایت همین ساختار رو پیاده سازی می کردم ولی اصلا نمی دونستم جنگو خودش داره، پس سعی کنین بیشترین میزان دید رو پیدا کنین تا دچار این مشکل نشید.
👍51
جنگولرن
نسخه قبلی دوره ساخت فروشگاه اینترنتی با جنگو رایگان شد. سرفصل های دوره قبل: ✔️ ساخت پروژه فروشگاه ✔️پیاده سازی قالب ✔️ ساخت مدل ها و ایجاد ارتباط منطقی بین جداول پایگاه داده ✔️ آشنایی با PostgreSQL ✔️ آماده سازی سبد خرید با Django Session – ✔️ ساخت Context…
دوره مقدماتی آموزش جنگو رایگان شد.

✔️نصب جنگو
✔️ساخت اولین پروژه django
✔️طراحی مدل ها
✔️آماده سازی پنل ادمین django
✔️آشنایی با Query Set و Shell
✔️ساخت List view و Detail view
✔️ایجاد Template متناسب با View ها
✔️اضافه کردن صفحه بندی (Pagination)
✔️طراحی مدل های ثبت نظرات وبلاگ
✔️ثبت نظر با استفاده از Form ها
✔️افزودن تگ به مطالب با استفاده از پکیج Taggit
✔️ساخت Custom Template Tag ها

ان شالله به مرور ویدئوهاش رو توی آپارات - یوتیوب و تلگرام به صورت کامل آپلود میکنم.
👍123
.

لینک ویدیوی جلسه ۱۷:

https://youtu.be/gJWKPcCsRbg

در این ویدیو، به توضیح جامع و کاملی در مورد لاگینگ (Logging) در برنامه‌نویسی پایتون پرداخته‌ام. موارد زیر را بررسی کرده‌ایم:

1. اهمیت لاگ‌ها: توضیح می‌دهیم که چرا لاگ‌ها برای اشکال‌زدایی، نظارت، حسابرسی و بهینه‌سازی عملکرد برنامه‌ها اهمیت دارند.

2. مفاهیم پایه‌ای لاگینگ در پایتون: نحوه استفاده از ماژول داخلی logging در پایتون و نحوه ایجاد پیام‌های لاگ در سطوح مختلف (DEBUG، INFO، WARNING، ERROR، CRITICAL).

3. لاگ‌های رنگی: استفاده از کتابخانه‌هایی مثل coloredlogs برای ایجاد لاگ‌های رنگی که خوانایی و شناسایی سریع‌تر پیام‌ها را فراهم می‌کند.

4. ذخیره لاگ‌ها در فایل: نحوه پیکربندی لاگینگ برای ذخیره لاگ‌ها در فایل به جای نمایش در کنسول، و استفاده از FileHandler.

5. سفارشی‌سازی لاگ‌ها: نحوه سفارشی‌سازی فرمت لاگ‌ها و افزودن هندلرهای مختلف برای ارسال خروجی به مکان‌های مختلف.

6. اجرای برنامه با سطوح مختلف لاگ: تنظیم سطح لاگینگ به صورت پویا با استفاده از متغیرهای محیطی یا آرگومان‌های خط فرمان.

7. افزونه‌ها و کتابخانه‌های مختلف برای لاگینگ در پایتون: معرفی کتابخانه‌هایی مانند loguru و structlog برای بهبود و تسهیل فرآیند لاگینگ.

8. معرفی و تمجید از سنتری: توضیح مزایای استفاده از Sentry برای نظارت بر خطاها و استثناها در برنامه‌ها، و چگونه Sentry می‌تواند به بهبود اشکال‌زدایی و ارائه گزارش‌های دقیق کمک کند.


جزوه ای که روش تدریس میکنم :
https://github.com/SEYEDBAX/course-notes/tree/main/lesson-17


🔔 حتما حتما یوتیوب رو فالو کنید و ویدیو رو لایک کنید و نوتیف رو روشن بزارید 🫶

https://t.me/QaDeveloper

@SEYED_BAX | @MakeDeveloper
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Transaction in #django

اگه نمیدونید به طور کلی ترنزاکشن چیه میتونید به این لینک سر بزنید. ولی خیلی خلاصه بخوام بگم به انجام چندتا کوئری مختلف ولی در یک unit ترنزاکشن میگن، یعنی شما ۳ تا کوئری انجام میدی، اگه حتی یکدونه از اون ۳ تا ارور بخوره بقیه ۲ تا هم هر تغییری داده باشن اون برمیگردونن یا به اصطلاح Rollback میکنه.

حالا #جنگو این قابلیت به شما میده که از این فیچر دیتابیس‌ها داخل کدتون استفاده کنید برای این کار میتونید از transaction.atomic استفاده کنید، این فانکشن هم قابلیت استفاده به عنوان دکوریتور رو داره هم کانتکس منیجر


به عنوان دکوریتور:
@transaction.atomic()
def something():
do_database_update()
do_database_delete()


یا به عنوان کانتکس منیجر:

def something():
with transaction.atomic():
do_database_update()
do_database_delete()

تو هر دو کد اگر اتفاقی داخل یکی از فانکشن ها بیوفته یعنی اگر ارور raise بشه کوئری‌ها و تغییراتی که رو دیتابیس اعمال شده همه rollback میشه و برمیگرده، شما میتونید چندتا ترنزاکشن به صورت nested هم انجام بدید برای مثال:

with transaction.atomic():
do_update():
with transaction.atomic():
do_delete()

تو اینجا باید یک نکته رو در نظر داشته باشید که جنگو هربار که یک nested میزنید از بیرون به داخل میره و هربار که وارد یک مرحله عمیق تر میشه یک savepoint میسازه از نستد بالایی یعنی اول ترنزاکشن آپدیت انجام میده بعد savepoint میسازه که بفهمه چیکار کرده بعد میره دومی، میتونید ساخت savepoint رو غیر فعال کنید با پاس دادن savepoint=false به فانکشن اتومیک که توصیه جنگو اینه که اینکار نکنید مگر اینکه واقعا مشکل پرفورمنس بخورید.

در پست بعدی درباره Transaction.on_commit صحبت میکنم :)

@TorhamDevCH
👍3
مشکل concurrency چیه و چطوری میتونیم داخل #جنگو حلش کنیم؟

بیایید اول بفهمیم مشکل چی هست اصلا که میخواییم حلش کنیم. از زمانی که انسان‌ها موفق شدم چند پروسس رو همزمان اجرا کنن این مشکل به وجود اومد برای مثال این روزها دیگه شما فقط یک ترد پروژه جنگوتون اجرا نمیکنید بلکه با ابزارهای مثل گونیکورن و یونیکورن و ... چندتا ترد و پروسس ازش اجرا میکنید تا همچی سریعتر اتفاق بیوفته. اما این مشکل که اتفاق میوفته چیه؟

فرض کنید شما یک سیستم بانکی دارید و داخل این بانک یک حساب مشترک دارید بین user1 و user2. هردو این یوزرها به این حساب دسترسی دارن یوزر اول پرداخت کننده است و یوزر دوم برداشت کننده حالا فکر کنید بالانس(موجودی) حساب ۱۰۰۰ دلاره.

در همین لحظه که ما هستیم user1 میخواد ۱۰۰ دلار به حساب واریز کنه و دقیقا همزمان باهاش user2 میخواد ۱۰۰ دلار برداشت کنه. سوال اینه که در آخر این برداشت و واریز موجود یا همون بالانس حساب چقدر خواهد بود؟ جواب منطقی ما اینه که بالانس همون هزار دلار خواهد بود چون ۱۰۰ دلار اومد و ۱۰۰ دلار هم رفت و آره! اگه برنامه ما فقط و فقط یک پروسس باشه این ۲ درخواست به ترتیب اجرا خواهد شد و بالانس همون هزار دلار میشه اما اگه برنامه بیشتر از یک پروسس باشه چه اتفاقی میوفته؟

خوب بیایید فرض کنیم این بار درخواست اول به پروسس شماره ۱ و درخواست دوم به پروسس شماره ۲ میره و این دو همزمان از دیتابیس بالانس حساب میخونن تا درنهایت بهش جمع و منها بزنن دیگه. مراحل این خواهد شد.

۱. یوزر اول درخواست میزنه و موجودی ۱۰۰۰ دلار رو دریافت میکنه
۲. یورر اول موجودی آپدیت میکنه به ۱۱۰۰ دلار .

۳. یوزر دوم دقیقا تو همون لحظه درخواست میزنه و قبل اپدیت شدن موجودی اون میگیره و نتیجه موجودی برای ۱۰۰۰ دلاره
۴. ازش ۱۰۰ تا کم میکنه و ۹۰۰ رو به عنوان بالانس ذخیره میکنه.


و درنهایت موجودی شد ۹۰۰ دلار! این ماجرا میتونست برعکس هم اتفاق بیوفته و موجودی بشه ۱۱۰۰ دلار که همش نتیجه یک چند صدم ثانیه اختلاف بین ریکوئست یک و دو بود. نکته اصلی این بود که اینا قبل اینکه اون یکی موجودی آپدیت موجودی رو میخوندن و داخل مموری ذخیره میکردند در نتیجه تو اپدیت هم اشتباه اپدیت میکردند.


حالا که فهمیدید ماجرا از چه قرار شما میتونید داخل #django با استفاده از select_for_update و ترنزاکشن که پست‌ها قبل توضیح دادم این ماجرا حل کنید. ( در حقیقت جنگو ماجرا رو حل نمیکنه بلکه با استفاده از متدها شما به جنگو میگید کوئری بسازه که نتیجه اش این بشه که دیتابیس براتون یک لاک رو row که میخوایید آپدیت کنید بگیره)


حالا روش استفاده و توضیحات بیشتر میتونید تو مقاله پایین بخونید. این پست خلاصه‌ای کوتاه از مقاله زیر بود ( خود مقاله هم کوتاه)

https://www.sankalpjonna.com/learn-django/managing-concurrency-in-django-using-select-for-update

@TorhamDevCH
👍71
جنگولرن
دوره مقدماتی آموزش جنگو رایگان شد. ✔️نصب جنگو ✔️ساخت اولین پروژه django ✔️طراحی مدل ها ✔️آماده سازی پنل ادمین django ✔️آشنایی با Query Set و Shell ✔️ساخت List view و Detail view ✔️ایجاد Template متناسب با View ها ✔️اضافه کردن صفحه بندی (Pagination) ✔️طراحی…
به صورت کامل آپلود شد

دوره رایگان مقدماتی آموزش جنگو

✔️نصب جنگو
✔️ساخت اولین پروژه django
✔️طراحی مدل ها
✔️آماده سازی پنل ادمین django
✔️آشنایی با Query Set و Shell
✔️ساخت List view و Detail view
✔️ایجاد Template متناسب با View ها
✔️اضافه کردن صفحه بندی (Pagination)
✔️طراحی مدل های ثبت نظرات وبلاگ
✔️ثبت نظر با استفاده از Form ها
✔️افزودن تگ به مطالب با استفاده از پکیج Taggit
✔️ساخت Custom Template Tag ها

لینک لیست پخش آپارات:
https://www.aparat.com/playlist/10321397
3👍3
📣تبلیغ رایگان

Python tips and tricks
The Good, Bad and the Ugly

📚توی این کانال فقط قرار هست در مورد core python صحبت کنیم.

👨‍💻این کانال یک بلاگ شخصی هست و پیرامون نظرات و چیزهایی که توی این چند سال کد زدن یاد گرفتم (فقط برای کمک به دوستان تازه‌کار)👨‍💻


@Mtio975

https://t.me/pythonwithmedev
👍2
وبینار بررسی پلتفرم های فریلنسر داخلی و نحوه گرفتن کار در این پلتفرم ها

در این وبینار قرار است از تجربیات مهندس محمد شکاری بادی در زمینه نحوه فعالیت به عنوان فریلنسر و استفاده از پلتفرم هایی همچون پونیشا و ... استفاده کنیم.

از جمله مواردی که بررسی خواهد شد:
- پیش نیاز ها و نیاز مندی های ورود به این بازار
- میزان تجربه چقدر تاثیر گذار خواهد بود
- از کجا شروع کنیم و چطور
- رزومه نویسی در این پلتفرم ها
- نکاتی در بهتر دیده شدن
- نحوه تعامل با کارفرما
- قیمت گذاری
و...

زمان برگزاری :
پنجشنبه ۳۱ خرداد - ساعت 18:00

ظرفیت: 100نفر
هزینه: رایگان 😁
لینک ثبت نام:
https://thealibigdeli.ir/event/
👍3
تا حالا براتون سوال شده جنگو چطوری وقتی یک رابطه one2many یا همون فارنکی میزنید چطوری وقتی فیلد صدا میکنید ابجکت فارنکی بهتون میده؟ یا چطوری کوئری look up هایی که میزنید برای مثال داخل filter رو هندل میکنه؟
مثلا رابطه بین مدل a و b دارید بعد همچنین چیزی مینویسید

a.fk.name
و جنگو مقدار name رو میده یا وقتی فیلتر میزنید
a.objects.filter(fk__name="test")

جنگو این‌ها رو با استفاده از descriptor در پایتون انجام میده که قابلیت‌های خفنی به کلاس‌تون میده، برای مثال وقتی یک attribute از یک کلاس صدا بزنید درجا یک کد ران کنید و خیلی چیزا دیگه که الان طولانی میشه توضیح بدم، در نتیجه پاشید برید داکیومنتشو بخونید :)

https://docs.python.org/3/howto/descriptor.html

@TorhamDevCH
👍6🥱2
جنگولرن
نسخه قبلی دوره ساخت فروشگاه اینترنتی با جنگو رایگان شد. سرفصل های دوره قبل: ✔️ ساخت پروژه فروشگاه ✔️پیاده سازی قالب ✔️ ساخت مدل ها و ایجاد ارتباط منطقی بین جداول پایگاه داده ✔️ آشنایی با PostgreSQL ✔️ آماده سازی سبد خرید با Django Session – ✔️ ساخت Context…
به صورت کامل آپلود شد

دوره رایگان ساخت فروشگاه اینترنتی با جنگو

✔️ ساخت پروژه فروشگاه
✔️پیاده سازی قالب
✔️ ساخت مدل ها و ایجاد ارتباط منطقی بین جداول پایگاه داده
✔️ آشنایی با PostgreSQL
✔️ آماده سازی سبد خرید با Django Session –
✔️ ساخت Context Processor اختصاصی
✔️ ثبت سفارش مشتری و ارائه شماره سفارش
✔️ راه اندازی درگاه پرداخت اینترنتی
✔️ کانفیگ پکیج django-allauth
✔️ عضویت با django-allauth و  Authentication
✔️ گانفیک email جهت ارسال تاییدیه عضویت به کاربر
✔️ ساخت API در Google Developer Console
✔️ ثبت نام در سایت با Google Account

لینک لیست پخش آپارات:
https://www.aparat.com/playlist/10357582
👏9
.

لینک ویدیوی جلسه 18:

https://youtu.be/OuyMAOgwZbc

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

جزوه ای که روش تدریس میکنم :
https://github.com/SEYEDBAX/course-notes/tree/main/lesson-18


🔔 حتما حتما یوتیوب رو فالو کنید و ویدیو رو لایک کنید و نوتیف رو روشن بزارید 🫶

https://t.me/QaDeveloper

تمرین : طبق مواردی که در انتهای ویدیو گفته شد به کمک شی گرایی ۴ امین ماشین حساب رو هم شما بسازید

@SEYED_BAX | @MakeDeveloper
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1👎1
Media is too big
VIEW IN TELEGRAM
دو تا تابع مهم در جنگو به نام های:
prefetch_related & select_related

از لینکدین Ebrahim Kiani

سلام خدمت دوستان عزیز لینکدین👋🏻
امیدوارم حالتون خوب باشه🙂
تو این کلیپ کوتاه آموزشی سعی کردم دو تا تابع مهم در جنگو به نام های:
prefetch_related & select_related
که در پرفورمنس برنامه هامون هم نقش بسزایی دارند رو آموزش بدم.
البته این مباحث را خودم از داخل یکی از مصاحبه هام یاد گرفتم و برای همین کلیپ آن را درست کردم.
پیشاپیش ممنونم از حمایت هاتون🤗
🔥7
Forwarded from Microfrontend.ir
از هفته بعد تمرکز کانال بر روی داکر و پستگرس خواهد بود و پلی لیست‌های جاوا اسکریپت رو هم با سرعت کمتری ادامه می‌دم. روی یک پلی لیست آموزش Go هم دارم کار می‌کنم که چون می‌خوام مثل پلی لیست‌های ناقص دیگه نشه تا کامل ضبط نکنم منتشر نمی‌کنم. برای حمایت از کانال به دوستان خود بگویید :)

https://youtube.com/microfrontend

〰️〰️〰️〰️〰️〰️
© | @microfrontend_ir
3👍3🔥1
بیایید به بهانه آپتومایز کردن کوئری‌های #جنگو چندتا چیز جدید درباره ORM جنگو یاد بگیریم

شما همیشه وقتی چیزی رو نیاز دارید داخل جنگو همچین کوئری میزنید:

Record.objects.filter(id__in=[1,2,3,4])


خب این قرار آبجکت‌هایی که ایدی ۱ تا ۴ دارن بهمون بده. حالا شما میخوایید با اینا یکسری پردازش انجام بدید مثلا بیایید اسم همه رکوردها رو نشون کار برید یا به عبارتی:


for r in records:
print(record.name)


و کار شما اینجا تموم میشه و خوشحال میشید. اماااااااا شما یک عالمه پردازش بی جا انجام دادید و یک عالمه منابع الکی خرج کرید. بیایید ببینیم کوئری بالا وقتی sql میشه چه شکلی میشه:



SELECT id,
name,
created_at,
is_deleted
FROM records
WHERE id IN (1, 2, 3, 4);


این چیزی که داخل دیتابیس اجرا میشه. متوجه اش شدید؟

اگه نشدید باید بگم شما فقط به فیلد name نیاز داشتید اما تمام فیلدهای اون اون رکوردها رو گرفتید! هیچ وقت هم ازشون استفاده نکردید.

برای حل این مشکل جنگو دوتا راه حل داره:
1. values
2. values_list

با استفاده از این دو میتونید فقط فیلدهایی که میخوایید رو بگیرید. برای مثال:



Record.objects.filter(id__in=[1,2,3,4]).values('name')



و حالا کوئری که میسازید همچین چیزی خواهد شد:


SELECT name
FROM records
WHERE id IN (1, 2, 3, 4);



و همینطور که میبینید حالا فقط اون فیلدی رو گرفتید که لازمش دارید.

تفاوت بین values و valuse_list تنها در دیتا استراکچر خروجی که به شما میده و داخل کوئری نهایی هردو مثل هم عمل میکنن. برای درک بیشتر:



>>> Record.objects.filter(is_deleted=False).values('id', 'name')
<QuerySet [{'id': 1, 'name': 'First record'}, {'id': 2, 'name': 'Second Record'}, {'id': 3, 'name': 'Third Record'}]>

>>> Record.objects.filter(is_deleted=False).values_list('id', 'name')
<QuerySet [(1, 'First record'), (2, 'Second Record'), (3, 'Third Record')]>


بله یکی دیکشنری و دومی تاپل :) همچنین اگه فقط فقط یک فیلد میخوایید مثلا name میتونید از flat=True هم استفاده کنید برای بهتر شدن دیتا خروجی:


>>> Record.objects.filter(is_deleted=False).values_list('name',flat=True)
<QuerySet ['First record', 'Second Record', 'Third Record']>


@TorhamDevCH
👍14🔥71
Media is too big
VIEW IN TELEGRAM
ساخت توکن لینک فعالسازی ایمیل در جنگو

بخشی از آپدیت جدید دوره فروشگاه اینترنتی با جنگو.
این قسمت در مورد اینا صحبت شد:
✔️مفهوم توکن
✔️کد بندی Base64
✔️متد get current site
✔️یکی از دلایل نگهداری امن از secret key جنگو
✔️و...

لینک آپارات:
https://www.aparat.com/v/uskbt0m
هر انتقاد یا پیشنهادی به این قسمت دارید به @miladhzz پیام بدید

لینک خرید این دوره 🫣🤫 :
https://www.daneshjooyar.com/project-django/

تشکر
👍3
چطور کوئری آپدیت بهتری داخل #جنگو بزنیم؟

روش‌های زیادی برای آپدیت کردن یک آجکت یا چندتا آبجکت داخل جنگو وجود داره، ساده ترین حالتی که افراد استفاده میکنن همچین چیزی.

مدل فرضی:

class Records(models.Model):
name = models.Charfield()
balance = models.InetegerField()
country =models.CharField()

برای مثال اگه کسی بخواد یک آبجکت از این مدل رو آپدیت کنه همچین کار میکنه:

r = Records.objects.get(pk=1)
r.name = "new name"
r.save()

که این اوکیه، بد نیست و آپدیت براتون انجام میده اما یک نکته رو بهش توجه نمیکنید!

زمانی که شما یک آبجکت این شکلی آپدیت میکنید در اصل دارید تمام فیلد‌ها رو آپدیت میکنید :) ولی خب مقدار فیلدهای قبلی همون قبلی ها آپدیت میشه، برای اینکه از این کار جلو گیری کنید باید explicit ( نمیدونم، فکر کنم دقیق تر معنی بده) باشید یعنی، دقیقا بگید کدوم فیلد/فیلدها میخوایید آپدیت کنید. این کار میکنید با استفاده از پارامتر update_fields انجام بدید.

r = Records.objects.get(pk=1)
r.name = "new name"
r.save(update_fields=["name"])


البته باید مراقب باشید که حتما فیلدهایی که میخوایید آپدیت کنید رو داخلش بزارید مگرنه آپدیت نمیشن.

پست بعدی آپدیت کردن چند آبجکت...


@TorhamDevCH
9👍6
این کد جنگو رو ببینید. کاربر با موبایل میتونه لاگین میکنه.
به هر دلیلی خواستیم بتونه فقط با فیلد موبایل لاگین کنه.

سوال:
وقتی به این راحتی میشه لاگین کرد چه نیازی به ساختن authentication backend داریم؟

اون django_login همون متد login جنگو هست. توی django.contrib.auth

آپدیت سوال:
ببیند مثلا من میخوام ادمین با user, pass توی پنل ادمینم لاگین بشه.
اما کاربرهای من با مثلا موبایل لاگین بشن.
برای لاگین شدن فقط میتونم با کال کردن متد لاگین و دادن user بهش اون user رو لاگین کنم.
پس چه نیازی به ساخت authentication backend کاستوم دارم؟
4🔥1
در مورد سوال قبلی

ببینید همونطوری که از اسمش پیداست authentication backend کارش authenticate هست.
اما کدی که من نوشتم لاگین کرده.

✔️بکند کارش لاگین کردن نیست. کارش احراز هویته (دقت کنید نه احراز دسترسی. با authorization فرق داره)
یعنی فقط میگه مثلا این موبایلی که دادی این اوکیه و اینم یوزرش هست.
بعد یوزری که میده رو لاگین می کنیم خودمون.

وقتی بکند کاستوم می سازیم. مثلا یه بکند داریم فقط موبایل میگیره. یکی هم پیشفرض سیستم هست با user, pass
وقتی متد authenticate رو (که توی django.contrib.auth هست) صدا می زنیم.

✔️خود جنگو تشخیص میده با کدوم بکند authenticate کنه. البته از لیست بکندهایی که توی تنظیمات هست استفاده میکنه.

✔️و البته signature ع بکند هم مهمه برای این تشخیص و اولین بکندی که باهاشون بخونه رو استفاده میکنه. البته اگه signature شون مثل هم باشه به ترتیبی که قرار دارند authenticate میکنه و اولی که اوکی بشه دیگه ادامه نمیده.

عکس کدهای جنگو هست. ببینید داره for میزنه توی بکندهایی که ما توی settings مشخص می کنیم. خط 68
👍41