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
pass: can i stay here? 👉👈
🤣8
TorhamDev | تورهام 😳
pass: can i stay here? 👉👈
یک نکته جالب:

تو عکس یک تودو میبینید که نوشته منطق withdraw یا همون برداشت رو اینجا توسعه بده.

نکته ای که میخوام بگم اینه که ما باید سعی کنیم بیزینس لاجیک رو تو یکجا نگه داریم تا جای ممکن حالا این تصمیم شماست که کجا قرارش بدید. توصیه جنگو اینه که سعی کنید اینجور چیزا نزدیک به مدل نگه دارید چون در نهایت بیشتر لاجیک‌ها به crud ختم میشه در نتیجه شاید بهتر باشه از این ویو صرفا جهت routing استفاده کنیم و داخلش یک فانکشن ران کنیم که برداشت برامون انجام بده مثلا همچین چیزی:


Wallet.objects.get(pk=id).do_withdraw(amount=100)



خب این یعنی من یک فانکشن رو مدل Wallet دارم که این کار قرار برام انجام بده.

یا به عبارتی:



@transaction.atomic()
def deposit(self, *, amount: int):
obj = self.get_queryset().select_for_update().get()
obj.balance = models.F("balance") + amount
obj.save()

Transaction.objects.create(
amount=amount,
wallet=self,
tr_type=TransactionsType.DIPOSIT,
status=TransactionsStatus.SUCCESS,
)

@transaction.atomic()
def withdraw(self, *, amount: int): ...



اینطوری اگه کسی متدهای مدل بخونه تا حد زیادی لاجیک‌‌هارو میفهمه و اینکه میدونه اگه دنبال یک لاجیک میگرده کجا بره!


@TorhamDevCH
👍9
get_object_404 in #django

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

from django.shortcuts import <NAME>


امروز میخوام درباره یکی از میان‌بر ها بگم به اسم get_object_404 این شرت‌کات کار نوشتن کد شما رو کمتر میکنه. بیشتر مواقع وقتی شما میخوایید یک آبجکت رو در دیتابیس کوئری بزنید باید این کار رو کنید: اگر آبجکت بود اون رو برگردون اگر نبود ارور ۴۰۴ بده.

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


def get_object(self):
try:
return Record.objects.get(id=self.request.query_params['id'])
except Record.DoesNotExist:
raise Http404()



حالا جنگو اومده این کار براتون کرده یک فانکشن. فقط صداش میزنید و مدل و کوئری که میخوایید بزنید رو بهش میدید و اگر وجود داشت آبجکت بهتون میده اگه نداشت خودش ارور ۴۰۴ میده.


def get_object(self):
return get_object_or_404(Record, id=self.request.query_params['id'])


این شرت‌کات یک نمونه مشابه داره به اسم get_list_or_404 که این یکی به شما لیستی از ابجکت‌ها رو برمیگردونه. اولی فقط و فقط یک آبجکت برمیگردوند.

@TorhamDevCH
👍7🍾2
تا حالا براتون سوال شده جنگو چطوری وقتی یک رابطه one2many یا همون فارنکی میزنید چطوری وقتی فیلد صدا میکنید ابجکت فارنکی بهتون میده؟ یا چطوری کوئری look up هایی که میزنید برای مثال داخل filter رو هندل میکنه؟
مثلا رابطه بین مدل a و b دارید بعد همچنین چیزی مینویسید

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

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

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

@TorhamDevCH
👍4
HTTP1 vs HTTP2 vs HTTP3 - A Deep Dive.pdf
3.9 MB
تفاوت بین http1 و http2 و http3 و مراحل رشدشون

داکیومنت فوق‌العاده‌ای به نظرم حتما بخونید، شاید شما هم نمی‌دانستید http0.9 هم داشتیم :)

من قبلا دوره حسین ناصر رو دیده بودم و خب تو اون دوره پروتوکل ها و http و نسخه های مختلف رو توضیح میده، این داکیومنت واقعا مکمل عالیه برای کامل کردن اون اطلاعات دوره.

- منبع

دوره حسین ناصر هم اسمش Fundamental of back-end engineering هستش، دوره خیلی خوبیه.

@TorhamDevCH
👍14💋51👎1
امروز یک پست جالب درباره آپتومایز کردن کوئری‌های جنگو مینویسم ✌️
🔥11❤‍🔥2👍1👌1
این چند روز اخیر داشتم رو این پروژه کار میکردم. خیلی چیزا جدید یادگرفتم. هنوز هم روش کار میکنم، هر روز که چیزا جدید میخونم روش پیاده میکنم، تا الان باب میل خودم هست :) حالا فرستادمش برای اهل فن‌ها تا مشکل بگیرن ازش بدم بیاد XD

https://github.com/TorhamDev/simple-wallet-improved


داخلش از جنگو - جنگو رست - رببیت - پستگرس استفاده کردم.



@TorhamDevCH
بیایید به بهانه آپتومایز کردن کوئری‌های #جنگو چندتا چیز جدید درباره 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
🙏7👍6👌21
بچه‌ها میتونید تسک‌هایی که شرکت‌ها بهتون دادن برای مصاحبه رو برام بفرستید لطفا؟ 👈👉🥹
تولدم مبارک 🎉

هدیه نمیگیرم ولی اگه کسی خواست بده میتونه تتر بزنه 😂❤️

My Public Address to Receive TRX TDzW3Q8DkenuYdoQFqsRE7mZZYuFhzZRAH

Pay me via Trust Wallet: https://link.trustwallet.com/send?coin=195&address=TDzW3Q8DkenuYdoQFqsRE7mZZYuFhzZRAH
22👎4👍2🍾2🗿2😁1💋1
چطور کوئری آپدیت بهتری داخل #جنگو بزنیم؟

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

مدل فرضی:

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
👍189
آپدیت کردن چند آبجکت به صورت همزمان در #جنگو

فریم‌ورک #django قابلیت آپدیت کردن دیتاها رو به روش ها مختلف داره که خیلی ها یا ازش بی خبر ان یا استفاده نمیکنن. بیایید ببینیم هر کدوم رو کجا استفاده کنی بهتره :)

مدل فرضی:

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

خب فرض کنید ما یک هدیه به مناسب عید نو روز میخواییم به کاربرا بدیم، مثلا میخاییم نفری ۲ هزار تومن هدیه بدیم D:

حالا چند روش وجود داره.

روش اول ( نوب):
users = Records.objects.all()

for user in users:
user.balanc = user.balance + 2
user.save()

خیلی ساده و البته درب و داغون در خیلی جهات. مشکل اول اینه که ما رو همه کاربرا حلقه میزنیم و هر بار آپدیت رو روی کاربرا صدا میزنیم یعنی برای هر یوزر یک درخواست اپدیت به دیتابیس میره که اگه ۱ میلیون یوزر داشته باشیم ۱ میلیون درخواست میره :).

( تو اینه پست به اینکه باید از F استفاده کنید یا کانکارنسی و اینا هندل کنید اشاره نمیکنم، پست‌ها قبلی بخونید)

حالا روش بهتر چیه؟

روش بهتر:

user = Records.objects.update(balance=F("balance") + 2 )

همینقدر ساده :)


سناریو دوم: با بک‌اند یک بازی خفن رو داریم توسعه میدیم، داخل این بازی هر هفته یک ایونت اتفاق میوفته که افرادی که اون رو تموم کنن در آخر هفته یک تایتل به کنار اسمشون اضافه میشه و همچنین اگه امتیاز بالاتر از ۱۰ کسب کرده باشن به بالانس پول داخل گیم‌شون هم ۱۰۰ تا گلد اضافه میشه.


حالا بیایید فقط کوئری آپدیت این بهش ببینیم، فرض کنید این کوئری آخر هفته اجرا میشه. ( این فیلدا تو مدل فرض نداریم دیگه خودتون فرض کنید هست 😂❤️)

users = Records objects.fileter(done_weekly=True)

for user in users:
user.name = "Grunt " + user.name
if user.weekly_score >= 10:
user.balance = user.balance + 100

user.save()


خب همینطور که خیلی معلومه مشکلات فراوان داخلش هست. بزرگ‌ترین مشکلش اینه که هر بار برای هر کاربر یک درخواست آپدیت میدیم که میشهه همون مشکل بالا، آما آیا این بار میشه از روش بالا استفاده کرد و اینو فیکسش کرد؟ نه
روش بالا زمانی کاربرد داره که فیلدها قراره یک مقداری ثابتی به همشون داده بشه، اینجا بعضی ها ۱۰۰ تا گلد میگیرن بعضی ها نه پس کار نمیکنه، اینجا ما میتونیم از فانکشن bulk_update جنگو استفاده کنیم.

همون حلقه بالا رو میزنید با این تفاوت که داخلش .save رو صدا نمیزنید و تمام آبجکت‌ها رو داخل مموری آپدیت میکنید و بعد همچین حرکتی میزنید:

Records.objects.bulk_update(updated_users_list)

و تموم همرو با هم آپدیت میکنید با یک درخواست اینجا حتی میتونید یک قدم جلوتر برید و با اضافه کردن updated_fields به ورودی فانشکن و مشخص کردن اینکه دقیقا دوتا فیلد بالانس و نام فقط قرار آپدیت بشه بهترش کنید!

از این به بعد بهتر آپدیت کنید :)

@TorhamDevCH
❤‍🔥9👍2🐳2🆒2
یک چیزی که خیلی داخل بچه‌هایی که جنگو یاد میگیرن میبینم اینه که خیلی تایم‌شون رو داخل یادگرفتن سیستم تمپلیت جنگو هدر میدن. اقا اگه قرار بک‌اند کار باشید و کارهای فول استکی انجام نمیدید(حتی اونجا هم بیشتر موارد لازم نیست) اصلا از این بخش بگذرید به کار شما نمیاد اصلا، بیشتر عمر بک‌اند تون قراره API توسعه بدید نه تمپلیت، به جاش روی خود API و ORM جنگو و DRF تمرکز کنید.

@TorhamDevCH
👍422❤‍🔥1👎1
ای بابا باز دوباره ۴ شد که
😭11😁6🥱3🥰1🌚1🍓1
دارم یکدوره جدید میزنم به عنوان: شیرجه عمیق در ORM جنگو

اسمش رو تصمیم نگرفتم ولی گرفتید ماجرا رو دیگه. دوره کوتاهی احتمالا ۴ قسمتی که CRUD توضیح بدم و اینکه چطور بهتر از orm استفاده کنیم.
👍24😁6🔥3
دوستان کسی نیست کاور بزنه؟ قسمت دوم(اول) هم رکورد کردم. خیلی وقته کاور نزدم چیزی به مغزم نرسید
👍3💅3🌚1👀1
Forwarded from Sadra Codes
شهریار زحمت کشیده یه کتابخونه طراحی کرده واسه بنچمارک کردن مدل‌های LLM زبان فارسی!

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

اگه مثل من علاقه دارید یا این مورد مربوطه به حوزه کاریتون، حتما بررسیش کنید. جالبه.

🔗 https://github.com/shahriarshm/parsbench

خود شهریار: https://x.com/shahriarshm
41👍1