جنگولرن
3.86K subscribers
289 photos
76 videos
31 files
561 links
آموزش Django و بستگان
Download Telegram
دوره تخصصی آموزش ویوهای کلاس محور جنگو منتشر شد.
Django Class-based Views in depth
در این دوره، به صورت تخصصی کلاس بیس ویوها رو بررسی می کنیم و با همه attribute ها و متدهاشون و روش Override کردنشون آشنا میشیم.
همچنین با همه Exception های CBVs کامل آشنا میشیم.
پشتیبانی دوره رو هم، مثل همیشه کامل و بدون محدودیت، خودم انجام میدم.
#CBVs #Django #DjangoInDepth
لینک دمو و خرید دوره:
https://www.daneshjooyar.com/django-supplementary-cbvs/
Forwarded from Django Expert (Hêmn Hosseinpana)
پیکربندی لاگ زدن در جنگو - django logging

در این سری از ویدیوها که به ترفندها و نکته های جنگو میپردازیم، به سراغ لاگ زدن در جنگو رفتیم و کانفیگ ها و شیوه پیکربندی آن را از طریق بررسی و خواندن کد داخلی جنگو، شرح دادیم. در این ویدیو به جای کد نوشتن، بیشتر کد خوندیم که بفهمیم جنگو خودش برای لاگ زدن چگونه کار میکند و ما چگونه میتونیم از آن استفاده کنیم. همچنین امکان django logging را در سرویس های کلودی مانند sentry و APM هم مطرح کردیم. این مفاهیم رو در پروژه مینی ترلو به شکل عملی استفاده میکنیم.


video link: https://youtu.be/LGatKmpL7k8

playlist: https://www.youtube.com/playlist?list=PLJ9zDGwhhsBwdrfdaoOqbYev3_ocuBOfv

#django #logging #microfrontend_ir
〰️〰️〰️〰️〰️
©️ @DjangoEx
🧨 شناخت و پیشگیری از یکی از رخنه (Exploit) های متداول وب اپ‌ها: XSS


📃 به عنوان توسعه‌دهنده وب بهتره سعی کنیم تا کدی که توسعه میدیم تا حدامکان #Secure (امن) باشه و در مقابل رخنه‌ها و حملات ساده و متداول آسیب پذیر (#vulnerable) نباشه (و شانس رخنه رو کم کنیم).

استفاده موفق از آسیب پذیری Cross-site-scripting یا XSS باعث میشه اپ شما کد های مخرب یا ناخواسته #Javascript رو برای دیگر کاربران نمایش بده و اجرا کنه.

🎃 کد جاوا اسکریپ مخرب میتونه:
اطلاعات کاربران رو بدزده (یا زمینه‌ساز حملات پیچیده‌تری بشه)
فعالیت هایی رو انجام بده که ناخواسته اند و مورد تایید یا نیاز کاربر نیستند.

یکی از مفروضات این مشکل امنیتی اینه که محتوایی که وب سایت یا اپ ما تولید میکنه "قابل اعتماد” است. پس برای پیشگیری اش منطقیه که هرچیزی که ممکنه این "اعتماد" رو خراب کنه مدنظر بگیریم.

⬅️ به صورت خیلی خلاصه،‌ اگر کد شما هر محتوا یا ورودی که از سمت کاربر بیاد رو بدون "تمیز کردن” و بررسی صحت (#Validation) ذخیره کنه یا نمایش بده،‌ این رخنه میتونه براش اتفاق بیفته.

⚔️ به عنوان اولین لایه پیشگیری، در وب فریمورک #Django ، فرض براینه که هرچه که در context برای رندر شدن در اختیارش میگذارید، "ناامن” است و با کمک متد html.escape() همه کاراکتر های html را به معادلشون تبدیل میکنه.
مثلا:
<img src="https://lnkd.in/eE-enrjb"/>
به
&lt;img src=&quot;https://lnkd.in/eUCsnhnx;
تبدیل میشه.

🌪 اما متاسفانه این کافی نیست:
1- این پیشفرض فقط شامل Django template engine میشود، مثلا اگر Angular یا React یا Vue استفاده میکنید،‌ احتمالا شامل این موضوع نیستید.

2- افزونه یا اپ های شخص ثالثی که استفاده میکنیم ممکنه شامل این آسیب پذیری باشند.

3- اگر از ()mark_safe یا همون "Safe string" ها در متدها و #template ها استفاده میکنید،‌ دیگه خروجی شما شامل این تبدیل نمیشه. (پیشنهاد میکنم تاجایی که میتونید از این متدها استفاده نکنید.)

4- بعضی از attr ها یا روش استفاده ما از متغیرها در template، ممکنه شامل این پیشفرض نشوند یا دورش بزنند،
مثلا:
<img src={{ profile_photo_url }}>
میتونه با سواستفاده تبدیل شه به
<”img src=”/img/home-bg.jpg onload=alert(1)>

5- کاراکتر backtick و همینطور دیتایی که با base64 انکود بشه escape نمیشود، در واقع محتوایی که کاراکترهای quote یا html نداشته باشه چیزی برای escape شدن نداره،‌ مثلا:
<script>spinner.minimum = {{ minimum_price }} ;</script>
میتونه تبدیل شه به:
<script>spinner.minimum = 0; alert(1) ;</script>

سعی میکنم در پست دیگه ای، با جزئیات بیشتری روش‌ها و راههایی که میتونیم تا حد ممکن از XSS در اپ Django مان پیشگیری (#mitigate ) کنیم رو جمع آوری کنم و بنویسم.

لینک مقاله اصلی که ازش الهام گرفتم:
https://lnkd.in/erpqQREc

از لینکدین Alireza Amouzadeh
تشکر از @alireza_amouzadeh

لینک:
https://www.linkedin.com/posts/alireza-amouzadeh_xss-exploitation-in-django-applications-activity-6948679390654291968-6_IX?utm_source=linkedin_share&utm_medium=member_desktop_web
👍8👎1
Forwarded from سید فرندز / برنامه نویسی / هک و امنیت / تکنولوژی (Reza Amin)
#django
#python

Django Lifecycle

این پکیج چیه کاربردش چیه؟

تفاوت اصلی میان Django Lifecycle و سیگنال‌ها (Signals) در Django این است که Django Lifecycle یک رویکرد ساختارمندتر و اصولی‌تر را برای مدیریت چرخه عمر اجزا فراهم می‌کند. با استفاده از Django Lifecycle، شما می‌توانید کدهای مربوط به هر مرحله از چرخه عمر را به صورت مستقیم در کلاس‌های مدل یا دیگر اجزا تعریف کنید و این اجزا را به یک مدل متصل کنید. این اجازه را به شما می‌دهد که کدهای مربوط به هر مرحله را در یک مکان مرتبط و خوانا نگه دارید و از تفکیک بخش‌ها بهره‌مند شوید.

مثالی از این بخش:

به عنوان مثال، فرض کنید که می‌خواهید هر زمان که یک مدل از نوع Post ایجاد یا به‌روزرسانی می‌شود، یک عملیات خاصی انجام دهید. با استفاده از Django Lifecycle، می‌توانید این عملیات را به صورت مستقیم در مدل Post تعریف کنید، به عنوان مثال:

from django.db import models
from django_lifecycle import LifecycleModel, hook

class Post(LifecycleModel):
title = models.CharField(max_length=100)
content = models.TextField()

@hook(BEFORE_UPDATE, when="content", has_changed=True)
def update_history(cls, old_instance, instance, field_name):
History.objects.create(
post=instance,
old_content=old_instance.content,
new_content=instance.content
)


post = Post.objects.create(title="Title", content="Content")


post.content = "Updated Content"
post.save()


در این مثال، یک مدل به نام Post تعریف شده است که از کلاس LifecycleModel ارث‌بری کرده است. با استفاده از دکوراتور hook، یک عملیات update_history برای مدل تعریف شده است. این عملیات هر زمان که محتوای یک نمونه از مدل تغییر می‌کند، یک رکورد جدید به جدول History اضافه می‌کند که تاریخچه تغییرات محتوا را ثبت می‌کند.

اطلاعات بیشتر راجبش:

https://github.com/rsinger86/django-lifecycle

@SEYED_BAX
👍81👎1
Forwarded from سید فرندز / برنامه نویسی / هک و امنیت / تکنولوژی (Reza Amin)
#python
#django

Generic relations

جنریک ریلیشن در جنگو یک رابطه خاصی است که به شما اجازه می دهد یک رابطه (کلید خارجی) را با هر مدلی که در پروژه جنگویی خود نصب کرده اید برقرار کنید. وقتی شما می خواهید یک سیستمی را پیاده سازی کنید که بتواند با اشیای مختلفی ارتباط برقرار کند. ب
رای مثال، یک سیستم نظر دهی که بتواند نظرات را برای پست ها، پروفایل های کاربری، تصاویر و حتی نظرات دیگر ذخیره کند.

برای استفاده از generic relations در جنگو، شما باید از بسته contenttypes استفاده کنید که به شما اجازه می دهد از مدل ContentType استفاده کنید. این مدل اطلاعاتی درباره مدل های نصب شده در پروژه شما را ذخیره می کند و شما می توانید با استفاده از سه فیلد زیر یک رابطه عمومی با هر مدلی برقرار کنید:

یک فیلد ForeignKey که به مدل ContentType اشاره می کند (معمولا با نام content_type نامگذاری می شود).
یک فیلد PositiveIntegerField که کلید اصلی شیء مرتبط را ذخیره می کند (معمولا با نام object_id نامگذاری می شود).
یک فیلد GenericForeignKey که با استفاده از دو فیلد قبلی یک رابطه با شیء مرتبط ایجاد می کند (معمولا با نام content_object نامگذاری می شود).

مثلا فرض کنید ما یک مدل Comment داریم که می خواهیم بتواند به هر مدلی نظر دهد. ما می توانیم از generic relations برای این منظور استفاده کنیم:

from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType

class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
text = models.TextField()
date = models.DateTimeField(auto_now_add=True)

content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()

خوب حالا اینطور می توانیم برای یک پست نظر ثبت کنیم :
post = Post.objects.get(pk=1) 

comment = Comment.objects.create(user=user, text="Nice post!", content_object=post)


اگر بخواهیم برای هر مدل دیگری هم که داریم مانند دوره آموزشی و مقاله یا هر مدل دیگری می توان از همین طریق نظر ثبت کرد .

@SEYED_BAX
👍6
جنگولرن
poetry.pdf
amjadi_precommit.pdf
4.1 MB
مطلبی از لینکدین Mohammad Amin Amjadi در رابطه با pre-commit

هر چقدر حجم کد بیشتر بشه یا تیم بزرگ‌تر
بشه چالش و دغدغه‌ها بیشتر هم میشن و ریوو کردن کد هم خودش به چالشی بزرگ‌تر تبدیل
میشه که روز به روز تایم بیشتری می‌گیره و از طرفی احتمال از قلم افتادن توافق‌ها،
نکات و اصول هم بیشتر میشه.

اینجاست که pre-commit به دادمون میرسه. در این پست در ابتدا سعی می‌کنم برخی از نکات و مواردی که خودم در تیم‌ها سعی می‌کردم رعایت کنم رو مطرح کنم [امیدوارم خودشون مفید و آموزنده باشن] و در نهایت به نحوه ستاپ و نوشتن pre-commit می‌پردازم و اشاره‌ای به pre-push در یه مثال کاربردی و مورد نیاز و همین طور جاب qa می‌کنم.


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


#git #gtilab #pre_commit #pre_push #python #django
6👍1
Forwarded from CodeCrafters (Behzad Azadi)
طراحی میکروسرویس با جنگو بخش دوم میکروسرویس چیست

میکروسرویس ها روندهای جدید توسعه هستند. امروزه شرکت ها معماری میکروسرویس را برای توسعه پروژه ترجیح می دهند. این یک راه حل بسیار فشرده برای یک پروژه است. مدیریت ماژول را آسان می کند و اجرای پروژه را سریعتر می کند. همچنین به توسعه سریعتر پروژه کمک می کند. این دلایل ذکر شده و بسیاری موارد دیگر باعث تقاضای میکروسرویس می شود.

معرفی میکروسرویس
برای میکروسرویس تعریف خاصی وجود ندارد و ممکن هست هر فرد به شکلی آنرا تعریف کند اما دو تعریف عمده آن به شکل زیر است
۱-میکروسرویس‌ها، سرویس‌های کوچک و مستقلی هستند که باهم کار میکنند
۲-میکروسرویس‌ها معماری سرویس گرا با زمینه‌های محدود هستند،بطور مستقل و با یک جزء دیگر در داخل ارتباط برقرار میکنند، این معماری بسیار خودکار و و سیستم‌های نرم افزاری را تکامل می‌دهد

بیایید ببینیم که آیا از معماری سرویس گرا (SOA) آگاه هستید یا خیر، سپس ماژولار بودن پروژه و ارتباط از طریق پیام را نیز می دانید. اگر از شیوه های DevOps آگاه هستید، در مورد استقرار خودکار نیز می دانید. هر دو بیشتر به رویکرد میکروسرویس نزدیک هستند.


سه اصل مهم در طراحی میکروسرویس‌ها:
۱-از میکروسرویس برای استقرار سیستم‌ها و پروژه‌های بزرگ استفاده کنید: برای تمام مقیاس‌های پروژه استفاده از میکروسرویس اشتباه است، بلکه مناسب پروژه‌های بزرگ است که مدیریت آن چالش برانگیز باشد، اما خود این موضوع هم سردرگم کننده هستش اینکه کدوم پروژه رو کوچیک، متوسط، بزرگ بنامیم، منتها اگر سیستم ما دارای بار بالایی از درخواست کاربر است و نیاز به مقیاس پذیری دارد، میتوانیم رویکرد میکروسرویس رو پیاده سازی کنیم(در حجم تعداد اپ نیز تعداد اپ بالا میتواند به این منزله باشد)

۲-این رویکرد هدف‌محور است: مهم نیست که وقتی با مشکل مواجه می‌شویم، باید از رویکرد میکروسرویس پیروی کنیم. امروزه بسیاری از متخصصان برای توسعه پروژه به این رویکرد اشاره می کنند زیرا هدف آنها تنها ارائه راه حل مشکلات نیست، همچنین برای دید بیشتر و حفظ سهولت در ماژول ها، چنین معماری را در عمل به کار می گیرند.

۳-قابلیت تعویض ماژول ها: در پروژه های توسعه یافته قبلی که با رویکرد میکروسرویس ساخته نشده اند، امکان تغییر هر جزء از پروژه کمتر است. قبل از تغییر سازنده کامپوننت باید در مورد تغییرات برنامه ریزی کند، وابستگی کد خاصی را پیدا کند، در صورت عدم موفقیت کد به هر دلیلی، مراحل بازگشت را فهرست کند و تاثیر کد را مشخص کند. پس از همه، تغییرات نیاز به انجام عملیات تست واحد و سپس آزمایش ادغام با کل محصول دارند


در برخی سناریوها، پروژه ها بسیار پیچیده هستند یا وابستگی‌های حیاتی شدیدی دارند، در چنین شرایطی در مورد مسائل آینده یا افزایش حجم بار، ما مجبوریم به جای تغییر، اجزا را حفظ کنیم، که این بزرگترین ضرر یک رویکرد است

در میکروسرویس ها، کل پروژه را بر اساس ماژول ها به یک جزء‌های کوچک تقسیم می کنیم. بطوری که امکان تکرارپذیری را بر روی هر جزء فراهم می کند که تعمیر و نگهداری پروژه رو راحتتر میکند

اپلیکیشن‌های میکروسرویس دارای بخش‌های مهم زیر هستند:
● به اندازه های کوچک تقسیم می شوند
● برای برقراری ارتباط نیازمند انتقال پیام هستند
● مقید به زمینه‌ها هستند
● توسعه انها بصورت مستقل هستش
● استقرار هر بخش مستقل هست
● متصل به کنترل کننده مرکزی نیستند
● ساخت ها توسط فرآیندهای خودکار مستقر می شوند

به شکل آرمان گرایانه به میکروسرویس‌ها نگاه نکنید و با این تصور که در دنیای واقعی قابل پیاده سازی نیست، اگر تصور میکنید که میکروسرویس‌ها توسط بانک‌ها، سیستم‌های بیمارستانی و هتلی پیاده سازی میشه سخت در اشتباه هستید هیچکدام از میکروسرویس استفاده نمیکنند بلکه بیشتر توسط شرکت‌های فعال در حوزه محتوای جریانی(stream content) مورد استفاده قرار میگیرد، استفاده و پیاده سازی میکروسرویس یک انتخاب فردی هست و محدود به دامنه‌ای نیست، اما هدف از آن دو مورد تمرکززدایی و استقلال می‌باشد

تمرکززدایی:به این معنی است کل کارهای داخلی پروژه شامل اجرای هر ماژول، مدیریت وظایف و جابجایی کامل پروژه دیگر توسط یک سیستم واحد، مدیریت و کنترل نمیشود

استقلال: به این معنی است که به تیم‌های توسعه خود برای تولید نرم افزار ایمان داشته باشیم

مزیت این دو رویکرد این است که تغییرات در نرم افزار آسانتر و سریعتر میشود و امکان تصمیم گیری سریعتر را فراهم میکند


ادامه در وبسایت

لینک وبسایت


چندتا نکته بگم
بخش دوم و سوم کتاب بشدت پربار و پر از تحربه‌هایی هست که در دنیای واقعی با اون سروکار داریم و درکی از مسائل برامون مشخص نبود، من سعی کردم در حد توان بخش‌های مهم رو برسونم


#microservice
#django

@code_crafters
👍1
یک نکته درباره primary key داخل #جنگو اینه که شما میتونید برای هر app به شکل خاص primary key خاص خودش رو داشته باشید. مثلا برای یک app از big integer استفاده کنید و برای یکی از UUID این رفتار رو برای هر اپ میتونید به مشخص کردن AppConfig.default_auto_field مشخص کنید. حالا #django این قابلیت رو هم بهتون میده که جدا از انتخاب دونه دونه برای هر اپ یک حالت گلوبال در نظر بگیرید که اگر مخصوص اپ ست نکرده باشید از اون استفاده میکنه که پیش‌فرض خود جنگو BigIntegerField در نظر میگیره و میشه با تغییر دادن DEFAULT_AUTO_FIELD داخل settings.py به شکل گلوبال تغییرش داد

@TorhamDevCH
👍1
این توانایی که خود #جنگو بهتون میده ولی از 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
3👍3
خب من یک چیز خیلی جالب و در این حال گیج‌کننده درباره ORM #جنگو فهمیدم.

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

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

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

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

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

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


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

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

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

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

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

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

@TorhamDevCH
👍9
یک مبحثی که خیلی وقت‌ها آدم‌های رو داخل #جنگو گیج میکنه موضوع 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
4👍3
کوئری raw زدن در #جنگو

درسته #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
Transaction per-request in #django


#جنگو قابلیت انجام ترنزکشن با دیتابیس به شما میده در چندید حالت مختلف یکی از حالت‌ها ترنزاکشن بر هر ریکوئستِ، یعنی چی؟ یعنی جنگو برای هر ریکوئستی که شما میگیرید یک ترنزاکشن باز میکنه یا به عباری برای هر ویو فانکشن شما یک atomic() ران میکنه! این قابلیت به شکل پیشفرض غیر فعاله ولی میتونید با اضافه ATOMIC_REQUESTS داخل کانفیگ دیتابیسی که میخوایید این حرکت باهاش بزنید این قابلیت فعال کنید.
این کار هر ریکوئست شمارو داخل یک ترنزاکشن warp میکنه و اگر ویو شما هر اروری بده ( ارور raise کنه ) ترنزاکشن rollback میخوره و تغییرات اعمال نمیشه.

@TorhamDevCH
👍3