Memperbarui hanya bidang tertentu dalam model.Model


92

Saya punya model

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

dan sekarang saya hanya ingin memperbarui activebidang. Jadi saya melakukan ini:

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

Sekarang saya mendapatkan kesalahan IntegrityError: PRIMARY KEY must be unique.

Apakah saya benar dengan metode pembaruan ini?

Jawaban:


187

Untuk memperbarui subset bidang, Anda dapat menggunakan update_fields:

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

The update_fieldsArgumen ditambahkan dalam Django 1,5. Di versi sebelumnya, Anda dapat menggunakan update()metode ini:

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

17

Biasanya, cara yang benar untuk memperbarui bidang tertentu dalam satu atau lebih contoh model adalah dengan menggunakan update()metode pada queryset masing-masing. Kemudian Anda melakukan sesuatu seperti ini:

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

Dengan cara ini, Anda tidak perlu memanggil save()model Anda lagi karena akan disimpan secara otomatis. Selain itu, update()metode ini mengembalikan jumlah contoh survei yang terpengaruh oleh pembaruan Anda.


2
Terima kasih. Saya mencobanya dengan .getalih - alih .filterdan ini tidak berhasil. Tetapi dengan filter itu berfungsi dengan baik. Tahukah Anda apa yang salah dengan kode saya di atas?
Pengguna Terdaftar

Masalah Anda mungkin terkait dengan question_id. Dari mana asalnya nilai ini? Dan baris mana yang menaikkan IntegrityError?
pemistahl

question_idberasal dari url (?P<question_id>\d+). Kesalahan saya adalah bahwa pada server kerja, django 1.4 diinstal dan kode saya 1.5. Tetapi dengan kode Anda, itu berfungsi dengan baik.
Pengguna Terdaftar

2
@RegisteredUser, sepertinya tidak ada metode "update" pada objek, hanya pada queryset. Saat Anda menggunakan .filter (), Anda mendapatkan queryset (menahan nol atau lebih objek) kembali. Saat Anda menggunakan .get () Anda mendapatkan satu objek.
mgojohn

Secara default, memanggil save()(@Alasdair solution) adalah solusi yang lebih aman, karena metode ini dapat memicu hal-hal seperti validasi, atau kode kustom apa pun, daripada yang update()tidak.
David D.
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.