Bir modeldeki yalnızca belirli alanları güncelleyin.


92

Bir modelim var

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

ve şimdi sadece activealanı güncellemek istiyorum . Ben de şunu yapıyorum:

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

Şimdi bir hata alıyorum IntegrityError: PRIMARY KEY must be unique.

Bu yöntemi güncellemek için haklı mıyım?

Yanıtlar:


187

Alanların bir alt kümesini güncellemek için şunları kullanabilirsiniz update_fields:

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

update_fieldsBağımsız değişken Django 1.5 ilave edildi. Önceki sürümlerde, update()bunun yerine yöntemi kullanabilirsiniz :

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

17

Genellikle, bir veya daha fazla model örneğindeki belirli alanları güncellemenin doğru yolu, update()yöntemi ilgili sorgu kümesinde kullanmaktır. Sonra şöyle bir şey yaparsınız:

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

Bu şekilde, save()otomatik olarak kaydedildiği için artık modelinizi aramanıza gerek kalmaz . Ayrıca update()yöntem, güncellemenizden etkilenen anket örneklerinin sayısını da döndürür.


2
Teşekkürler. Onun .getyerine denedim .filterve bu işe yaramıyor. Ancak filtre ile iyi çalışıyor. Yukarıdaki kodumda neyin yanlış olduğunu biliyor musunuz?
Kayıtlı Kullanıcı

Sorununuz ile ilgili olabilir question_id. Bu değer nereden geliyor? Ve hangi tam çizgi yükseliyor IntegrityError?
pemistahl

question_idurl’lerden gelir (?P<question_id>\d+). Benim hatam, çalışan sunucuda django 1.4 kurulu olması ve benim kodum 1.5 olmasıydı. Ancak kodunuzla iyi çalışıyor.
Kayıtlı Kullanıcı

2
@RegisteredUser, nesnelerde "güncelleme" yöntemi yok gibi görünüyor, sadece sorgu kümelerinde. .Filter () kullandığınızda, bir sorgu kümesi (sıfır veya daha fazla nesneyi tutan) geri alırsınız. .Get () kullandığınızda tek bir nesne elde edersiniz.
mgojohn

Varsayılan olarak, save()(@Alasdair çözümü) çağırmak daha güvenli bir çözümdür, çünkü bu yöntem doğrulama veya herhangi bir özel kod gibi şeyleri tetiklemediğinden daha tetikleyebilir update().
David D.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.