Оновіть лише конкретні поля в моделях. Модель


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.

Я правильно з цим методом для оновлення?

Відповіді:


186

Щоб оновити підмножину полів, ви можете використовувати 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походить з URL-адрес (?P<question_id>\d+). Моєю помилкою було те, що на робочому сервері встановлено django 1.4 і мій код - 1,5. Але з вашим кодом це працює нормально.
Зареєстрований користувач

2
@RegisteredUser, схоже, немає методу "оновлення" на об'єктах, лише на наборах запитів. Коли ви використовуєте .filter (), ви отримуєте набір запитів (утримуючи нуль або більше об’єктів) назад. Коли ви використовуєте .get (), ви отримуєте один об’єкт.
mgojohn

За замовчуванням виклик save()(@Alasdair рішення) є більш безпечним рішенням, оскільки цей метод може викликати такі речі, як перевірка чи будь-який власний код, ніж update()ні.
Девід Д.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.