【问题标题】:How to change to BooleanField after True to False every month in Django?如何在 Django 中每个月从 True 到 False 后更改为 BooleanField?
【发布时间】:2021-10-03 18:58:07
【问题描述】:

信息:当我创建一个新客户时,我想将 pending_customer 设为 True,我将其设置为默认值 True,因此它工作正常,一个月后 pending_customer 自动设为 false。

我也尝试制作函数get_pending_customer 谁能做到我知道这不是我想做的方式。这就像一个基于任务的函数,它会在一个月后自动将 pending_customer 字段 True 变为 false。我想知道我该怎么做?

谁能告诉我最好的方法是什么?

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

【问题讨论】:

  • 一个月后是否需要将pending_customer重置为True?还是完全依赖于 created_on 字段??
  • @umair 我只想让 pending_customer 在一个月后得到 False。忽略这个 created_on 这是今天的日期
  • 请看看我的问题更新了!
  • 似乎你需要一个调度器和一个额外的字段,其中包含它应该被打开的日期
  • 是的,我需要调度器...

标签: django django-models django-rest-framework django-celery-beat


【解决方案1】:

我建议你使用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')

【讨论】:

    【解决方案2】:

    如果用户在不到 30 天前注册,您可以使用布尔字段 True 来注释 QuerySet,而不是安排任务。

    您可以使用 BooleanField 注释对象,这是带有 ExpressionWrapper [Django-doc]:

    from datetime import timedelta
    from django.db import models
    from django.db.models import BooleanField, ExpressionWrapper, 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=ExpressionWrapper(
                    Q(created_on__gte=Now()-timedelta(days=30)),
                    output_field=BooleanField()
                )
            )

    因此,在我们的模型中,我们可以省略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)
        # no pending customer field
        # pending_customer = models.BooleanField(default=True)
    
        objects = CustomerManager()
    
        @classmethod
        def get_pending_customers(cls):
            cls.objects.filter(pending_customer=True)

    然后我们可以通过Customer.get_pending_customers() 访问待定客户。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-18
      • 1970-01-01
      • 2020-11-25
      • 2017-11-05
      • 2011-07-08
      • 1970-01-01
      相关资源
      最近更新 更多