Forwarded from TorhamDev | تورهام 😳
این توانایی که خود #جنگو بهتون میده ولی از trick دیگه هم میتونید استفاده کنید و اون هم ساختن یک مدل ابسترکت و بقیه مدلها ازش ارث ببرن.
مثال:
از اونجایی که اگه داخل مدل #django فیلدی داشته باشید که داخلش primary_key مقدار True داشته باشه جنگو دیگه از اون مقدار دیفالتی که مشخص کردید (هردو حالت دو پیام بالا) استفاده نمیکنه و میاد از این فیلد استفاده میکنه. حالا شما میتونید بقیه مدلهاتون رو از این مدل ارث بری کنید و دیگه نگران مقدار id نباشید.
@TorhamDevCH
مثال:
from django.db import models
from uuid import uuid4
class Base(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
class Meta:
abstract = True
از اونجایی که اگه داخل مدل #django فیلدی داشته باشید که داخلش primary_key مقدار True داشته باشه جنگو دیگه از اون مقدار دیفالتی که مشخص کردید (هردو حالت دو پیام بالا) استفاده نمیکنه و میاد از این فیلد استفاده میکنه. حالا شما میتونید بقیه مدلهاتون رو از این مدل ارث بری کنید و دیگه نگران مقدار id نباشید.
@TorhamDevCH
❤3👍3
Forwarded from TorhamDev | تورهام 😳
خب من یک چیز خیلی جالب و در این حال گیجکننده درباره ORM #جنگو فهمیدم.
تو پیام قبلی گفتم که کوئریهای #django دقیقا چه زمانی واقعا اجرا میشن. اما اینجا یک نکته دیگهای هم هست، جنگو نتیجه کوئریهارو کش میکنه.
و این خیلیییییییییییی مهمه، یعنی بعضی از جاها که فکر میکنید جنگو قرار دیتابیس هیت کنه هیت نمیکنه و از کش استفاده میکنه و بعضی جاها که فکر میکنید قرار کش استفاده کنه واقعا هیت میکنه. دونستن و فهمیدن این که چه زمانی کش استفاده میکنه چه زمانی نه حدود ۲ ساعت از من زمان گرفت :) ولی تو این پست توضیح میدم چیزی که فهمیدم رو.
اول این قانون تو ذهنتون داشته باشید: هر چیزی که باعث ایجاد یک QuerySet جدید بشه، باعث هیت به دیتابیس خواهد شد اگر اون کوئری اجرا بشه.
به مثال زیر دقت کنید:
خب تو این مثال فکر میکنید چندبار دیتابیس توسط جنگو هیت میشه؟ اگه ماجرا کش کردن ندونید ولی ماجرا اینکه چه زمانی واقعا اجرا میشه رو بدونید احتمالا با خودتون میگید ۳ بار داخل این کد جنگو دیتابیس رو هیت میکنه.
اما اگر من بگم فقط دو بار دیتابیس هیت میکنه چی؟
بزارید توضیح بدم. تو خط اول ما صرفا کوئری رو ساختیم و هیچ هیتی به دیتابیس نزدیم. تو خط دوم ما کوئری پرینت کردیم و اینجا اولین هیت به دیتابیس خورده میشه، ولی یک نکته اینجاست وقتی شما یک کوئری رو پرینت میکنید جنگو نمیاد کل کوئری رو اجرا کنه چون منطقی نیست!، مثلا اگر کوئری شما هزارتا خروجی داشته باشه شما اون هزارتا رو که داخل پرینت نمیخایید، در نتیجه جنگو فقط یک بخش از کوئری رو ران میکنه یا به عبارت دیگه از LIMIT استفاده میکنه!. تو این خط هیچ کش کردنی اتفاق نمیوفته(جلوتر میگم چرا)
خط بعدی ما از if استفاده کردیم و اینجا یک هیت دیگه به دیتابیس میخوره اما اینبار کل کوئری اجرا میشه و اینجاست که جنگو ریزالت کوئری میگیره و داخل کش ذخیره میکنه. تو خط بعدی که اومدیم حلقه زدیم روی کوئری جنگو دیگه نمیاد به دیتابیس درخواست بزنه و از کش استفاده میکنه!
در نتیجه اینجا فقط ۲ بار دیتابیس هیت میخوره.
ادامه داخل پیام بعد...
@TorhamDevCH
تو پیام قبلی گفتم که کوئریهای #django دقیقا چه زمانی واقعا اجرا میشن. اما اینجا یک نکته دیگهای هم هست، جنگو نتیجه کوئریهارو کش میکنه.
و این خیلیییییییییییی مهمه، یعنی بعضی از جاها که فکر میکنید جنگو قرار دیتابیس هیت کنه هیت نمیکنه و از کش استفاده میکنه و بعضی جاها که فکر میکنید قرار کش استفاده کنه واقعا هیت میکنه. دونستن و فهمیدن این که چه زمانی کش استفاده میکنه چه زمانی نه حدود ۲ ساعت از من زمان گرفت :) ولی تو این پست توضیح میدم چیزی که فهمیدم رو.
اول این قانون تو ذهنتون داشته باشید: هر چیزی که باعث ایجاد یک QuerySet جدید بشه، باعث هیت به دیتابیس خواهد شد اگر اون کوئری اجرا بشه.
به مثال زیر دقت کنید:
users = User.objects.all()
print(users)
if users:
for u in users:
print(u)
خب تو این مثال فکر میکنید چندبار دیتابیس توسط جنگو هیت میشه؟ اگه ماجرا کش کردن ندونید ولی ماجرا اینکه چه زمانی واقعا اجرا میشه رو بدونید احتمالا با خودتون میگید ۳ بار داخل این کد جنگو دیتابیس رو هیت میکنه.
اما اگر من بگم فقط دو بار دیتابیس هیت میکنه چی؟
بزارید توضیح بدم. تو خط اول ما صرفا کوئری رو ساختیم و هیچ هیتی به دیتابیس نزدیم. تو خط دوم ما کوئری پرینت کردیم و اینجا اولین هیت به دیتابیس خورده میشه، ولی یک نکته اینجاست وقتی شما یک کوئری رو پرینت میکنید جنگو نمیاد کل کوئری رو اجرا کنه چون منطقی نیست!، مثلا اگر کوئری شما هزارتا خروجی داشته باشه شما اون هزارتا رو که داخل پرینت نمیخایید، در نتیجه جنگو فقط یک بخش از کوئری رو ران میکنه یا به عبارت دیگه از LIMIT استفاده میکنه!. تو این خط هیچ کش کردنی اتفاق نمیوفته(جلوتر میگم چرا)
خط بعدی ما از if استفاده کردیم و اینجا یک هیت دیگه به دیتابیس میخوره اما اینبار کل کوئری اجرا میشه و اینجاست که جنگو ریزالت کوئری میگیره و داخل کش ذخیره میکنه. تو خط بعدی که اومدیم حلقه زدیم روی کوئری جنگو دیگه نمیاد به دیتابیس درخواست بزنه و از کش استفاده میکنه!
در نتیجه اینجا فقط ۲ بار دیتابیس هیت میخوره.
ادامه داخل پیام بعد...
@TorhamDevCH
👍9
Forwarded from TorhamDev | تورهام 😳
خب از ماجرا و گفتههای خود داکیومنت جنگو میتونیم نتیجه بگیریم که جنگو زمانی یک ریزالت یک کوئری رو کش میکنه که کوئری کاملا اجرا بشه. یعنی داخل پرینت که بخشیش فقط اجرا شد کش اتفاق نمیوفته ولی داخل if کش اتفاق میوفته.
حالا شاید براتون سوال بشه کش رو چطوری میشه دید؟ میتونید با استفاده از _result_cache ببینیدش، اینطوری:
خروجی این خواهد بود: ( اگر فقط یک یوزر داشته باشیم)
همینطور که میبینید بعد از اجرا کردن پرینت رو کوئری کش هنوز None ( اینجا یکم شاید فهمیدنش سخت بشه با یکدونه یوزر ولی فکر کن هزارتا یوزر داریم پرینت فقط ۱۰ تاشو نشون خواهد داد)
پس بعد پرینت کش اتفاق نیوفتاد. ولی بعد از اینکه if اجرا شد کش پر شد و از اون به بعد جنگو از کش استفاده میکنه. البتهههههههه یک سری نکته هست که برمیگرده به قانونی که تو پست قبل گفتم. برای مثال:
تو این کد اینبار ۳ بار کوئری به دیتابیس میخوره. چرا؟ چون وقتی از .values استفاده میکنید یک QurySet جدید میسازید و اون کوئریست کش جدا خودش رو داره و از اونجایی که کشش خالیه در اون لحظه جنگو یک درخواست دیگه به دیتابیس خواهد زد :)
پایان\
@TorhamDevCH
حالا شاید براتون سوال بشه کش رو چطوری میشه دید؟ میتونید با استفاده از _result_cache ببینیدش، اینطوری:
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: torham>]>
Cache: None
Cache: [<User: torham>]
torham
همینطور که میبینید بعد از اجرا کردن پرینت رو کوئری کش هنوز None ( اینجا یکم شاید فهمیدنش سخت بشه با یکدونه یوزر ولی فکر کن هزارتا یوزر داریم پرینت فقط ۱۰ تاشو نشون خواهد داد)
پس بعد پرینت کش اتفاق نیوفتاد. ولی بعد از اینکه if اجرا شد کش پر شد و از اون به بعد جنگو از کش استفاده میکنه. البتهههههههه یک سری نکته هست که برمیگرده به قانونی که تو پست قبل گفتم. برای مثال:
users = User.objects.all()
print(users)
if users:
for u in users.values("username"):
print(u)
تو این کد اینبار ۳ بار کوئری به دیتابیس میخوره. چرا؟ چون وقتی از .values استفاده میکنید یک QurySet جدید میسازید و اون کوئریست کش جدا خودش رو داره و از اونجایی که کشش خالیه در اون لحظه جنگو یک درخواست دیگه به دیتابیس خواهد زد :)
پایان\
@TorhamDevCH
👍4
Forwarded from 🧑💻PythonDev🧑💻
دیتابیس SQL در مقابل NoSQL: کی چی به کارمون میاد؟
توی دنیای امروز، انتخاب بین SQL و NoSQL میتونه گیچ کننده باشه، مخصوصاً با این همه گزینه دردسترس. از دیتابیس های relational مثل MySQL یا PostgreSQL گرفته تا دیتابیس های مدرن مبتنی بر داکیومنت مثل MongoDB یا ذخیرهسازهای کلید-مقدار مثل DynamoDB، انتخاب بهترین گزینه برای پروژههامون میتونه حسابی سخت باشه.
تو این پست قرار این موضوع رو سادهتر کنیم و بفهمیم کدومشون برای چه کاری بهتره.
دیتابیس ها SQL چی هستن؟
دیتابیس های SQL که بهشون دیتابیس ها رابطهای (relational databases) هم میگن، سالهاست که تو دنیای تکنولوژی حرف اول رو میزنن. این دیتابیس ها ساختارشون جدولی هست و از یه زبون به اسم SQL (زبان پرس و جوی ساختاریافته) برای تعریف و دستکاری دادهها استفاده میکنن. SQL برای کارهایی که به انسجام و دقت داده و کوئری های پیچیده نیاز دارن، عالیه.
یکی از مزایای اصلی دیتابیس ها SQL مثل MySQL و PostgreSQL اینه که با استفاده از relationship ها، میتونن از یکپارچگی دادهها مطمئن بشن. دیتابیس ها SQL با تعریف یه سری قوانین از قبل، یه جوری دادهها رو ذخیره میکنن که همیشه دقیق و منظم باشن.
از SQL کجا ها استفاده کنیم؟
👈 سیستمهای Transactional: برای سیستمهایی که نیاز به انجام تراکنشهای دقیق دارن (مثل سیستمهای بانکی یا فروشگاههای اینترنتی) عالیه. این سیستمها یه جوری باید کار کنن که هیچوقت مشکلی تو ذخیره یا تغییر اطلاعات پیش نیاد.
👈 گزارشگیری و تحلیل
👈 انبار داده: از SQL خیلی وقتها برای ذخیره و تحلیل اطلاعاتی مثل اطلاعات مربوط به فروش یا رفتار مشتریها استفاده میشه.
دیتابیس ها NoSQL
دیتابیس ها NoSQL مثل MongoDB و ElasticSearch برخلاف پایگاههای SQL، رویکردی منعطفتر و بدون اسکما (schema-less) برای دادهها ارائه میدن. این پایگاهها برای مدیریت حجم زیادی از دادههای بدون ساختار یا نیمه ساختار طراحی شدن و برای مواردی که در اونجا مقیاسپذیری، انعطافپذیری و کارایی حرف اول رو میزنن، عالی هستن.
یکی از ویژگیهای قابل توجه اونها قابلیتhorizontal scaling هستش، یعنی میتونن با توزیع دادهها روی چند سرور مختلف، حجم زیادی از داده رو مدیریت کنن. این قابلیت باعث میشه که دیتابیس ها NoSQL برای اپلیکیشنهایی که به سرعت رشد میکنن و نیاز به مدیریت حجم زیادی از داده دارن، انتخاب فوقالعادهای باشن.
علاوه بر این، دیتابیس های NoSQL بسیار انعطافپذیر هستن و به توسعهدهندهها این امکان رو میدن که بدون نیاز به اسکماهای از پیش تعریفشده، دادههای بدون ساختار رو ذخیره و بازیابی کنن. این ویژگی اونها رو برای سناریوهایی که فرمت دادهها ممکنه در طول زمان تغییر کنه، ایدهآل میکنه.
از NoSQL کجا ها استفاده کنیم؟
👈 سیستمهای توزیعشده و مقیاسپذیر.
👈 دادههای حجیم و Real-Time Analytics: دیتابیس های NoSQL در سناریوهایی که شامل دادههای حجیم و تحلیل لحظهای هستن و در اونجا توان عملیاتی بالا و تأخیر کم اهمیت زیادی داره، عالی عمل میکنن.اونها به طور معمول در اپلیکیشنهایی مانند IoT، تحلیل شبکههای اجتماعی و real-time recommendation engines استفاده میشن.
تصورات غلط رایج
با وجود تمام نقاط قوتی که دیتابیس های SQL و NoSQL دارن، در موردشون یه سری تصورات غلط رایج وجود داره.
دیتابیس ها SQL انعطافپذیر نیستن: درسته که دیتابیس ها SQL اسکما یا ساختار ثابتی دارن، اما اونها امکانات قدرتمندی برای تعریف روابط بین جداول و اعمال محدودیتهای یکپارچگی داده ارائه میدن.
دیتابیس ها SQL نمیتونن به صورت horizontal مقیاسپذیر باشن: هر دوی دیتابیس ها SQL و NoSQL میتونن به صورت horizontal مقیاسپذیر باشن، حتی اگه روش های مقیاس پذیریشون متفاوت باشه
دیتابیس ها NoSQL از transactional پشتیبانی نمیکنن: بسیاری از دیتابیس ها NoSQL قابلیتهای تراکنشی رو ارائه میدن، با وجود اینکه با چیزی که تو دیتابیس ها SQL به عنوان ACID شناخته میشه، فرق کنه.
دیتابیس ها NoSQL همیشه از دیتابیس ها SQL سریعتر هستن: عملکرد یه پایگاه داده به عوامل مختلفی بستگی داره، از جمله ماهیت حجم کاری، توزیع داده، الگوهای دسترسی به داده و استراتژیهای ایندکسگذاری. هر دوی دیتابیس ها SQL و NoSQL میتونن بهینه سازی بشن.
نتیجهگیری
در نتیجه، انتخاب راهحل مناسب دیتابیس برای پروژه نیازمند درک دقیق نقاط قوت و ضعف دیتابیس هاس. در حالی که دیتابیس های SQL در یکپارچگی داده قوی و پشتیبانی از کوئری های پیچیده رو ارائه میدن، دیتابیس ها NoSQL مقیاسپذیری و انعطافپذیری رو به ارمغان میارن و هر دو موارد استفاده خاص خودشون رو دارن و میتونن در کنار هم استفاده بشن. در نهایت، انتخاب به ماهیت دادههای شما و نیازهای خاص اپلیکیشن شما بستگی داره.
توی دنیای امروز، انتخاب بین SQL و NoSQL میتونه گیچ کننده باشه، مخصوصاً با این همه گزینه دردسترس. از دیتابیس های relational مثل MySQL یا PostgreSQL گرفته تا دیتابیس های مدرن مبتنی بر داکیومنت مثل MongoDB یا ذخیرهسازهای کلید-مقدار مثل DynamoDB، انتخاب بهترین گزینه برای پروژههامون میتونه حسابی سخت باشه.
تو این پست قرار این موضوع رو سادهتر کنیم و بفهمیم کدومشون برای چه کاری بهتره.
دیتابیس ها SQL چی هستن؟
دیتابیس های SQL که بهشون دیتابیس ها رابطهای (relational databases) هم میگن، سالهاست که تو دنیای تکنولوژی حرف اول رو میزنن. این دیتابیس ها ساختارشون جدولی هست و از یه زبون به اسم SQL (زبان پرس و جوی ساختاریافته) برای تعریف و دستکاری دادهها استفاده میکنن. SQL برای کارهایی که به انسجام و دقت داده و کوئری های پیچیده نیاز دارن، عالیه.
یکی از مزایای اصلی دیتابیس ها SQL مثل MySQL و PostgreSQL اینه که با استفاده از relationship ها، میتونن از یکپارچگی دادهها مطمئن بشن. دیتابیس ها SQL با تعریف یه سری قوانین از قبل، یه جوری دادهها رو ذخیره میکنن که همیشه دقیق و منظم باشن.
از SQL کجا ها استفاده کنیم؟
👈 سیستمهای Transactional: برای سیستمهایی که نیاز به انجام تراکنشهای دقیق دارن (مثل سیستمهای بانکی یا فروشگاههای اینترنتی) عالیه. این سیستمها یه جوری باید کار کنن که هیچوقت مشکلی تو ذخیره یا تغییر اطلاعات پیش نیاد.
👈 گزارشگیری و تحلیل
👈 انبار داده: از SQL خیلی وقتها برای ذخیره و تحلیل اطلاعاتی مثل اطلاعات مربوط به فروش یا رفتار مشتریها استفاده میشه.
دیتابیس ها NoSQL
دیتابیس ها NoSQL مثل MongoDB و ElasticSearch برخلاف پایگاههای SQL، رویکردی منعطفتر و بدون اسکما (schema-less) برای دادهها ارائه میدن. این پایگاهها برای مدیریت حجم زیادی از دادههای بدون ساختار یا نیمه ساختار طراحی شدن و برای مواردی که در اونجا مقیاسپذیری، انعطافپذیری و کارایی حرف اول رو میزنن، عالی هستن.
یکی از ویژگیهای قابل توجه اونها قابلیتhorizontal scaling هستش، یعنی میتونن با توزیع دادهها روی چند سرور مختلف، حجم زیادی از داده رو مدیریت کنن. این قابلیت باعث میشه که دیتابیس ها NoSQL برای اپلیکیشنهایی که به سرعت رشد میکنن و نیاز به مدیریت حجم زیادی از داده دارن، انتخاب فوقالعادهای باشن.
علاوه بر این، دیتابیس های NoSQL بسیار انعطافپذیر هستن و به توسعهدهندهها این امکان رو میدن که بدون نیاز به اسکماهای از پیش تعریفشده، دادههای بدون ساختار رو ذخیره و بازیابی کنن. این ویژگی اونها رو برای سناریوهایی که فرمت دادهها ممکنه در طول زمان تغییر کنه، ایدهآل میکنه.
از NoSQL کجا ها استفاده کنیم؟
👈 سیستمهای توزیعشده و مقیاسپذیر.
👈 دادههای حجیم و Real-Time Analytics: دیتابیس های NoSQL در سناریوهایی که شامل دادههای حجیم و تحلیل لحظهای هستن و در اونجا توان عملیاتی بالا و تأخیر کم اهمیت زیادی داره، عالی عمل میکنن.اونها به طور معمول در اپلیکیشنهایی مانند IoT، تحلیل شبکههای اجتماعی و real-time recommendation engines استفاده میشن.
تصورات غلط رایج
با وجود تمام نقاط قوتی که دیتابیس های SQL و NoSQL دارن، در موردشون یه سری تصورات غلط رایج وجود داره.
دیتابیس ها SQL انعطافپذیر نیستن: درسته که دیتابیس ها SQL اسکما یا ساختار ثابتی دارن، اما اونها امکانات قدرتمندی برای تعریف روابط بین جداول و اعمال محدودیتهای یکپارچگی داده ارائه میدن.
دیتابیس ها SQL نمیتونن به صورت horizontal مقیاسپذیر باشن: هر دوی دیتابیس ها SQL و NoSQL میتونن به صورت horizontal مقیاسپذیر باشن، حتی اگه روش های مقیاس پذیریشون متفاوت باشه
دیتابیس ها NoSQL از transactional پشتیبانی نمیکنن: بسیاری از دیتابیس ها NoSQL قابلیتهای تراکنشی رو ارائه میدن، با وجود اینکه با چیزی که تو دیتابیس ها SQL به عنوان ACID شناخته میشه، فرق کنه.
دیتابیس ها NoSQL همیشه از دیتابیس ها SQL سریعتر هستن: عملکرد یه پایگاه داده به عوامل مختلفی بستگی داره، از جمله ماهیت حجم کاری، توزیع داده، الگوهای دسترسی به داده و استراتژیهای ایندکسگذاری. هر دوی دیتابیس ها SQL و NoSQL میتونن بهینه سازی بشن.
نتیجهگیری
در نتیجه، انتخاب راهحل مناسب دیتابیس برای پروژه نیازمند درک دقیق نقاط قوت و ضعف دیتابیس هاس. در حالی که دیتابیس های SQL در یکپارچگی داده قوی و پشتیبانی از کوئری های پیچیده رو ارائه میدن، دیتابیس ها NoSQL مقیاسپذیری و انعطافپذیری رو به ارمغان میارن و هر دو موارد استفاده خاص خودشون رو دارن و میتونن در کنار هم استفاده بشن. در نهایت، انتخاب به ماهیت دادههای شما و نیازهای خاص اپلیکیشن شما بستگی داره.
👍4
Forwarded from DevOps (babak dorani)
جونیور و میدلول ها :
رفقا اگر به هر زبانی برنامه مینویسین
و در سطح جونیور و میدلول هستین
دوره جنگو رو ببینین
راستش این دوره اصلا جنگو نیست
پارت اول :
اماده سازی سرور و کلود فلر و ابزارها مثل نکسوز داکر کامپوز و ........
پارت دوم یه اپ ساده با جنگو ( شما همینو با زبان یا فریمورک خودت بنویس مثلا
نست جی اس
لاراول
جین
و.........
پارت سوم سی ای سی دی
و دپلویمنت
اصلا سطحتون یه جور عجیبی تغییر میکنه
دیدگاهتون خیلی پیشرفته تر میشه
https://youtube.com/playlist?list=PLYrn63eEqAzY5uG5ks_OquWcojzHvhp9Z&si=aYZXHwT2GHn2da5p
رفقا اگر به هر زبانی برنامه مینویسین
و در سطح جونیور و میدلول هستین
دوره جنگو رو ببینین
راستش این دوره اصلا جنگو نیست
پارت اول :
اماده سازی سرور و کلود فلر و ابزارها مثل نکسوز داکر کامپوز و ........
پارت دوم یه اپ ساده با جنگو ( شما همینو با زبان یا فریمورک خودت بنویس مثلا
نست جی اس
لاراول
جین
و.........
پارت سوم سی ای سی دی
و دپلویمنت
اصلا سطحتون یه جور عجیبی تغییر میکنه
دیدگاهتون خیلی پیشرفته تر میشه
https://youtube.com/playlist?list=PLYrn63eEqAzY5uG5ks_OquWcojzHvhp9Z&si=aYZXHwT2GHn2da5p
👍16👎1
Forwarded from TorhamDev | تورهام 😳
یک مبحثی که خیلی وقتها آدمهای رو داخل #جنگو گیج میکنه موضوع Aggregation هستش. برای مثال کوئری پایین:
خب این کوئری مشخصه چه کاری داره انجام میده، همه میتونن بفهمنش مخصوصا وقتی خروجی کوئری رو میبینن، اما اگر ازشون بپرسید خب Aggregation چی هستش هیچ ایده ای ندارن! و این ماجرا از ضعف در دانش SQL سر چشمه میگیره. چون خیلی از آدمهایی که دارن #django کار میکنن مستقیم سراغ جنگو اومدن و نرفتن چیزهای دیگه رو مطالعه کنن و یاد بگیرن.
اسم Aggregation داخل ORM جنگو مستقیما از SQL میاد. در SQL یک سری فانکشن وجود داره که بهشون Aggregation functions میگن و کارشون خلاصه سازی اطلاعات:
MIN() - returns the smallest value within the selected column
MAX() - returns the largest value within the selected column
COUNT() - returns the number of rows in a set
SUM() - returns the total sum of a numerical column
AVG() - returns the average value of a numerical column
و خب شما میتونید داخل کوئریهای SQL ازشون استفاده کنید و دیتا خروجی رو خلاصه سازی کنید و یا یک آمار ازش دربیارید. مثلا میانگین قیمت کتابهای تو سال اخیر و ...
یک کوئری مثال برای Aggregation میتونه این باشه:
خب از اونجایی که ORM جنگو در نهایت قرار کار همین SQL نوشتن برای شما انجام بده و کوئری شمارو به SQL تبدیل کنه شما دقیقا همین کوئری میتونید داخل جنگو به این صورت بنویسید:
میتونید لیست فانکشنهای Aggregation خود SQL داخل این لینک ببینید و ساپورت جنگو هم میتونید داخل این لینک ببینید.
در نهایت از دانش SQL غافل نباشید و حتما یادش بیگیرید. هرچی بیشتر SQL بدونید زندگی راحتتری خواهید داشت.
@TorhamDevCH
>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Avg("price"), Max("price"), Min("price"))
# {'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
خب این کوئری مشخصه چه کاری داره انجام میده، همه میتونن بفهمنش مخصوصا وقتی خروجی کوئری رو میبینن، اما اگر ازشون بپرسید خب Aggregation چی هستش هیچ ایده ای ندارن! و این ماجرا از ضعف در دانش SQL سر چشمه میگیره. چون خیلی از آدمهایی که دارن #django کار میکنن مستقیم سراغ جنگو اومدن و نرفتن چیزهای دیگه رو مطالعه کنن و یاد بگیرن.
اسم Aggregation داخل ORM جنگو مستقیما از SQL میاد. در SQL یک سری فانکشن وجود داره که بهشون Aggregation functions میگن و کارشون خلاصه سازی اطلاعات:
MIN() - returns the smallest value within the selected column
MAX() - returns the largest value within the selected column
COUNT() - returns the number of rows in a set
SUM() - returns the total sum of a numerical column
AVG() - returns the average value of a numerical column
و خب شما میتونید داخل کوئریهای SQL ازشون استفاده کنید و دیتا خروجی رو خلاصه سازی کنید و یا یک آمار ازش دربیارید. مثلا میانگین قیمت کتابهای تو سال اخیر و ...
یک کوئری مثال برای Aggregation میتونه این باشه:
SELECT AVG(Price) as price_avg FROM Books WHERE puddate='2023-01-01';
خب از اونجایی که ORM جنگو در نهایت قرار کار همین SQL نوشتن برای شما انجام بده و کوئری شمارو به SQL تبدیل کنه شما دقیقا همین کوئری میتونید داخل جنگو به این صورت بنویسید:
>>> from django.db.models import Avg
>>> from datetime import datetime
>>> Books.objects.filter(pubdate=datetime(2023, 1, 1)).aggregate(price_avg=Avg("price"))
میتونید لیست فانکشنهای Aggregation خود SQL داخل این لینک ببینید و ساپورت جنگو هم میتونید داخل این لینک ببینید.
در نهایت از دانش SQL غافل نباشید و حتما یادش بیگیرید. هرچی بیشتر SQL بدونید زندگی راحتتری خواهید داشت.
@TorhamDevCH
W3Schools
W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.
❤4👍3
Forwarded from نوشتههای ترمینالی
شاید شما هم مثل من پوشهی تنظیمات editorتون رو به gitignore همهی پروژههاتون اضافه میکنید، اما اگر پروژه، پروژهی ما نیست چی؟ به تمام پروژههایی که contributor شون هستیم چی؟ یا مثلا فایل .DS_Store مک رو در نظر بگیرید، چون یک نفر مک داره باید این به gitignore پروژه اضافه بشه؟
راه حل بهترش استفاده از global gitignoreئه، یه فایل گیت ایگنور که برای سیستم شما روی همه چی اعمال میشه نه فقط یه ریپوزیتوری.
در موردش اینجا بخونید:
https://sebastiandedeyne.com/setting-up-a-global-gitignore-file/
راه حل بهترش استفاده از global gitignoreئه، یه فایل گیت ایگنور که برای سیستم شما روی همه چی اعمال میشه نه فقط یه ریپوزیتوری.
در موردش اینجا بخونید:
https://sebastiandedeyne.com/setting-up-a-global-gitignore-file/
Sebastiandedeyne
Setting up a global .gitignore file
Reviewing pull requests, I often see contributors sneakily adding editor configuration to the repository's .gitignore file.
composer.lock package.lock+ .vscode
If everyone would commit their environment-specific .gitignore rules, we'd have a long list…
composer.lock package.lock+ .vscode
If everyone would commit their environment-specific .gitignore rules, we'd have a long list…
👍6
✅ارسال ایمیل در جنگو
لینک زیر رو ببینید:
https://docs.djangoproject.com/en/5.0/topics/email/#module-django.core.mail
✔️دو تا متد برای ارسال ایمیل معرفی کرده یکی send_mail و دیگری send_mass_mail که دومی برای ارسال چندتا ایمیل به صورت یکجا هست.
✔️هر دوشون یه پارامتر دارن به اسم fail_silently که مقدار bool میگیره. و اگه True باشه هنگام ارسال email اگه خطایی رخ بده Exception ش raise میشه.
✔️ یه متد جالب هم داره به اسم mail_admins که برای ارسال ایمیل به ادمین هاس 😂
✔️برای اینکه توی ایمیلی که میخواهیم بفرستیم از تگ های HTML استفاده کنیم از EmailMultiAlternatives می تونیم استفاده کنیم.
✔️ و نهایتا اگه بخواهیم تستی ایمیل ارسال کنیم طوری که نتیجه ایمیل رو ببینیم ولی نیاز به سرور ایمیل (مثلا جیمیل) نداشته باشیم میتونیم مقدار EMAIL_BACKEND رو برابر django.core.mail.backends.console.EmailBackend بزاریم.
نکات بیشتری توی لینک هست که توصیه میکنم خودتون مطالعه اش کنید
لینک زیر رو ببینید:
https://docs.djangoproject.com/en/5.0/topics/email/#module-django.core.mail
✔️دو تا متد برای ارسال ایمیل معرفی کرده یکی send_mail و دیگری send_mass_mail که دومی برای ارسال چندتا ایمیل به صورت یکجا هست.
✔️هر دوشون یه پارامتر دارن به اسم fail_silently که مقدار bool میگیره. و اگه True باشه هنگام ارسال email اگه خطایی رخ بده Exception ش raise میشه.
✔️ یه متد جالب هم داره به اسم mail_admins که برای ارسال ایمیل به ادمین هاس 😂
✔️برای اینکه توی ایمیلی که میخواهیم بفرستیم از تگ های HTML استفاده کنیم از EmailMultiAlternatives می تونیم استفاده کنیم.
✔️ و نهایتا اگه بخواهیم تستی ایمیل ارسال کنیم طوری که نتیجه ایمیل رو ببینیم ولی نیاز به سرور ایمیل (مثلا جیمیل) نداشته باشیم میتونیم مقدار EMAIL_BACKEND رو برابر django.core.mail.backends.console.EmailBackend بزاریم.
نکات بیشتری توی لینک هست که توصیه میکنم خودتون مطالعه اش کنید
Django Project
Sending email | Django documentation
The web framework for perfectionists with deadlines.
👍6
Forwarded from TorhamDev | تورهام 😳
کوئری raw زدن در #جنگو
درسته #django یک ORM خوب داره و تقریبا تمام چیزهایی که لازم دارید رو ساپورت میکنه اما شما میتونید داخل جنگو مستقیم کوئری SQL ران کنید!
ران کردن این کوئریها به صورت raw میتونه تو دو لایه در جنگو انجام بشه. یک در لایه مدل خودتون و دومی تو لایه پایین تر مستقیم با کانکشن دیتابیس.
تو حال اول جنگو سعی میکنه که خروجی SQL را براتون Map کنه و خروجی دوباره مدل براتون برگردونه حتی وقتی دارید raw میزنید مثال:
مدل فرضی:
کوئری مثال:
این کوئری دقیقا معادل objects.all() و جنگو خروجی رو بر اساس اسم فیلدها مپ میکنه به مدل. این مهمه ها! بر اساس اسم فیلد! یعنی شما میتونید کوئری رو حتی رو یک تیبل دیگه بزنید و تا زمانی که اسم فیلدا خروجیتون با مدل یکی باشه جنگو اونهارو مپ میکنه. مثال:
بله میتونیم از AS استفاده کنیم و اسم فیلدا مشابه مدلمون بزاریم. خود جنگو هم یک فیچر داره که براتون همین AS رو میزنه!
میتونید از پارامتر translations استفاده کنید برای اینکار.
میتونید برخی از فیلدها رو انتخاب نکنید!
برای مثال:
برای مثال داخل این raw کوئری ما فیلد last_name رو انتخاب نکردیم. حالا چه اتفاقی افتاده؟ همچنان اگه شما فیلد last_name صدا بزنید مشکلی پیش نمیاد و دریافتش میکنید ولیییییی جنگو از اونجایی که اون فیلد داخل کوئری وارد نکرده بودید و خروجیش رو نداشته خودش میاد همون لحضه دوباره یک درخواست به دیتابیس میزنه و اون دریافت میکنه!
لایه خود کانکشن
اگه این مپینگ رو نمیخایید و کلا میخوایید یک کوئری مستقیم بزنید مثل زمانی که از یک کتابخونه معمولی تو پایتون برای دیتابیس استفاده میکنید میتونید از connection در جنگو استفاده کنید! مثال:
خروجی یک لیست از نتایج خواهد بود. البته میتونید با یک حرکت ساده این لیست مپ کنید خودتون و در نهایت یک دیکشنری داشته باشید.
و آخرین نکته اینکه وقتی دارید از raw استفاده میکنید دیگه اسلایس کردن رو لول کوئری لیمیت نمیزاره و بهتره از LIMIT استفاده کنید داخل خود کوئری SQL
@TorhamDevCH
درسته #django یک ORM خوب داره و تقریبا تمام چیزهایی که لازم دارید رو ساپورت میکنه اما شما میتونید داخل جنگو مستقیم کوئری SQL ران کنید!
ران کردن این کوئریها به صورت raw میتونه تو دو لایه در جنگو انجام بشه. یک در لایه مدل خودتون و دومی تو لایه پایین تر مستقیم با کانکشن دیتابیس.
تو حال اول جنگو سعی میکنه که خروجی SQL را براتون Map کنه و خروجی دوباره مدل براتون برگردونه حتی وقتی دارید raw میزنید مثال:
مدل فرضی:
class Person(models.Model):
first_name = models.CharField(...)
last_name = models.CharField(...)
birth_date = models.DateField(...)
کوئری مثال:
Person.objects.raw("SELECT * FROM myapp_person")
این کوئری دقیقا معادل objects.all() و جنگو خروجی رو بر اساس اسم فیلدها مپ میکنه به مدل. این مهمه ها! بر اساس اسم فیلد! یعنی شما میتونید کوئری رو حتی رو یک تیبل دیگه بزنید و تا زمانی که اسم فیلدا خروجیتون با مدل یکی باشه جنگو اونهارو مپ میکنه. مثال:
>>> Person.objects.raw(
... """
... SELECT first AS first_name,
... last AS last_name,
... bd AS birth_date,
... pk AS id,
... FROM some_other_table
... """
... )
بله میتونیم از AS استفاده کنیم و اسم فیلدا مشابه مدلمون بزاریم. خود جنگو هم یک فیچر داره که براتون همین AS رو میزنه!
>>> name_map = {"first": "first_name", "last": "last_name", "bd": "birth_date", "pk": "id"}
>>> Person.objects.raw("SELECT * FROM some_other_table", translations=name_map)
میتونید از پارامتر translations استفاده کنید برای اینکار.
میتونید برخی از فیلدها رو انتخاب نکنید!
برای مثال:
>>> for p in Person.objects.raw("SELECT id, first_name FROM myapp_person"):
... print(
... p.first_name, # This will be retrieved by the original query
... p.last_name, # This will be retrieved on demand
... )
...
برای مثال داخل این raw کوئری ما فیلد last_name رو انتخاب نکردیم. حالا چه اتفاقی افتاده؟ همچنان اگه شما فیلد last_name صدا بزنید مشکلی پیش نمیاد و دریافتش میکنید ولیییییی جنگو از اونجایی که اون فیلد داخل کوئری وارد نکرده بودید و خروجیش رو نداشته خودش میاد همون لحضه دوباره یک درخواست به دیتابیس میزنه و اون دریافت میکنه!
لایه خود کانکشن
اگه این مپینگ رو نمیخایید و کلا میخوایید یک کوئری مستقیم بزنید مثل زمانی که از یک کتابخونه معمولی تو پایتون برای دیتابیس استفاده میکنید میتونید از connection در جنگو استفاده کنید! مثال:
from django.db import connection
def my_custom_sql(self):
with connection.cursor() as cursor:
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
return row
خروجی یک لیست از نتایج خواهد بود. البته میتونید با یک حرکت ساده این لیست مپ کنید خودتون و در نهایت یک دیکشنری داشته باشید.
def dictfetchall(cursor):
"""
Return all rows from a cursor as a dict.
Assume the column names are unique.
"""
columns = [col[0] for col in cursor.description]
return [dict(zip(columns, row)) for row in cursor.fetchall()]
و آخرین نکته اینکه وقتی دارید از raw استفاده میکنید دیگه اسلایس کردن رو لول کوئری لیمیت نمیزاره و بهتره از LIMIT استفاده کنید داخل خود کوئری SQL
@TorhamDevCH
👍5
✅نسخه قبلی دوره ساخت فروشگاه اینترنتی با جنگو رایگان شد.
سرفصل های دوره قبل:
✔️ ساخت پروژه فروشگاه
✔️پیاده سازی قالب
✔️ ساخت مدل ها و ایجاد ارتباط منطقی بین جداول پایگاه داده
✔️ آشنایی با PostgreSQL
✔️ آماده سازی سبد خرید با Django Session –
✔️ ساخت Context Processor اختصاصی
✔️ ثبت سفارش مشتری و ارائه شماره سفارش
✔️ راه اندازی درگاه پرداخت اینترنتی
✔️ کانفیگ پکیج django-allauth
✔️ عضویت با django-allauth و Authentication
✔️ گانفیک email جهت ارسال تاییدیه عضویت به کاربر
✔️ ساخت API در Google Developer Console
✔️ ثبت نام در سایت با Google Account
ان شالله به مرور ویدئوهای دوره قبلی رو توی آپارات - یوتیوب و تلگرام به صورت کامل آپلود میکنم.
و لینک نسخه جدید آموزش ساخت فروشگاه اینترنتی با جنگو با 64 درصد تخفیف:
https://www.daneshjooyar.com/project-django/
سرفصل های دوره قبل:
✔️ ساخت پروژه فروشگاه
✔️پیاده سازی قالب
✔️ ساخت مدل ها و ایجاد ارتباط منطقی بین جداول پایگاه داده
✔️ آشنایی با PostgreSQL
✔️ آماده سازی سبد خرید با Django Session –
✔️ ساخت Context Processor اختصاصی
✔️ ثبت سفارش مشتری و ارائه شماره سفارش
✔️ راه اندازی درگاه پرداخت اینترنتی
✔️ کانفیگ پکیج django-allauth
✔️ عضویت با django-allauth و Authentication
✔️ گانفیک email جهت ارسال تاییدیه عضویت به کاربر
✔️ ساخت API در Google Developer Console
✔️ ثبت نام در سایت با Google Account
ان شالله به مرور ویدئوهای دوره قبلی رو توی آپارات - یوتیوب و تلگرام به صورت کامل آپلود میکنم.
و لینک نسخه جدید آموزش ساخت فروشگاه اینترنتی با جنگو با 64 درصد تخفیف:
https://www.daneshjooyar.com/project-django/
❤7👍4🔥4👎2
Forwarded from TorhamDev | تورهام 😳
Transaction per-request in #django
#جنگو قابلیت انجام ترنزکشن با دیتابیس به شما میده در چندید حالت مختلف یکی از حالتها ترنزاکشن بر هر ریکوئستِ، یعنی چی؟ یعنی جنگو برای هر ریکوئستی که شما میگیرید یک ترنزاکشن باز میکنه یا به عباری برای هر ویو فانکشن شما یک atomic() ران میکنه! این قابلیت به شکل پیشفرض غیر فعاله ولی میتونید با اضافه ATOMIC_REQUESTS داخل کانفیگ دیتابیسی که میخوایید این حرکت باهاش بزنید این قابلیت فعال کنید.
این کار هر ریکوئست شمارو داخل یک ترنزاکشن warp میکنه و اگر ویو شما هر اروری بده ( ارور raise کنه ) ترنزاکشن rollback میخوره و تغییرات اعمال نمیشه.
@TorhamDevCH
#جنگو قابلیت انجام ترنزکشن با دیتابیس به شما میده در چندید حالت مختلف یکی از حالتها ترنزاکشن بر هر ریکوئستِ، یعنی چی؟ یعنی جنگو برای هر ریکوئستی که شما میگیرید یک ترنزاکشن باز میکنه یا به عباری برای هر ویو فانکشن شما یک atomic() ران میکنه! این قابلیت به شکل پیشفرض غیر فعاله ولی میتونید با اضافه ATOMIC_REQUESTS داخل کانفیگ دیتابیسی که میخوایید این حرکت باهاش بزنید این قابلیت فعال کنید.
این کار هر ریکوئست شمارو داخل یک ترنزاکشن warp میکنه و اگر ویو شما هر اروری بده ( ارور raise کنه ) ترنزاکشن rollback میخوره و تغییرات اعمال نمیشه.
@TorhamDevCH
Django Project
Settings | Django documentation
The web framework for perfectionists with deadlines.
👍3
📣تبلیغ رایگان
قالب فروشگاهی HTML بلسر , Blesser
با طراحی مدرن و جذاب است که با استفاده از فریمورک UnoCss توسعه داده شده است.
مشاهده پیش نمایش
لینک خرید قالب:
https://www.rtl-theme.com/blesser-html-template/
قالب فروشگاهی HTML بلسر , Blesser
با طراحی مدرن و جذاب است که با استفاده از فریمورک UnoCss توسعه داده شده است.
مشاهده پیش نمایش
لینک خرید قالب:
https://www.rtl-theme.com/blesser-html-template/
🤮4❤2👍1
وبینار بررسی بازار فعالیت برای توسعه دهنده بک اند پایتون
در این وبینار قرار است از تجربیات مهندس فرزین شمس (Farzin Shams) در زمینه توسعه دهنده پایتون و همچنین مراتب مختلف در گرفتن پروژه،ارائه و تجربیات ایشون در این زمینه بپردازیم.
از جمله مواردی که بررسی خواهد شد:
- پیش نیازها و مواردی که به عنوان یک نیرویی که میخواد تازی به این حوزه وارد بشه
- اشتباهات فردی خودم زمان شروع به کار
- به چالش کشیدن خود
- اهمیت انگیزه داشتن جهت یادگیری پی در پی
- آیا دورهها به تنهایی برای بازار کار کافیست؟
- جلوگیری از پراکندگی در یادگیری
- نقشه راه در صورت نیاز
- مباحث مهم جهت یادگیری به عنوان یک بک اند دولوپر
- پرزنت درست برای دریافت پروژه
- آیا ارزون کار کردن درسته در شروع
- پلتفرم های دریافت پروژه
زمان برگزاری :
پنجشنبه ۲۴ خرداد - ساعت 18:00
ظرفیت: 100نفر
هزینه: رایگان
لینک ثبت نام:
https://thealibigdeli.ir/event/
در این وبینار قرار است از تجربیات مهندس فرزین شمس (Farzin Shams) در زمینه توسعه دهنده پایتون و همچنین مراتب مختلف در گرفتن پروژه،ارائه و تجربیات ایشون در این زمینه بپردازیم.
از جمله مواردی که بررسی خواهد شد:
- پیش نیازها و مواردی که به عنوان یک نیرویی که میخواد تازی به این حوزه وارد بشه
- اشتباهات فردی خودم زمان شروع به کار
- به چالش کشیدن خود
- اهمیت انگیزه داشتن جهت یادگیری پی در پی
- آیا دورهها به تنهایی برای بازار کار کافیست؟
- جلوگیری از پراکندگی در یادگیری
- نقشه راه در صورت نیاز
- مباحث مهم جهت یادگیری به عنوان یک بک اند دولوپر
- پرزنت درست برای دریافت پروژه
- آیا ارزون کار کردن درسته در شروع
- پلتفرم های دریافت پروژه
زمان برگزاری :
پنجشنبه ۲۴ خرداد - ساعت 18:00
ظرفیت: 100نفر
هزینه: رایگان
لینک ثبت نام:
https://thealibigdeli.ir/event/
👍8
درخواست همکاری پارت تایم
دات نت/پایتون
سلام به همه
من از سال 2008 شروع به یادگیری سی شارپ کردم
با ویندوز فرم شروع کردم
هیچوقت نتونستم با وب فرم و ام وی سی مایکروسافت ارتباط برقرار کنم
توی گاج و سان و چارگون با دات نت بیشتر آشنا شدم
از سال 2018 به صورت خودآموز شروع به یادگیری پایتون کردم
و بعد از اینکه یکم پایتون یاد گرفتم سراغ جنگو رفتم
یه مقطعی انگولار هم مجبور شدم کد بزنم.
توی یه پروژه هم ری اکت رو زیارت کردم.
دیگه بقیه کارهای ناشایستی که باعث شده اقیانوسی به عمق ده سانتی متر بشم رو نمیگم که حداقل یه درخواست همکاری برام بیاد.
با توضیحات فوق، خوشحال میشم اگه موقعیت شغلی پارت تایمی می شناسید به من معرفی کنید. آیدی من @miladhzz
سال هارو میلادی نوشتم چون اسمم میلاده 😁 😕
دات نت/پایتون
سلام به همه
من از سال 2008 شروع به یادگیری سی شارپ کردم
با ویندوز فرم شروع کردم
هیچوقت نتونستم با وب فرم و ام وی سی مایکروسافت ارتباط برقرار کنم
توی گاج و سان و چارگون با دات نت بیشتر آشنا شدم
از سال 2018 به صورت خودآموز شروع به یادگیری پایتون کردم
و بعد از اینکه یکم پایتون یاد گرفتم سراغ جنگو رفتم
یه مقطعی انگولار هم مجبور شدم کد بزنم.
توی یه پروژه هم ری اکت رو زیارت کردم.
دیگه بقیه کارهای ناشایستی که باعث شده اقیانوسی به عمق ده سانتی متر بشم رو نمیگم که حداقل یه درخواست همکاری برام بیاد.
با توضیحات فوق، خوشحال میشم اگه موقعیت شغلی پارت تایمی می شناسید به من معرفی کنید. آیدی من @miladhzz
سال هارو میلادی نوشتم چون اسمم میلاده 😁 😕
🔥11👍6❤4😁4👎1
جنگولرن
db_ali.pdf
orm_ali.pdf
691.6 KB
✅پیاده سازی انواع Relation ها با استفاده از Django ORM
از لینکدین علی بیگدلی
تو پست قبلی با توضیحات کلی مدل های ارتباطی آشنا شدیم و در این پست می خوایم این ارتباطات رو در قالب کلاس های مدل تشریح کنیم. باید در نظر داشته باشید که سناریو ها برای پیاده سازی در هر پروژه ممکنه متفاوت باشن و منتهی مراتب از لحاظ عملکرد یکی هستن. نکته ای که اهمیت داره دیدگاه و جوانب اون هستش که چطور به یک مسئله نگاه میشه در طراحی، گاهی اوقات مدل های طراحی تقریبا یکی به نظر میان ولی اسم گذاری هاشون فرق دارن و برای همین که منطق متفاوتی رو علاوه بر تشابه میرسونن.
در کل باید سعی کنیم تا بیشتری میزان اطلاعات رو توی بخش طراحی کسب کنیم تا در پروژه های بزرگتر قدرت تصمیم گیری بیشتری پیدا کنیم.
از جمله مواردی که به نظر من می تونه خیلی بهتون درک عمیق بده و شاید خیلی درگیرش نباشید Generic Relation و استفاده از Through هستش که خودم در زمانی که باهاشون آشنا نبودم دنبال راه حل های مشابهی میگشم که در نهایت همین ساختار رو پیاده سازی می کردم ولی اصلا نمی دونستم جنگو خودش داره، پس سعی کنین بیشترین میزان دید رو پیدا کنین تا دچار این مشکل نشید.
از لینکدین علی بیگدلی
تو پست قبلی با توضیحات کلی مدل های ارتباطی آشنا شدیم و در این پست می خوایم این ارتباطات رو در قالب کلاس های مدل تشریح کنیم. باید در نظر داشته باشید که سناریو ها برای پیاده سازی در هر پروژه ممکنه متفاوت باشن و منتهی مراتب از لحاظ عملکرد یکی هستن. نکته ای که اهمیت داره دیدگاه و جوانب اون هستش که چطور به یک مسئله نگاه میشه در طراحی، گاهی اوقات مدل های طراحی تقریبا یکی به نظر میان ولی اسم گذاری هاشون فرق دارن و برای همین که منطق متفاوتی رو علاوه بر تشابه میرسونن.
در کل باید سعی کنیم تا بیشتری میزان اطلاعات رو توی بخش طراحی کسب کنیم تا در پروژه های بزرگتر قدرت تصمیم گیری بیشتری پیدا کنیم.
از جمله مواردی که به نظر من می تونه خیلی بهتون درک عمیق بده و شاید خیلی درگیرش نباشید Generic Relation و استفاده از Through هستش که خودم در زمانی که باهاشون آشنا نبودم دنبال راه حل های مشابهی میگشم که در نهایت همین ساختار رو پیاده سازی می کردم ولی اصلا نمی دونستم جنگو خودش داره، پس سعی کنین بیشترین میزان دید رو پیدا کنین تا دچار این مشکل نشید.
👍5❤1
جنگولرن
✅نسخه قبلی دوره ساخت فروشگاه اینترنتی با جنگو رایگان شد. سرفصل های دوره قبل: ✔️ ساخت پروژه فروشگاه ✔️پیاده سازی قالب ✔️ ساخت مدل ها و ایجاد ارتباط منطقی بین جداول پایگاه داده ✔️ آشنایی با PostgreSQL ✔️ آماده سازی سبد خرید با Django Session – ✔️ ساخت Context…
✅دوره مقدماتی آموزش جنگو رایگان شد.
✔️نصب جنگو
✔️ساخت اولین پروژه django
✔️طراحی مدل ها
✔️آماده سازی پنل ادمین django
✔️آشنایی با Query Set و Shell
✔️ساخت List view و Detail view
✔️ایجاد Template متناسب با View ها
✔️اضافه کردن صفحه بندی (Pagination)
✔️طراحی مدل های ثبت نظرات وبلاگ
✔️ثبت نظر با استفاده از Form ها
✔️افزودن تگ به مطالب با استفاده از پکیج Taggit
✔️ساخت Custom Template Tag ها
ان شالله به مرور ویدئوهاش رو توی آپارات - یوتیوب و تلگرام به صورت کامل آپلود میکنم.
✔️نصب جنگو
✔️ساخت اولین پروژه django
✔️طراحی مدل ها
✔️آماده سازی پنل ادمین django
✔️آشنایی با Query Set و Shell
✔️ساخت List view و Detail view
✔️ایجاد Template متناسب با View ها
✔️اضافه کردن صفحه بندی (Pagination)
✔️طراحی مدل های ثبت نظرات وبلاگ
✔️ثبت نظر با استفاده از Form ها
✔️افزودن تگ به مطالب با استفاده از پکیج Taggit
✔️ساخت Custom Template Tag ها
ان شالله به مرور ویدئوهاش رو توی آپارات - یوتیوب و تلگرام به صورت کامل آپلود میکنم.
👍12❤3
Forwarded from محمد لرنینگ (آموزش برنامه نویسی)
.
لینک ویدیوی جلسه ۱۷:
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://www.tgoop.com/QaDeveloper
✅ @SEYED_BAX | @MakeDeveloper
لینک ویدیوی جلسه ۱۷:
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://www.tgoop.com/QaDeveloper
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Forwarded from TorhamDev | تورهام 😳
Transaction in #django
اگه نمیدونید به طور کلی ترنزاکشن چیه میتونید به این لینک سر بزنید. ولی خیلی خلاصه بخوام بگم به انجام چندتا کوئری مختلف ولی در یک unit ترنزاکشن میگن، یعنی شما ۳ تا کوئری انجام میدی، اگه حتی یکدونه از اون ۳ تا ارور بخوره بقیه ۲ تا هم هر تغییری داده باشن اون برمیگردونن یا به اصطلاح Rollback میکنه.
حالا #جنگو این قابلیت به شما میده که از این فیچر دیتابیسها داخل کدتون استفاده کنید برای این کار میتونید از transaction.atomic استفاده کنید، این فانکشن هم قابلیت استفاده به عنوان دکوریتور رو داره هم کانتکس منیجر
به عنوان دکوریتور:
یا به عنوان کانتکس منیجر:
تو هر دو کد اگر اتفاقی داخل یکی از فانکشن ها بیوفته یعنی اگر ارور raise بشه کوئریها و تغییراتی که رو دیتابیس اعمال شده همه rollback میشه و برمیگرده، شما میتونید چندتا ترنزاکشن به صورت nested هم انجام بدید برای مثال:
تو اینجا باید یک نکته رو در نظر داشته باشید که جنگو هربار که یک nested میزنید از بیرون به داخل میره و هربار که وارد یک مرحله عمیق تر میشه یک savepoint میسازه از نستد بالایی یعنی اول ترنزاکشن آپدیت انجام میده بعد savepoint میسازه که بفهمه چیکار کرده بعد میره دومی، میتونید ساخت savepoint رو غیر فعال کنید با پاس دادن savepoint=false به فانکشن اتومیک که توصیه جنگو اینه که اینکار نکنید مگر اینکه واقعا مشکل پرفورمنس بخورید.
در پست بعدی درباره Transaction.on_commit صحبت میکنم :)
@TorhamDevCH
اگه نمیدونید به طور کلی ترنزاکشن چیه میتونید به این لینک سر بزنید. ولی خیلی خلاصه بخوام بگم به انجام چندتا کوئری مختلف ولی در یک 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
Fauna
What is a database transaction?
A database transaction is a sequence of multiple operations performed on a database, and all served as a single logical unit of work — taking place wholly or not at all.
👍3
Forwarded from TorhamDev | تورهام 😳
مشکل 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
بیایید اول بفهمیم مشکل چی هست اصلا که میخواییم حلش کنیم. از زمانی که انسانها موفق شدم چند پروسس رو همزمان اجرا کنن این مشکل به وجود اومد برای مثال این روزها دیگه شما فقط یک ترد پروژه جنگوتون اجرا نمیکنید بلکه با ابزارهای مثل گونیکورن و یونیکورن و ... چندتا ترد و پروسس ازش اجرا میکنید تا همچی سریعتر اتفاق بیوفته. اما این مشکل که اتفاق میوفته چیه؟
فرض کنید شما یک سیستم بانکی دارید و داخل این بانک یک حساب مشترک دارید بین user1 و user2. هردو این یوزرها به این حساب دسترسی دارن یوزر اول پرداخت کننده است و یوزر دوم برداشت کننده حالا فکر کنید بالانس(موجودی) حساب ۱۰۰۰ دلاره.
در همین لحظه که ما هستیم user1 میخواد ۱۰۰ دلار به حساب واریز کنه و دقیقا همزمان باهاش user2 میخواد ۱۰۰ دلار برداشت کنه. سوال اینه که در آخر این برداشت و واریز موجود یا همون بالانس حساب چقدر خواهد بود؟ جواب منطقی ما اینه که بالانس همون هزار دلار خواهد بود چون ۱۰۰ دلار اومد و ۱۰۰ دلار هم رفت و آره! اگه برنامه ما فقط و فقط یک پروسس باشه این ۲ درخواست به ترتیب اجرا خواهد شد و بالانس همون هزار دلار میشه اما اگه برنامه بیشتر از یک پروسس باشه چه اتفاقی میوفته؟
خوب بیایید فرض کنیم این بار درخواست اول به پروسس شماره ۱ و درخواست دوم به پروسس شماره ۲ میره و این دو همزمان از دیتابیس بالانس حساب میخونن تا درنهایت بهش جمع و منها بزنن دیگه. مراحل این خواهد شد.
۱. یوزر اول درخواست میزنه و موجودی ۱۰۰۰ دلار رو دریافت میکنه
۲. یورر اول موجودی آپدیت میکنه به ۱۱۰۰ دلار .
۳. یوزر دوم دقیقا تو همون لحظه درخواست میزنه و قبل اپدیت شدن موجودی اون میگیره و نتیجه موجودی برای ۱۰۰۰ دلاره
۴. ازش ۱۰۰ تا کم میکنه و ۹۰۰ رو به عنوان بالانس ذخیره میکنه.
و درنهایت موجودی شد ۹۰۰ دلار! این ماجرا میتونست برعکس هم اتفاق بیوفته و موجودی بشه ۱۱۰۰ دلار که همش نتیجه یک چند صدم ثانیه اختلاف بین ریکوئست یک و دو بود. نکته اصلی این بود که اینا قبل اینکه اون یکی موجودی آپدیت موجودی رو میخوندن و داخل مموری ذخیره میکردند در نتیجه تو اپدیت هم اشتباه اپدیت میکردند.
حالا که فهمیدید ماجرا از چه قرار شما میتونید داخل #django با استفاده از select_for_update و ترنزاکشن که پستها قبل توضیح دادم این ماجرا حل کنید. ( در حقیقت جنگو ماجرا رو حل نمیکنه بلکه با استفاده از متدها شما به جنگو میگید کوئری بسازه که نتیجه اش این بشه که دیتابیس براتون یک لاک رو row که میخوایید آپدیت کنید بگیره)
حالا روش استفاده و توضیحات بیشتر میتونید تو مقاله پایین بخونید. این پست خلاصهای کوتاه از مقاله زیر بود ( خود مقاله هم کوتاه)
https://www.sankalpjonna.com/learn-django/managing-concurrency-in-django-using-select-for-update
@TorhamDevCH
Sankalpjonna
Managing concurrency in Django using select_for_update
A tutorial on how one can use select_for_update to lock a Django queryset until the transaction it is in is committed in order to handle concurrency.
👍7❤1