模型中的字段在objects.filter()内为'undefined

0 投票
1 回答
659 浏览
提问于 2025-04-18 06:02

在我的模型中,有一个叫做 'expire_date' 的日期字段。我有一个函数用来查询我的模型:

def date_delta_days(earlier_date, later_date):
    return (later_date - earlier_date).days

class Command(BaseCommand):
    help = """ Manages list expiration.  If lists are expiring soon, sends an email warning the list owners
               If a list has expired, the .pck file associated with that list is deleted
           """

    def handle(self, *args, **options):
        now = datetime.now()
        expiring_lists = ListEntry.objects.filter(
            date_delta_days(now, expire_date) # <------ error is on this line
        )

当我这样写的时候,出现了一个语法错误,提示说 expiration_date 无法识别,尽管它在我的 ListEntry 模型中已经定义了。这里面是不是有什么我遗漏的呢?这看起来在 SQL 中写起来应该是个简单的查询。

这是我的模型定义:

class ListEntry(models.Model):
    name = models.CharField(max_length=64)
    # active_date = models.DateTimeField('date of last list activity')
    expire_date = models.DateField('date of expiration')
    create_date = models.DateField('date created')


    class Meta:
        ordering = ('name',)

这是相关的错误代码:

File "/home/jared/projects/list_expiration/list_app/management/commands/check_lists.py", line 19, in handle
    date_delta_days(now, expire_date)
NameError: global name 'expire_date' is not defined

1 个回答

2

在你的过滤器中,你传递了一个位置参数——可能是一个时间差(timedelta),这个时间差是从time_delta_days函数返回的。在那个函数里,你使用了两个变量:一个是通过datetime.datetime.now()获取的当前时间对象,还有一个……这就是你问题的根源。你传递了一个叫expiration_date的变量,但在那个时候它可能还没有定义。

你可能想要做的是使用命名参数,因为filter()函数是这样工作的。由于日期时间字段是可以比较的,你可以使用__gt__lt这些关键词(还有其他支持的逻辑运算符)。你想要找到那些在未来30天内会过期的ListEntry对象,那么你可以使用:

month_from_now = datetime.datetime.now() + datetime.timedelta(days=30)
ListEntry.objects.filter(expiration_date__lt=month_from_now,
                         expiration_date__gt=datetime.datetime.now())

我添加了第二个过滤参数,以确保你不会查看那些已经过期的ListEntry对象。你可以很容易地根据自己的需要调整这段代码。

撰写回答