ฉันจะแปลง Django QuerySet เป็นรายการคำสั่งได้อย่างไร


122

ฉันจะแปลง Django QuerySet เป็นรายการคำสั่งได้อย่างไร ฉันไม่พบคำตอบสำหรับเรื่องนี้ดังนั้นฉันจึงสงสัยว่าฉันไม่มีฟังก์ชันตัวช่วยทั่วไปที่ทุกคนใช้หรือไม่

คำตอบ:


178

ใช้.values()วิธีการ:

>>> Blog.objects.values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}],
>>> Blog.objects.values('id', 'name')
[{'id': 1, 'name': 'Beatles Blog'}]

หมายเหตุ: ผลลัพธ์คือสิ่งQuerySetที่ส่วนใหญ่ทำงานเหมือนรายการ แต่ไม่ได้เป็นตัวอย่างของlist. ใช้list(Blog.objects.values(…))หากคุณต้องการอินสแตนซ์ของlistไฟล์.


7
ใช่คุณระบุฟิลด์ที่คุณต้องการvalues()ส่งคืนโดยส่งเป็นอาร์กิวเมนต์ ระวังด้วยแม้ว่าดูเหมือนว่าค่าจะส่งคืนรายการของคำสั่งซึ่งเป็นรายการ<class 'django.db.models.query.ValuesQuerySet'>และไม่ใช่รายการ
dm03514

10
สิ่งนี้ไม่ได้ส่งคืนรายการจริง ๆ
astreltsov

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

34

.values()วิธีการจะกลับคุณเป็นผลมาจากประเภทValuesQuerySetซึ่งโดยปกติคือสิ่งที่คุณต้องการในกรณีส่วนใหญ่

แต่ถ้าคุณต้องการคุณสามารถเปลี่ยนValuesQuerySetเป็นรายการ Python ดั้งเดิมได้โดยใช้ความเข้าใจรายการ Python ดังที่แสดงในตัวอย่างด้านล่าง

result = Blog.objects.values()             # return ValuesQuerySet object
list_result = [entry for entry in result]  # converts ValuesQuerySet into Python list
return list_result

ฉันพบว่าข้างต้นช่วยได้หากคุณกำลังเขียนการทดสอบหน่วยและจำเป็นต้องยืนยันว่าค่าผลตอบแทนที่คาดหวังของฟังก์ชันตรงกับค่าที่ส่งคืนจริงซึ่งในกรณีนี้ทั้งสองอย่างexpected_resultและactual_resultต้องเป็นประเภทเดียวกัน (เช่นพจนานุกรม)

actual_result = some_function()
expected_result = {
    # dictionary content here ...
}
assert expected_result == actual_result

17
หรือคุณสามารถทำให้การแปลงเป็นรายการง่ายขึ้นด้วยสิ่งนี้list(result)
Adiyat Mubarak

12

หากคุณต้องการประเภทข้อมูลเนทีฟด้วยเหตุผลบางประการ (เช่นการทำให้อนุกรม JSON) นี่เป็นวิธีสกปรกอย่างรวดเร็วของฉัน:

data = [{'id': blog.pk, 'name': blog.name} for blog in blogs]

อย่างที่คุณเห็นการสร้างคำสั่งภายในรายการนั้นไม่ได้แห้งจริงๆดังนั้นหากมีใครรู้วิธีที่ดีกว่านี้ ...


ฉันดูเหมือนจะได้รับมันทำงานกับแล้วdata = list( blogs ) json.dumps( data )อาร์เรย์ออกมาพร้อมกับวัตถุมากมายที่ด้านจาวาสคริปต์โดยไม่จำเป็นต้องแยกวิเคราะห์
Arthur Tarasov

3

คุณไม่ตรงกำหนดสิ่งที่พจนานุกรมควรมีลักษณะเช่น QuerySet.values()แต่ส่วนใหญ่มีแนวโน้มที่คุณจะหมายถึง จากเอกสาร django อย่างเป็นทางการ :

ส่งคืน a ValuesQuerySet- QuerySetคลาสย่อยที่ส่งคืนพจนานุกรมเมื่อใช้เป็นอ็อบเจ็กต์ที่ทำซ้ำได้แทนที่จะเป็นโมเดลอินสแตนซ์

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



1

คุณสามารถใช้values()วิธีการตามคำสั่งที่คุณได้รับจากฟิลด์โมเดล Django ที่คุณสร้างแบบสอบถามจากนั้นคุณสามารถเข้าถึงแต่ละฟิลด์ได้อย่างง่ายดายด้วยค่าดัชนี

เรียกแบบนี้ -

myList = dictOfSomeData.values()
itemNumberThree = myList[2] #If there's a value in that index off course...



0

คุณสามารถกำหนดฟังก์ชันโดยใช้ model_to_dict ได้ดังนี้:

def queryset_to_dict(qs,fields=None, exclude=None):
    my_array=[]
    for x in qs:
        my_array.append(model_to_dict(x,fields=fields,exclude=exclude))
    return my_array
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.