Как обновить свойство экземпляра модели как внешний ключ другой модели

У меня следующая ситуация. У меня есть модель Django, которая включает ссылку на другой класс, например:

class Document(models.Model):

    document = models.FileField(upload_to=user_file_path)
    origin = models.CharField(max_length=9)
    date = models.DateField()
    company = models.ForeignKey(Company, on_delete=models.CASCADE)

Компания включает свойство под названием status. В другой части кода я работаю с документом типа Document и хочу обновить свойство status компании внутри документа, поэтому я делаю следующее:

doc.company.status = new_value
save.doc()

или

setattr(company, 'status', new_value)
save.company()

В первом случае значение doc.company.status обновляется, но при запросе компании сохраняется старое значение, а во втором случае все наоборот, значение company.status обновляется, но doc.company.status сохраняет старое значение. Я всегда полагал, что обновление любого из них (doc.company или company) имеет немедленный эффект на другой, но теперь кажется, что doc имеет копию company (или какую-то ленивую связь, которую трудно предугадать), и оба остаются отдельными, и оба они должны быть обновлены, чтобы изменить значение. Альтернативный вариант, который, похоже, работает (сохраняя doc.company вместо doc):

doc.company.status = new_value
doc.company.save()

Похоже, что новое значение для статуса не распространяется мгновенно на компанию, но да, когда оно требуется в запросе или операции. Может ли кто-нибудь объяснить точную взаимосвязь или способ выполнения или дать ссылку, где я могу найти правильные объяснения? Спасибо

Установка атрибута экземпляра объекта изменяет только атрибут этого экземпляра. После использования save() значение сохраняется в базе данных.

Если ранее были определены переменные того же экземпляра, они останутся прежними. То есть, пока вы не вызовете refresh_from_db()метод.

Рассмотрим следующий сценарий:

company_var1 = Company.objects.get(pk=13)
company_var2 = Company.objects.get(pk=13)

company_var1.status = new_value  # This only changes the attribute on the model instance
print(company_var1.status)  # Output: new value
print(company_var2.status)  # Output: old value

company_var1.save()  # This updates the database table
print(company_var1.status)  # Output: new value
# Note how the company_var2 is still the same even though
# it refers to the same DB table row (pk=13).
print(company_var2.status)  # Output: old value

# After doing this company_var2 will get the values from the DB
company_var2.refresh_from_db()
print(company_var1.status)  # Output: new value
print(company_var2.status)  # Output: new value

Надеюсь, это прояснит ситуацию, и вы сможете применить это к своему случаю.

Вернуться на верх