使用classmethod在Django中设置字段默认值
我在网上找到了很多关于这个话题的帖子,但没有人明确指出问题出在哪里。
代码
class Item(models.Model):
@classmethod
def get_next_item_number(cls):
return cls.objects.count() + 1
number = models.IntegerField(default=get_next_item_number)
问题
当我访问Django的管理面板时,和“数字”字段相关的文本框里显示了
<classmethod object at 0x7fab049d7c50>
所以我尝试修改上面的代码
class Item(models.Model):
@classmethod
def get_next_item_number(cls):
return cls.objects.count() + 1
number = models.IntegerField(default=get_next_item_number())
但是当我运行Django服务器时,我得到了:
number = models.IntegerField(default=get_next_item_number())
TypeError: 'classmethod' object is not callable
我知道通过把get_next_item_number()声明为一个外部函数可以避免这些问题,但对我来说这个解决方案不太优雅,因为get_next_item_number()只和Item类有关。
我是不是漏掉了什么解决方案?
2 个回答
0
重写你的 __init__
方法,在这里给你的 Item
类设置默认值,看看下面的代码:
from django.db import models
class Item(models.Model):
number = models.IntegerField()
@classmethod
def get_next_item_number(cls):
return cls.objects.count() + 1
def __init__(self, *args, **kwargs):
super(Item, self).__init__(*args, **kwargs)
if not self.pk and not self.number:
self.number = Item.get_next_item_number()
下面是运行结果的流程
>>> from your_app import models
>>> models.Item().save()
>>> models.Item().number
>>> 2
>>> models.Item().save()
>>> models.Item().number
>>> 3
>>> models.Item.objects.filter(id=1)[0].number #number only get its value from classmethod on new items
>>> 1
6
我找到了解决办法:
代码
class Item(models.Model):
@staticmethod
def get_next_item_number():
return Item.objects.count() + 1
number = models.IntegerField(default=get_next_item_number.__func__)
我对可能的后果不是很了解,但这个方法确实有效。