فقط اسم محصولها رو از دیتابیس لازم دارین؟ لازم نیست جنگو کل آبجکتها رو بسازه!
متد
values_list با flat=True فقط همون یک ستون رو از دیتابیس میخونه و بهجای آبجکتهای مدل، خودِ مقدارها رو برمیگردونه. فرض کنید مدل Product با فیلدهای name و price داریم و سه محصول Book (120)، Pen (15) و Bag (300) توی دیتابیس هست:
qs = Product.objects.order_by("price")
names = qs.values_list("name", flat=True)
print(list(names))
خروجی:
['Pen', 'Book', 'Bag']
نتیجه یک لیست معمولی پایتونه از اسمها، مرتبشده بر اساس قیمت؛ آماده برای حلقه، ساختن فایل CSV یا فرستادن توی پاسخ API.
پشت صحنه: فقط همون ستون خونده میشه
با چاپ کردن
query میشه SQL ساختهشده رو دید:
qs = Product.objects.order_by("price")
names = qs.values_list("name", flat=True)
print(names.query)
خروجی:
SELECT "shop_product"."name" AS "name" FROM "shop_product" ORDER BY "shop_product"."price" ASC
توی SELECT فقط ستون name اومده. طبق مستندات جنگو، وقتی فقط چند فیلد لازم دارید و به امکانات آبجکت مدل نیازی نیست، گرفتن همون فیلدها بهینهتره؛ مخصوصاً برای جدولهایی با ستونهای زیاد یا متنهای بلند.💎
چند ستون: تاپل، namedtuple یا دیکشنری
اگه چند فیلد بدید، هر ردیف یک تاپل میشه. با
named=True تاپل اسمدار (namedtuple) میگیرید و متد values هم هر ردیف رو به شکل دیکشنری برمیگردونه:
qs = Product.objects.order_by("price")
print(list(qs.values_list("name", "price")))
print(qs.values_list("name", "price", named=True)[0])
print(qs.values("name", "price")[0])
خروجی:
[('Pen', 15), ('Book', 120), ('Bag', 300)]
Row(name='Pen', price=15)
{'name': 'Pen', 'price': 15}پارامتر flat فقط با یک فیلد
اگه
flat=True رو با بیشتر از یک فیلد بدید، جنگو خطا میده:
Product.objects.values_list("name", "price", flat=True)
خروجی (خط آخر خطا):
TypeError: 'flat' is not valid when values_list is called with more than one field.
▫️ برای گرفتن یک مقدار از یک ردیف خاص، بعدش
get رو صدا بزنید:
qs = Product.objects.values_list("price", flat=True)
print(qs.get(name="Book"))
خروجی:
120
▫️ چیزی که برمیگرده آبجکت مدل نیست؛ پس متدهای مدل و
save روی این مقدارها کار نمیکنن. هر جا آبجکت کامل لازم دارید، همون کوئری معمولی رو بنویسید.
▫️ نتیجه هنوز یک QuerySet تنبله (lazy)؛ یعنی تا وقتی ازش استفاده نکنید (مثلاً با list یا یک حلقه) کوئریای به دیتابیس نمیره و میشه قبلش
filter و order_by هم بهش زد.
آموزش هوش مصنوعی و برنامه نویسی 👇
@codingyar
وبسایت آموزشی:
www.codingyar.com

