Смотреть в Telegram
#پست_جدید میخوام درمورد یک موضوع خیلی جالب توی جنگو صحبت کنم که اکثرا توش مشکل دارن خب اون چیه؟ 🤓 کش شدن نتیجه کوری ها❗️ میدونستید که جنگو نتیجه کوری هارو کش میکنه؟ حالا این یعنی چی ⁉️ یعنی جنگو فقط یک بار دیتابیس رو هیت میکنه و دیتا رو میگیره و همونو کش میکنه و از دفعه های بعدی تا زمان پایان اجرای تابع فعلی از اون نتیجه کش شده استفاده میکنه حالا بیاید توضیح بدم. ⭕️ قبلش یه نکته مهم رو بگم: ⭕️ هر چیزی که باعث ایجاد یک QuerySet جدید بشه باعث هیت شدن جدید به دیتابیس خواهد شد. حالا بریم مثالو ببینیم:
users = User.objects.all()
print(users)

if users:
    for u in users:
         print(u)
خب تو این کد بنظرتون چند بار دیتابیس توسط جنگو هیت وصدا زده میشه میشه؟ حتما فکرمیکنید ۳ بار نه اینجوری نیست ❗️ اینجا فقط 2 بار داره به دیتابیس هیت میزنه. 1️⃣ توی خط اول ما فقط queryset رو تعریف کردیم. از اونجایی که میدونید کوری ست ها توی جنگو lazy هستن و تا وقتی که صداشون نزنیم اجرا نمیشن. 2️⃣ توی خط دوم ما queryset رو print کردیم و اولین هیتمون به دیتابیس زده میشه ولی یه نکته print نمیره کل رکورد هارو بیاره چون منطقی نیست. پرینت یک محدودیت داره برای آوردن رکورد ها مثلا اگه شما هزار تا رکورد داشته باشید print کل اون هزار تا رو نمیاره و مثلا ۱۰۰ تاشو میاره دومین نکته اینه که اینجا هیچ کشی اتفاق نمی افته( دلیلشو جلوتر میگم) 3️⃣ توی خط سوم ما میخوایم با if بررسی کنیم کاربری وجود داره یا نه اینجا جنگو میاد کش ر و چک میکنه تا ببینه برای users ریزالتی کش شده یانه اینجا میبینه هیچ کشی وجود نداره و در نتیجه اینجا دومین هیتمون به دیتابیس میخوره و کل رکورد هارو برمیگردونه و مثل print عمل نمیکنه و نکته بعدی اینه اینجا ریزالت کوری توی رم سرور توسط جنگو کش میشه حالا اینجا جالب میشه😁 توی خط بعدی که یه حلقه زدیم روی users اینجا میاد کش رو چک میکنه و میبینه که ریزالت users کش شده و میاد از اون کش استفاده میکنه و به دیتابیس هیچ کوری نمیزنه و درنتیجه اینجا فقط دوبار به دیتابیس هیت خورده میشه حالا چرا print نتیجش کش نشد؟ به گفته خود جنگو، جنگو فقط زمانی ریزالت یه queryset رو کش میکنه که اون queryset کامل اجرا بشه. و توی print چون queryset کامل اجرا نمیشه منطقا ریزالتش کش نمیشه ولی توی if چون queryset کامل اجرا شد ریزالتشم کش شد برای اثبات این حرفم میتونید چیزایی که کش شده رو ببینید 👇
users = User.objects.all()
print(users)
print("Cache: ", users._result_cache)

if users:
    print("Cache: ", users._result_cache)
    for u in users:
        print(u)
خروجی این کد هم این خواهد بود:
<QuerySet [<User: mohammad>]>
Cache:  None
Cache:  [<User: mohammad>]
mohammad
همونطور که میبینید بعد از اجرا شدن print هیچ ریزالتی کش نشده و کش خالیه چون queryset کامل اجرا نشد. ولی وقتی if اجرا شد چون queryset کامل اجرا شد ریزالتم کش شد و ازاین به بعد از کش استفاده میکنه. یه نکته در پایان بگم این کش تا زمانی باقی میمونه که اجرای تابع تموم شه و بعد ازاون توسط garbage collector از مموری سرور پاک میشه جنگو توسط پایتون و پایتون روی سرور اجرا میشه. توی پستای بعدی درمورد garbage collector بیشتر توضیح میدم #جنگو #کش_در_جنگو #برنامه_نویسی @ninja_learn_ir
Telegram Center
Telegram Center
Канал