我有一个模型,我想知道是否可以设置触发模型字段更改的条件。例如,我有一个模型
class BillboardTracker(models.Model):
client_name = models.CharField(max_length=400)
entry_date = models.DateTimeField(default=datetime.now)
duration = models.PositiveIntegerField()
expiry_date = models.DateField()
is_expired = models.BooleanField(default=False)
我想知道是否有可能在模型中有一个函数,当失效日期结束时,is_expired等于True。我试过这个
def expire(self):
if datetime.now == self.expiry_date:
self.is_expired = True
但它不起作用。有可能实现这个吗?
答案 0 :(得分:10)
这里最简单的事情就是根本没有过期的字段!这不是必需的。你需要的是一个财产。
class BillboardTracker(models.Model):
client_name = models.CharField(max_length=400)
entry_date = models.DateTimeField(default=datetime.now)
duration = models.PositiveIntegerField()
expiry_date = models.DateField()
@property
def is_expired(self):
if datetime.now > self.expiry_date:
return True
return False
请记住,如果该字段与具有简单计算的另一个字段相同,则数据库中没有字段。这会自动消除您必须将项目标记为已过期的头痛。
如果您想知道对象是否已过期。
if instance.is_expired == True:
print 'yes, that ones gone'
如果您想要检索一整套已过期的对象
BillboardTracker.objects.filter(expiry_date__le=datetime.now())
这就是我提到您不需要存储可以轻松计算的字段的原因。
在大多数RDBMS中,无法有效地索引布尔字段(例如is_expired列)。所以这实际上意味着如果你在expiry_date字段上创建一个索引,上面的查询将比那个布尔字段上的查询更快。
答案 1 :(得分:1)
您需要在此功能中进行两项更改, 首先使用 datetime.now(),然后使用
您可能希望像这样更新逻辑:
def expire(self):
if datetime.now() >= self.expiry_date:
self.is_expired = True
return True
else:
return False
因为有时两个值可能不完全相同,但仍然 BillboardTracker 需要is_expired =所有之前日期的True。
在你的意见中:
def your_view(request):
instance = BillboardTracker.objects.get(id=some_id)
if instance.is_expired() == True:
print 'expired'
else:
print 'fresh'