ฉันมีfirst_name, last_nameและalias(อุปกรณ์เสริม) ซึ่งผมต้องค้นหา ดังนั้นฉันต้องการแบบสอบถามเพื่อให้ชื่อทั้งหมดที่มีชื่อแทน
เฉพาะในกรณีที่ฉันสามารถทำได้:
Name.objects.filter(alias!="")ดังนั้นสิ่งที่เทียบเท่ากับข้างต้นคืออะไร?
ฉันมีfirst_name, last_nameและalias(อุปกรณ์เสริม) ซึ่งผมต้องค้นหา ดังนั้นฉันต้องการแบบสอบถามเพื่อให้ชื่อทั้งหมดที่มีชื่อแทน
เฉพาะในกรณีที่ฉันสามารถทำได้:
Name.objects.filter(alias!="")ดังนั้นสิ่งที่เทียบเท่ากับข้างต้นคืออะไร?
คำตอบ:
คุณสามารถทำได้:
Name.objects.exclude(alias__isnull=True)หากคุณต้องการยกเว้นค่า null และสตริงว่างวิธีที่ต้องการให้ทำคือเชื่อมโยงเงื่อนไขต่างๆดังนี้:
Name.objects.exclude(alias__isnull=True).exclude(alias__exact='')ผูกมัดวิธีการเหล่านี้ร่วมกันตรวจสอบโดยทั่วไปแต่ละสภาพเป็นอิสระในตัวอย่างข้างต้นเรายกเว้นแถวที่aliasเป็นทั้ง null หรือสตริงที่ว่างเปล่าเพื่อให้คุณได้รับทั้งหมดNameวัตถุที่มีไม่ว่างไม่ว่างaliasฟิลด์ SQL ที่สร้างขึ้นจะมีลักษณะดังนี้:
SELECT * FROM Name WHERE alias IS NOT NULL AND alias != ""นอกจากนี้คุณยังสามารถส่งอาร์กิวเมนต์หลายรายการไปยังการโทรครั้งเดียวexcludeซึ่งจะช่วยให้มั่นใจว่าจะไม่รวมเฉพาะออบเจ็กต์ที่ตรงตามเงื่อนไขทุกข้อ :
Name.objects.exclude(some_field=True, other_field=True)ที่นี่แถวที่some_field และ other_fieldถูกรับจริงถูกแยกออกดังนั้นเราจึงได้แถวทั้งหมดที่ทั้งสองฟิลด์ไม่เป็นจริง รหัส SQL ที่สร้างขึ้นจะมีลักษณะเช่นนี้:
SELECT * FROM Name WHERE NOT (some_field = TRUE AND other_field = TRUE)อีกทางหนึ่งถ้าตรรกะของคุณซับซ้อนกว่านั้นคุณสามารถใช้วัตถุ Qของ Django :
from django.db.models import Q
Name.objects.exclude(Q(alias__isnull=True) | Q(alias__exact=''))สำหรับข้อมูลเพิ่มเติมดูหน้านี้และหน้านี้ในเอกสาร Django
นอกเหนือจากนี้: ตัวอย่าง SQL ของฉันเป็นเพียงการเปรียบเทียบรหัส SQL ที่สร้างขึ้นจริงอาจมีลักษณะที่แตกต่างออกไป คุณจะได้รับความเข้าใจที่ลึกซึ้งยิ่งขึ้นเกี่ยวกับการทำงานของแบบสอบถาม Django โดยการดู SQL ที่พวกเขาสร้างขึ้นจริง ๆ
ORเงื่อนไขในการหลอมรวม ฉันจะแก้ไขคำตอบเพื่อชี้แจง
                    NOT (A AND B) NOT A OR NOT Bฉันคิดว่ามันทำให้เกิดความสับสนกับนักพัฒนา Django ใหม่ที่รู้จัก SQL แต่ไม่คุ้นเคยกับ ORM
                    ANDในแบบสอบถามแรกเป็นเพราะคุณกำลังใช้OR excludeในกรณีทั่วไปก็อาจจะต้องมากขึ้นที่จะคิดว่าการผูกมัดเป็นเช่นTHEN exclude(A) THEN exclude(B)ขออภัยเกี่ยวกับภาษาที่รุนแรงข้างต้น คำตอบของคุณเป็นสิ่งที่ดีจริงๆ แต่ฉันกังวลเกี่ยวกับนักพัฒนาใหม่ที่รับคำตอบของคุณโดยทั่วไป
                    ANDและORอาจเป็นประโยชน์สำหรับคนที่มา Django จากพื้นหลัง SQL เพื่อความเข้าใจที่ลึกซึ้งยิ่งขึ้นของ Django ฉันคิดว่าเอกสารทำงานได้ดีกว่าที่ฉันสามารถทำได้
                    Name.objects.filter(alias__gt='',alias__isnull=False)alias__isnull=Falseเงื่อนไขซ้ำซ้อน หากสนามเป็นจริงNullมันจะถูกยกเว้นโดยประโยคแรก?
                    alias__gtเป็นสิ่งเดียวที่ทำงานสำหรับคอลัมน์ประเภท JSON ที่ผมอยากจะยกเว้นสตริงที่ว่างเปล่าจาก JSON {'something:''}เช่น ดังนั้นไวยากรณ์การทำงานคือ:jsoncolumnname__something__gt=''
                    ประการแรกเอกสาร Django แนะนำอย่างยิ่งไม่แนะนำให้ใช้ค่า NULL สำหรับเขตข้อมูลแบบสตริงเช่น CharField หรือ TextField อ่านเอกสารประกอบสำหรับคำอธิบาย:
https://docs.djangoproject.com/en/dev/ref/models/fields/#null
การแก้ไข: คุณสามารถเชื่อมโยงวิธีการต่างๆบน QuerySets ได้ด้วยฉันคิดว่า ลองสิ่งนี้:
Name.objects.exclude(alias__isnull=True).exclude(alias="")นั่นควรให้ฉากที่คุณกำลังมองหา
จาก Django 1.8
from django.db.models.functions import Length
Name.objects.annotate(alias_length=Length('alias')).filter(alias_length__gt=0)เพื่อหลีกเลี่ยงข้อผิดพลาดทั่วไปเมื่อใช้excludeโปรดจำไว้ว่า:
คุณสามารถไม่ได้เพิ่มหลายเงื่อนไขเข้ายกเว้น ()filterบล็อกเช่น หากต้องการยกเว้นหลายเงื่อนไขคุณต้องใช้การยกเว้นหลายรายการ ()
ตัวอย่าง
ไม่ถูกต้อง :
User.objects.filter (email='example@example.com '). ยกเว้น (profile__nick_name =' ', profile__avt =' ')
ถูกต้อง :
User.objects.filter (email='example@example.com '). ยกเว้น (profile__nick_name =' '). ยกเว้น (profile__avt =' ')
คุณสามารถทำได้:
Name.objects.exclude(alias="").exclude(alias=None)มันง่ายมาก ๆ  filterใช้เพื่อจับคู่และexcludeเพื่อจับคู่ทุกอย่าง แต่สิ่งที่ระบุ นี้จะประเมินผลการศึกษาลงใน SQL NOT alias='' AND alias IS NOT NULLเป็น
alias="") และ NULL ( alias=None) ออกจากแบบสอบถาม Name(alias=None)ขอแสดงจะรวมถึงกรณีที่มี
                    .filter(alias!="")แต่ไม่ใช่ชื่อ ฉันแก้ไขคำตอบของฉันแล้ว อย่างไรก็ตามฟิลด์อักขระไม่ควรอนุญาตค่า NULL และใช้สตริงว่างสำหรับค่าที่ไม่ใช่ (ตามแบบแผน)
                    นี่เป็นอีกวิธีที่ง่ายที่จะทำ
Name.objects.exclude(alias=None)None""ไม่ได้เป็นสิ่งเดียวกับ
                    
OR(เฉพาะในกรณีนี้) ก็ผลิตANDSQL ดูหน้านี้สำหรับการอ้างอิง: docs.djangoproject.com/en/dev/topics/db/queries/…ข้อดีของการโยงคือคุณสามารถผสมexcludeและfilterสร้างแบบจำลองของเงื่อนไขการสืบค้นที่ซับซ้อน หากคุณต้องการจำลอง SQL จริงORคุณต้องใช้วัตถุ Django Q: docs.djangoproject.com/en/dev/topics/db/queries/?hl=th โปรดแก้ไขการแก้ไขของคุณเพื่อสะท้อนสิ่งนี้ .