TorhamDev | تورهام 😳 – Telegram
TorhamDev | تورهام 😳
2.84K subscribers
420 photos
49 videos
21 files
591 links
code, linux and anything related.

• YouTube
youtube.com/@techwithtori

• CodeNaline Podcast
@CodeNaline

• Group
@GothamProgrammers

• Github
github.com/TorhamDev

• Email
torhamdev@gmail.com
Download Telegram
ساعت ۷ صبح بهتون خوش بگذره 🥰
😁6😭2🔥1🥰1🌚1
دوستان شهریار پس از سالها بلاخره پخت

حل کردن بازی Wordle با پایتون

https://shahriarshm.com/?p=104


@TorhamDevCH
😁5👍1👎1
دوستان همینک وب سرور خودم رو معرفی میکنم. آینده وب سرورها.
https://github.com/TorhamDev/its-a-webserver

فقط متد GET از HTTP/1.1 رو ساپورت میکنه 😂✌️
@TorhamDevCH
Houdini
Eminem
#music

خواستم بگم امینم برگشت 💀
https://youtu.be/22tVWwmTie8
موزیک ویدیوش حتما ببینید
❤‍🔥1👎1
Media is too big
VIEW IN TELEGRAM
Learn PostgreSQL Tutorial - Full Course for Beginners

دانلود کرده بودم برای مصارف شخصی گفتم شاید به دردتون بخوره. نسخه یوتیوبش هست. این برای اونایی که نت درست و درمون ندارن.
15
Forwarded from Sadra Codes
توی نسخه 0.6.3 پای‌اکشن، سرعت اجرای اکشن به دلیل Dependency Management بهینه‌تر، بهبود پیدا کرده و سریعتر شده.

و اینکه خروجی کامند pyaction run تمیزتر و بهتر شده. :))


More >> https://pyaction.imsadra.me/
1👍1
شاید برای شما هم سوال بود که چطور SQL کوئری‌هایی که با ORM جنگو میزنیم رو ببینیم؟

https://b0uh.github.io/django-show-me-the-sql.html

@TorhamDevCH
👍41
به نظرم یکی از بهترین اسکیل(مهارت؟)هایی که به عنوان یک برنامه‌نویس میتونید داشته باشید، توانایی تحقیق و جست‌وجو، یعنی چی؟
یعنی وقتی یک سوالی براتون پیش میاد سریع نرید دنبال اینکه جواب چیه. منظورم اینه که بدون درک کردن جواب صرفا جواب بدونید. مثل اون موقع‌هایی که داری گیم بازی میکنی تو یک مرحله میمونی و گوگل و بقیه جاهارو میگردی که فقط مرحله رو رد کنی، دقیقا هرکاری که طرف میکنه رو انجام میدی تا مرحله رو رد کنی:).
ولی خب شاید بهتر بود از همون اول دیالوگ NPCهارو میخوندی XD.
موضوع اینه که آدم فضایی‌ها نمیان به اون آدم‌ها بگن که چطوری اون مرحله کار میکنه یا راه حل فلان مشکل چیه، اون آدم‌ها صرفا انقدر صبور و کنجکاو بودن که دیالوگ NPCها رو بخونن. در نتیجه شماهم اگه سعی کنی دفعه بعد که مشکلی رو خوردید به جای جواب مستقیم به سمت جواب غیر مستقیم برید و اول موضوع و مشکل رو درک کنید احتمالا خیلی چیزهای بیشتری یاد میگیرید.

روشش هم ساده است.
به یک مشکل میخورید، مثلا ارور، اینجا دوتا مسیر پیش‌رو داریم.
مسیر اول ارور کپی میکنی گوگل یا این‌روزا با کلاس‌ترها GPTمیکنن و جواب مستقیم در میارید دوتا خط کد هم کپی میکنید یا تغییر میدید و پایان.

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

@TorhamDevCH
👍15🔥11❤‍🔥11
ایونت لوپ چیست؟ درسته داخل js توضیح میده ولی این مفهوم همجا یک چیزه ما داخل Async پایتون هم ایونت لوپ رو داریم. و البته که یکم js یادگرفتن بد نیست :)

اگه یک نفر اینطوری js یاد میده، من برم js دولوپر شم 😂💔

https://www.youtube.com/watch?v=8aGhZQkoFbQ
👍1
یک نکته درباره primary key داخل #جنگو اینه که شما میتونید برای هر app به شکل خاص primary key خاص خودش رو داشته باشید. مثلا برای یک app از big integer استفاده کنید و برای یکی از UUID این رفتار رو برای هر اپ میتونید به مشخص کردن AppConfig.default_auto_field مشخص کنید. حالا #django این قابلیت رو هم بهتون میده که جدا از انتخاب دونه دونه برای هر اپ یک حالت گلوبال در نظر بگیرید که اگر مخصوص اپ ست نکرده باشید از اون استفاده میکنه که پیش‌فرض خود جنگو BigIntegerField در نظر میگیره و میشه با تغییر دادن DEFAULT_AUTO_FIELD داخل settings.py به شکل گلوبال تغییرش داد

@TorhamDevCH
❤‍🔥22👍2
TorhamDev | تورهام 😳
یک نکته درباره primary key داخل #جنگو اینه که شما میتونید برای هر app به شکل خاص primary key خاص خودش رو داشته باشید. مثلا برای یک app از big integer استفاده کنید و برای یکی از UUID این رفتار رو برای هر اپ میتونید به مشخص کردن AppConfig.default_auto_field…
این توانایی که خود #جنگو بهتون میده ولی از trick دیگه هم میتونید استفاده کنید و اون هم ساختن یک مدل ابسترکت و بقیه مدل‌ها ازش ارث ببرن.
مثال:

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
41👍1
کوئری‌های #جنگو lazy هستند

اما این یعنی چی؟ کلا برای فهمیدن موضوع lazy فکر کنم این ویدیو شهریار شریعتی (Laziness in Python تنبلی در پایتون ) خوب باشه و بتونید بفهمیدش، یا اینکه نسخه انگلیسی از Computerphile.

به این مثال توجه کنید:

>>> q = Entry.objects.filter(headline__startswith="What")
>>> q = q.filter(pub_date__lte=datetime.date.today())
>>> q = q.exclude(body_text__icontains="food")
>>> print(q)


این مثال خود داکیومنت جنگوعه. اینجا با ۳ تا کوئری زدیم و یکچیزی از دیتابیس درخواست کردیم، حالت عادی با خودتون میگید خب الان ۳ بار دیتابیس hit شده (درخواست رفته براش) اما در حقیقت فقط یک بار دیتابیس هیت شده و اون هم تو خط آخر جایی که کوئری رو پرینت کردیم. جنگو تنها و تنها زمانی دیتابیس رو با کوئری که شما زدید hit میکنه که دیتا رو درخواست کرده باشید. حالا چه پرینت باشه چه حلقه بزنید روش و ... و این نتیجه لیزی بودن کوئری هاست. تو کد بالا در حقیقت خط اول یک کوئری ساختیم، خط دوم یک فیلتر به همون کوئری اضافه کردیم و در نتیجه یک کوئری جدید ساخته شده و خط سوم هم همینطور و در نهااااااااااایت در خط چهارم یک کوئری به دیتابیس زدیم که داخش گفته هدلاین با what شروع شده باشه تاریخ پابلیش کوچیکتر از امروز باشه اونایی رو میخام که داخل بدنه شو کلمه food وجود داره.

@TorhamDevCH
6👍2
خب من یک چیز خیلی جالب و در این حال گیج‌کننده درباره ORM #جنگو فهمیدم.

تو پیام قبلی گفتم که کوئری‌های #django دقیقا چه زمانی واقعا اجرا میشن. اما اینجا یک نکته دیگه‌ای هم هست، جنگو نتیجه کوئری‌هارو کش میکنه.

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

اول این قانون تو ذهنتون داشته باشید: هر چیزی که باعث ایجاد یک QuerySet جدید بشه، باعث هیت به دیتابیس خواهد شد اگر اون کوئری اجرا بشه.

به مثال زیر دقت کنید:

users = User.objects.all()
print(users)

if users:
for u in users:
print(u)


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

اما اگر من بگم فقط دو بار دیتابیس هیت میکنه چی؟

بزارید توضیح بدم. تو خط اول ما صرفا کوئری رو ساختیم و هیچ هیتی به دیتابیس نزدیم. تو خط دوم ما کوئری پرینت کردیم و اینجا اولین هیت به دیتابیس خورده میشه، ولی یک نکته اینجاست وقتی شما یک کوئری رو پرینت میکنید جنگو نمیاد کل کوئری رو اجرا کنه چون منطقی نیست!، مثلا اگر کوئری شما هزارتا خروجی داشته باشه شما اون هزارتا رو که داخل پرینت نمیخایید، در نتیجه جنگو فقط یک بخش از کوئری رو ران میکنه یا به عبارت دیگه از LIMIT استفاده میکنه!. تو این خط هیچ کش کردنی اتفاق نمیوفته(جلوتر میگم چرا)

خط بعدی ما از if استفاده کردیم و اینجا یک هیت دیگه به دیتابیس میخوره اما این‌بار کل کوئری اجرا میشه و اینجاست که جنگو ریزالت کوئری میگیره و داخل کش ذخیره میکنه. تو خط بعدی که اومدیم حلقه زدیم روی کوئری جنگو دیگه نمیاد به دیتابیس درخواست بزنه و از کش استفاده میکنه!

در نتیجه اینجا فقط ۲ بار دیتابیس هیت میخوره.

ادامه داخل پیام بعد...

@TorhamDevCH
👍11❤‍🔥3🆒21
TorhamDev | تورهام 😳
خب من یک چیز خیلی جالب و در این حال گیج‌کننده درباره ORM #جنگو فهمیدم. تو پیام قبلی گفتم که کوئری‌های #django دقیقا چه زمانی واقعا اجرا میشن. اما اینجا یک نکته دیگه‌ای هم هست، جنگو نتیجه کوئری‌هارو کش میکنه. و این خیلیییییییییییی مهمه، یعنی بعضی از جاها…
خب از ماجرا و گفته‌های خود داکیومنت جنگو میتونیم نتیجه بگیریم که جنگو زمانی یک ریزالت یک کوئری رو کش میکنه که کوئری کاملا اجرا بشه. یعنی داخل پرینت که بخشیش فقط اجرا شد کش اتفاق نمیوفته ولی داخل if کش اتفاق میوفته.
حالا شاید براتون سوال بشه کش رو چطوری میشه دید؟ میتونید با استفاده از _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
👍7🆒41
یک مبحثی که خیلی وقت‌ها آدم‌های رو داخل #جنگو گیج میکنه موضوع Aggregation هستش. برای مثال کوئری پایین:


>>> 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
👍731🌚1
If you think you're perfect already, then you never will be.

—Cristiano Ronaldo
11👍1
توصیه خود #جنگو اینه که آقا اگه به کوئریت شک داری احساس میکنی مقدار اشتباه داره میده یا اینی که نوشتی نتیجه‌اش اون SQL که میخواستی نشده، بشین ببین واقعا چه کوئری SQL ای ساخته که اینکه چطور این کار کنید تو یکی از پست‌ها بالا گفته بودم.

@TorhamDevCH
👍2
شاید برای شما هم سوال بود که چطور SQL کوئری‌هایی که با ORM جنگو میزنیم رو ببینیم؟

https://b0uh.github.io/django-show-me-the-sql.html

@TorhamDevCH
❤‍🔥2