อัปเดตเฉพาะฟิลด์ที่ระบุในโมเดลเท่านั้น


92

ฉันมีแบบจำลอง

class Survey(models.Model):
    created_by = models.ForeignKey(User)
    question = models.CharField(max_length=150)
    active = models.NullBooleanField()
    def __unicode__(self):
        return self.question

และตอนนี้ฉันต้องการอัปเดตเฉพาะactiveฟิลด์ ดังนั้นฉันจึงทำสิ่งนี้:

survey = get_object_or_404(Survey, created_by=request.user, pk=question_id)
survey.active = True
survey.save(["active"]) 

IntegrityError: PRIMARY KEY must be uniqueตอนนี้ผมได้รับข้อผิดพลาด

ฉันใช้วิธีนี้ในการอัปเดตหรือไม่

คำตอบ:


187

ในการอัปเดตส่วนย่อยของฟิลด์คุณสามารถใช้update_fields:

survey.save(update_fields=["active"]) 

update_fieldsอาร์กิวเมนต์ถูกเพิ่มเข้ามาใน Django 1.5 ในเวอร์ชันก่อนหน้านี้คุณสามารถใช้update()วิธีนี้แทน:

Survey.objects.filter(pk=survey.pk).update(active=True)

17

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

affected_surveys = Survey.objects.filter(
    # restrict your queryset by whatever fits you
    # ...
    ).update(active=True)

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


2
ขอบคุณ. ฉันลองใช้.getแทน.filterและไม่ได้ผล แต่ด้วยตัวกรองมันใช้งานได้ดี คุณรู้หรือไม่ว่ามีอะไรผิดปกติกับรหัสของฉันด้านบน?
ผู้ใช้ที่ลงทะเบียน

question_idปัญหาของคุณอาจจะเกี่ยวข้องกับ ค่านิยมนี้มาจากไหน? และบรรทัดใดที่เพิ่มขึ้นIntegrityError?
pemistahl

question_idมาจาก (?P<question_id>\d+)URL ความผิดของฉันคือติดตั้ง django 1.4 บนเซิร์ฟเวอร์ที่ใช้งานได้และรหัสของฉันคือ 1.5 แต่ด้วยรหัสของคุณมันใช้งานได้ดี
ผู้ลงทะเบียน

2
@RegisteredUser ดูเหมือนว่าจะไม่มีเมธอด "อัปเดต" บนอ็อบเจ็กต์เลย เมื่อคุณใช้. filter () คุณจะได้รับ queryset (ถือวัตถุเป็นศูนย์ขึ้นไป) กลับมา เมื่อคุณใช้. get () คุณจะได้รับวัตถุชิ้นเดียว
mgojohn

โดยค่าเริ่มต้นการโทรsave()(@Alasdair solution) เป็นวิธีที่ปลอดภัยกว่าเนื่องจากวิธีนี้อาจทริกเกอร์สิ่งต่างๆเช่นการตรวจสอบความถูกต้องหรือโค้ดที่กำหนดเองใด ๆ มากกว่าที่update()จะไม่ทำ
David D.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.