首页 > 解决方案 > 如何在 Django 的 shell 中更新模型的属性值?

问题描述

我有一个这样的模型:

class Territory(models.Model):
    voivodeship = models.IntegerField(null=True, blank=True)
    powiat = models.IntegerField(null=True, blank=True)
    gmina = models.IntegerField(null=True, blank=True)
    type = models.IntegerField(null=True, blank=True)
    name = models.CharField(max_length=500)
    type_name = models.CharField(max_length=100)
    comparison_group = models.ForeignKey(ComparisonGroup, on_delete=models.SET_NULL,
                                         related_name='territories', null=True, blank=True)
    partnership = models.ForeignKey(Partnership, on_delete=models.SET_NULL,
                                    related_name='member_territories', null=True, blank=True)

    class Meta:
        unique_together = ('voivodeship', 'powiat', 'gmina', 'type')
        verbose_name = 'Jednostka terytorialna'
        verbose_name_plural = 'Jednostki terytorialne'

    def __str__(self):
        return f'{self.name} - {self.type_name} ({self.code})'

    @property
    def code(self):
        if self.voivodeship and self.powiat and self.gmina and self.type:
            return f'{self.voivodeship:02}{self.powiat:02}{self.gmina:02}{self.type}'
        return '--'

现在,其中一些领土的code属性为--, 因为self.gmina并且self.type在数据库中为 NULL。然后我更新了一些行——为一些地区单位添加了值self.gminaself.type我想更新它们的code属性。我试过:

territories = Territory.objects.filter(type_name='some type name')
for t in territories:
    t.code = <some calculated value>

但我得到一种错误:

Traceback (most recent call last):
  File "<console>", line 3, in <module>
AttributeError: can't set attribute

如何让 Djangocode为 Territory 模型中的所有项目重新计算此值?

标签: python-3.xdjangodjango-models

解决方案


Django 只会在必要时查询数据库,因此会保留查询或模型实例的结果,直到它们从数据库中更新。为此,请再次运行查询并重新分配模型实例或使用方法刷新模型Model.refresh_from_db()

code 属性没有存储在数据库中,它是在方法调用期间动态计算的。要重新评估其结果,您必须调用该属性而不是分配给它。发生错误是因为您正在为类属性分配值。

territories = Territory.objects.filter(type_name='some type name')
for t in territories:
   print(t.code)  # Updated code property
   print(t)       # Updated __str__() call

推荐阅读