在Django DateField上查询以更改搜索日期

72qzrwbm  于 12个月前  发布在  Go
关注(0)|答案(2)|浏览(112)

我在Django中有一个表示一周的模型。我想让某人输入任何日期并让模型自动保存本周的开始。这很简单,只需覆盖保存。

class Week(models.Model):
  start_date = models.DateField()
  
  def save(self):
    self.start_date = self.start_date - datetime.timedelta(days=date.weekday())

字符串
但我也希望有人能够查询任何一天,并获得周。例如,我希望有人这样做:

this_week = Week.objects.filter(start_date=date.today())


其中今天是星期三,并获取week对象,其中日期被设置为一周的开始。它需要对任何日期起作用,而不仅仅是今天。
我知道我们可以在管理器中覆盖get_queryset,但是有没有一种方法可以编辑实际搜索的内容?我能找到的每个管理器示例都只是以静态方式更改了queryset。或者我最好的选择是尝试子类化DateField?
(Note上面的代码是输入的,简化的,可能包含错误,但它在我的实际代码中工作)

vzgqcmou

vzgqcmou1#

我们可以将DateField子类化为每次清除一周开始的日期时间。这看起来像:

from django.db.models.fields import DateField
from datetime import timedelta

class WeekField(DateField):
    def to_python(self, value):
        value = super().to_python(value)
        if value is not None:
            value -= timedelta(days=value.weekday())
        return value

字符串
然后我们可以用WeekField来创建、过滤等。例如,我们可以在Week模型中指定这一点:

class Week(models.Model):
    week = WeekField()


然后使用.get_or_create(…)

>>> from datetime import date
>>> Week.objects.get_or_create(week=date.today())
(<Week: Week object (1)>, True)
>>> Week.objects.get_or_create(week=date.today())
(<Week: Week object (1)>, False)


筛选周数:

>>> Week.objects.filter(week=date(2021, 8, 31))
<QuerySet [<Week: Week object (1)>]>
>>> Week.objects.filter(week=date(2021, 8, 2))
<QuerySet []>


看看本周开始的.values()

>>> Week.objects.values()
<QuerySet [{'id': 1, 'week': datetime.date(2021, 8, 30)}]>


我没有广泛地测试这个,但我想大部分功能都涵盖了。

55ooxyrt

55ooxyrt2#

在数据库级别,可以根据start_date进行排序,而不是默认的primary_key

class Week(models.Model):
  start_date = models.DateField()

  class Meta:
    ordering = ['start_date']

字符串
从这里,它是相当直接向前得到你正在寻找的一周。

week = Week.objects.filter(start_date__lte=date.today()).first()


使用Meta的替代方法是在查询中简单地使用order_by

week = Week.objects.filter(start_date__lte=date.today()).order_by('start_date').first()

相关问题