如何在 Django 中每个月从 True 到 False 后更改为 BooleanField?
How to change to BooleanField after True to False every month in Django?
Info:当我创建一个新客户时,我想将 pending_customer
设置为 True,我将其设置为默认值 True,因此它工作正常并且在一个月后 pending_customer
自动设为false。
我也尝试制作函数 get_pending_customer
谁能做到我知道这不是我想做的事情。这就像一个基于任务的函数,它会在一个月后自动使 pending_customer
字段为真为假。我想知道我该怎么做?
谁能告诉我最好的方法是什么?
models.py
from django.utils.timezone import datetime
class Customer(models.Model):
"""Customer Model"""
name = models.CharField(max_length=255)
phone = models.CharField(max_length=11)
created_on = models.DateTimeField(auto_now_add=True)
pending_customer = models.BooleanField(default=True)
"""Example""" # I know it's wrong way
def get_pending_customer(self):
today = datetime.date.today()
month = datetime.timedelta(30)
after_month = today + month
if after_month:
panding = self.object
panding.pending_payment = False
panding.save()
return today
我会建议你使用 custom-management-commands。
将你的代码写在一个 python 文件中,并在每天的特定时间将其放入 cron 到 运行。在程序中查找超过 30 天的对象并根据您的用例更新它们。
项目结构:
App_Name/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
update_old_data_moreover_30_days.py
tests.py
views.py
这是你的 update_old_data_moreover_30_days.py
文件:
from django.core.management.base import BaseCommand, CommandError
from App_Name.models import Customer
from datetime import datetime, timedelta
class Command(BaseCommand):
def handle(self, *args, **options):
Customer.objects.filter(created_on__lte=datetime.now()-timedelta(days=30)).update(pending_customer=False)
self.stdout.write('Updated customers older than 30 days')
如果用户注册时间少于 30 天,您可以使用布尔字段 True
来注释 QuerySet
,而不是安排任务。
您可以用 BooleanField
注释对象,这是条件的结果
ExpressionWrapper
[Django-doc]:
from datetime import timedelta
from django.db import models
from django.db.models import BooleanField, <b>ExpressionWrapper</b>, Q
from django.db.models.functions import Now
class CustomerManager(models.Model):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).annotate(
pending_customer=<b>ExpressionWrapper(</b>
Q(created_on__gte=Now()-timedelta(days=30)),
output_field=BooleanField()
<b>)</b>
)
在我们的模型中,因此可以省略pending_customer
字段,根据需要确定。该模型因此看起来像:
class Customer(models.Model):
"""Customer Model"""
name = models.CharField(max_length=255)
phone = models.CharField(max_length=11)
created_on = models.DateTimeField(auto_now_add=True)
# <em>no</em> pending customer field
# <s>pending_customer = models.BooleanField(default=True)</s>
objects = CustomerManager()
@classmethod
def get_pending_customers(cls):
cls.objects.filter(pending_customer=True)
然后我们可以访问 Customer.get_pending_customers()
的未决客户。
Info:当我创建一个新客户时,我想将 pending_customer
设置为 True,我将其设置为默认值 True,因此它工作正常并且在一个月后 pending_customer
自动设为false。
我也尝试制作函数 get_pending_customer
谁能做到我知道这不是我想做的事情。这就像一个基于任务的函数,它会在一个月后自动使 pending_customer
字段为真为假。我想知道我该怎么做?
谁能告诉我最好的方法是什么?
models.py
from django.utils.timezone import datetime
class Customer(models.Model):
"""Customer Model"""
name = models.CharField(max_length=255)
phone = models.CharField(max_length=11)
created_on = models.DateTimeField(auto_now_add=True)
pending_customer = models.BooleanField(default=True)
"""Example""" # I know it's wrong way
def get_pending_customer(self):
today = datetime.date.today()
month = datetime.timedelta(30)
after_month = today + month
if after_month:
panding = self.object
panding.pending_payment = False
panding.save()
return today
我会建议你使用 custom-management-commands。
将你的代码写在一个 python 文件中,并在每天的特定时间将其放入 cron 到 运行。在程序中查找超过 30 天的对象并根据您的用例更新它们。
项目结构:
App_Name/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
update_old_data_moreover_30_days.py
tests.py
views.py
这是你的 update_old_data_moreover_30_days.py
文件:
from django.core.management.base import BaseCommand, CommandError
from App_Name.models import Customer
from datetime import datetime, timedelta
class Command(BaseCommand):
def handle(self, *args, **options):
Customer.objects.filter(created_on__lte=datetime.now()-timedelta(days=30)).update(pending_customer=False)
self.stdout.write('Updated customers older than 30 days')
如果用户注册时间少于 30 天,您可以使用布尔字段 True
来注释 QuerySet
,而不是安排任务。
您可以用 BooleanField
注释对象,这是条件的结果
ExpressionWrapper
[Django-doc]:
from datetime import timedelta
from django.db import models
from django.db.models import BooleanField, <b>ExpressionWrapper</b>, Q
from django.db.models.functions import Now
class CustomerManager(models.Model):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).annotate(
pending_customer=<b>ExpressionWrapper(</b>
Q(created_on__gte=Now()-timedelta(days=30)),
output_field=BooleanField()
<b>)</b>
)
在我们的模型中,因此可以省略pending_customer
字段,根据需要确定。该模型因此看起来像:
class Customer(models.Model):
"""Customer Model"""
name = models.CharField(max_length=255)
phone = models.CharField(max_length=11)
created_on = models.DateTimeField(auto_now_add=True)
# <em>no</em> pending customer field
# <s>pending_customer = models.BooleanField(default=True)</s>
objects = CustomerManager()
@classmethod
def get_pending_customers(cls):
cls.objects.filter(pending_customer=True)
然后我们可以访问 Customer.get_pending_customers()
的未决客户。