我正在一个项目中,我正在接受用户付款。到期日是自付款日起30天。最初,is_due字段为false,但是我希望将其更改为true,而不是在截止日期只有7天时手动更新。即使到处查找,我也没有解决办法。
模型
class Payment(models.Model):
username = models.ForeignKey(UserProfile,on_delete = models.CASCADE, related_name='name')
amount = models.IntegerField()
date = models.DateField(blank=False, default = datetime.datetime.now())
due_date = models.DateField()
payment_mode = models.CharField(max_length=50, choices=PaymentModes,null=True,blank=True)
collected_by = models.ForeignKey(UserProfile,on_delete = None, related_name='collected_by')
is_due = models.BooleanField(default = False)
def __str__(self):
return self.username.user.username
def save(self, *args, **kwargs):
self.due_date = self.date + monthdelta(1)
dt = self.due_date-datetime.date.today()
if dt.days <=7:
self.is_due = True
else:
self.is_due = False
super(Payment, self).save(*args, **kwargs)
答案 0 :(得分:2)
安排任务以更新行通常不是一个好主意,因为这不是一个非常可靠的解决方案。如果计划内存中的任务,则服务器的重新启动将导致不触发计划的任务。您可以使用 celery 之类的工具来使用“持久”计划的任务,但这需要花一些精力来设置它,而且两种解决方案都不“精确”:在任务执行之前可能要花一些额外的时间被触发。
将due_date
设置为date
并保留一个月可能同样适用:您这里有重复数据,这往往很糟糕。如果due_date
始终是date
,又多了一个月,则您正在浪费磁盘空间。此外,save()
函数不会总是触发:例如,如果您批量更新,Django将绕过 save函数,因此您的数据可能不一致。
处理此问题的最简单方法是注释查询集,例如在管理器中:
from django.db.models import BooleanField, ExpressionWrapper, Q
import datetime
from datetime import date, timedelta
class PaymentManager(models.Manager):
def get_queryset(self):
return super().get_queryset().annotate(
is_due=ExpressionWrapper(
Q(due_date__lt=datetime.date.today()-timedelta(days=7)),
output_field=BooleanField()
)
)
class Payment(models.Model):
username = models.ForeignKey(UserProfile,on_delete = models.CASCADE, related_name='name')
amount = models.IntegerField()
date = models.DateField(blank=False, default=date.today)
due_date = models.DateField()
payment_mode = models.CharField(max_length=50, choices=PaymentModes,null=True,blank=True)
collected_by = models.ForeignKey(UserProfile,on_delete = None, related_name='collected_by')
objects = PaymentManager()
def __str__(self):
return self.username.user.username
def save(self, *args, **kwargs):
self.due_date = self.date + monthdelta(1)
super(Payment, self).save(*args, **kwargs)
请注意,您的date = DateField(..)
的默认值应该为date.today
,而不是 ,因为通过调用它,它将将启动服务器的日期(而不是创建日期)设置为默认日期。date.today()