จะรับ QuerySet ของแถวทั้งหมดพร้อมฟิลด์เฉพาะสำหรับแต่ละแถวได้อย่างไร


109

ฉันมีแบบจำลองEmployeesและต้องการมี QuerySet ของแถวทั้งหมด แต่มีฟิลด์เฉพาะบางฟิลด์จากแต่ละแถวไม่ใช่ทุกฟิลด์

ฉันรู้วิธีสืบค้นแถวทั้งหมดจากตาราง / โมเดล:

Employees.objects.all()

ฉันต้องการทราบวิธีการเลือกฟิลด์สำหรับแต่ละองค์ประกอบ Queryset ฉันจะทำเช่นนั้นได้อย่างไร?


คุณหมายถึงอะไร "และใช้เพียงอันเดียว"? A SELECT colแทนSELECT *?
Ciro Santilli 郝海东冠状病六四事件法轮功

คำตอบ:


193
Employees.objects.values_list('eng_name', flat=True)

ที่สร้างรายชื่อแบนของทุกeng_names หากคุณต้องการมากกว่าหนึ่งฟิลด์ต่อแถวคุณไม่สามารถทำรายการแบบรวมได้: สิ่งนี้จะสร้างรายการสิ่งที่เพิ่มขึ้น:

Employees.objects.values_list('eng_name', 'rank')

ขอบคุณสำหรับคำตอบจะเป็นอย่างไรถ้าฉันต้องการเลือกเพียง 1 ช่องหรือมากกว่านั้น (ไม่ใช่ทั้งหมด)
zentenk

ขออภัยฉันไม่เข้าใจคำถาม
Daniel Roseman

4
โปรดแบ่งปันเอกสารที่จะช่วยให้ผู้อื่น
bob marti

26

นอกเหนือจากvalues_listที่Daniel กล่าวถึงแล้วคุณยังสามารถใช้only(หรือdeferเพื่อให้ได้ผลตรงกันข้าม) เพื่อรับชุดวัตถุที่มีเฉพาะ id และฟิลด์ที่ระบุเท่านั้น:

Employees.objects.only('eng_name')

สิ่งนี้จะเรียกใช้แบบสอบถามเดียว:

SELECT id, eng_name FROM employees

3
คำสั่งนี้ส่งคืนฟิลด์ทั้งหมดสำหรับ Django เวอร์ชัน 2.1.3 และ python เวอร์ชัน 3.6.2 ให้ฉัน
Ananthi

มันจะดึงข้อมูลนี้ที่ยื่นไว้เท่านั้น แต่ถ้าคุณพยายามเข้าถึงฟิลด์อื่นระบบจะเรียกใช้การสืบค้นฐานข้อมูลแยกต่างหาก ดังนั้นนี่จึงเป็นเทคนิคการเพิ่มประสิทธิภาพที่ดี แต่อย่าสร้างแบบสอบถามเพิ่มเติมเหล่านี้ มิฉะนั้นคุณจะสูญเสียประสิทธิภาพแทนที่จะได้รับ
Eerik Sven Puudist

6

เราสามารถเลือกฟิลด์ที่ต้องการมากกว่าค่า

Employee.objects.all().values('eng_name','rank')

หลังจากเรียกใช้แบบสอบถามสำเร็จวิธีการจัดเก็บค่าของเขตข้อมูลในตัวแปรเช่น var_name = <query_name>. <field_name> ?
user12379095

@ user12379095 เพียงแค่นี้:var_name = Employee.objects.all().values('eng_name','rank')
theQuestionMan

@ user12379095 จากนั้นใช้ var_name - ตัวอย่างเช่นพิมพ์ชื่อพนักงานและอันดับทั้งหมดคุณสามารถทำได้:for person in var_name: print(person['eng_name'] + " " + person['rank'])
theQuestionMan

3

คำตอบของ Oskar Persson เป็นวิธีที่ดีที่สุดในการจัดการเพราะทำให้ง่ายต่อการส่งข้อมูลไปยังบริบทและปฏิบัติตามปกติจากเทมเพลตเมื่อเราได้รับอินสแตนซ์วัตถุ (สามารถรับอุปกรณ์ประกอบฉากซ้ำได้อย่างง่ายดาย) แทนที่จะเป็นรายการค่าธรรมดา

หลังจากนั้นคุณสามารถรับเสาที่ต้องการได้อย่างง่ายดาย:

for employee in employees:
    print(employee.eng_name)

หรือในเทมเพลต:

{% for employee in employees %}

    <p>{{ employee.eng_name }}</p>

{% endfor %}

2

คุณสามารถใช้ values_list ร่วมกับตัวกรองได้เช่นนั้น

active_emps_first_name = Employees.objects.filter(active=True).values_list('first_name',flat=True)

รายละเอียดเพิ่มเติมที่นี่


0

คำตอบของแดเนียลตรงประเด็น หากคุณต้องการสอบถามมากกว่าหนึ่งฟิลด์ให้ทำดังนี้

Employee.objects.values_list('eng_name','rank')

สิ่งนี้จะแสดงรายการสิ่งที่เพิ่มขึ้น คุณไม่สามารถใช้ชื่อ = Ture เมื่อค้นหามากกว่าหนึ่งเขตข้อมูล

ยิ่งไปกว่านั้นหากคุณรู้ว่ามีเพียงฟิลด์เดียวที่มีข้อมูลนั้นและคุณรู้รหัส pk ให้ทำสิ่งนี้:

Employee.objects.values_list('eng_name','rank').get(pk=1)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.