如何将对象的 pk 作为整数?

How to have an object's pk as an integer?

我有这个型号:

class Class(models.Model):
    class_id = models.IntegerField(blank=False)

    def save(self, *args, **kwargs):
        self.class_id = self.pk+1000
        super(Class, self).save(*args, **kwargs)

如您所见,我希望将 pk 添加到 1000 并将其用作 class_id 值。但是我得到这个错误:

TypeError at /new-class

unsupported operand type(s) for +: 'NoneType' and 'int'

如何将 pk 设为整数?

您收到此错误是因为在您将实例保存到数据库之前 ID 是 None。

无论如何,如果这个值始终是 id + 1000,为什么还要将它存储到数据库中?您可以改用 属性。我会推荐这个解决方案,因为它不需要对数据库进行任何更改,并且如果需求发生变化,以后很容易重构。

class Class(models.Model):

    @property
    def class_id(self):
        return self.pk and self.pk + 1000

使用 属性 的替代方法是查询集 annotation

from django.db.models import F
qs = Class.objects.annotate(class_id=F('pk') + 1000)
qs.get(id=42).class_id  # model instance attribute with value 1042

如果要使用原来的方法,必须修改保存方法。

def save(self, *args, **kwargs):
    if self._state.adding:
        # save once to get a id
        super().save(*args, **kwargs)
    self.class_id = self.pk + 1000
    super().save(*args, **kwargs)

pk 一个整数,但它在创建模型之前不会被设置,因为它来自数据库中的序列。

您还可以使用布尔值 self._state.adding 来确定模型是否已经创建。