【问题标题】:How to access model attributes in custom manager?如何在自定义管理器中访问模型属性?
【发布时间】:2017-07-12 23:07:23
【问题描述】:

我有一个带有 DateField 的对象的 Django 模型。我还有两个管理器在特定日期范围内过滤这些对象。

class SchoolYearManager(models.Manager):
    def get_query_set(self):
        now = datetime.datetime.now()
        current_year = now.year
        start_date = datetime.date(current_year, 7, 1)
        end_date = datetime.date((current_year + 1), 6, 30)
        return super(SchoolYearManager, self).get_query_set().filter(status=self.model.LIVE).filter(event_date__range=(start_date, end_date))

class PastSchoolYearManager(models.Manager):
    def get_query_set(self):
        current_year = self.model.event_date.year
        start_date = datetime.date(current_year, 7, 1)
        end_date = datetime.date((current_year + 1), 6, 30)
        return super(PastSchoolYearManager, self).get_query_set().filter(status=self.model.LIVE).filter(event_date__range=(start_date, end_date))

class Event(models.Model):
    LIVE = 3
    DRAFT = 4
    STATUS_CHOICES = (
        (LIVE, 'Live'),
        (DRAFT, 'Draft'),
    )
    status = models.IntegerField(choices=STATUS_CHOICES, default=4, help_text="Only entries with a status of 'live' will be displayed publically.")
    event_date = models.DateField()

    objects = Models.Manager()
    school_year_events = SchoolYearManager()
    past_school_year_events = PastSchoolYearManager()

我的第一位经理 (SchoolYearManager) 按预期返回该日期范围内的事件。但是当我尝试做Event.past_school_year_events.all() 时,我得到一个属性错误:“type object 'Event' has no attribute 'event_date'”。

我与第二个经理 (PastSchoolYearEvents) 的目标是包装通用年份存档视图以返回特定年份的日期范围内的事件。

为什么我不能在经理内拨打self.model.event_date

我这样做是否正确?如果没有,有什么更好的方法来做到这一点?

【问题讨论】:

    标签: python django django-models filter


    【解决方案1】:

    这怎么可能?它指的是哪个活动日期?当您调用Event.past_school_year_events.all() 时,您没有模型实例。 self.model,顾名思义,就是模型类。那么它怎么会知道你的意思是什么日期呢?

    我实际上无法弄清楚您要做什么 - 您将从哪里获得日期。你想从一个事件开始,然后在同一年获得所有其他事件吗?在这种情况下,我怀疑您只是想将past_school_year_events 变成模型方法,而不是管理器。

    编辑如果您想从特定年份开始,经理当然是合适的,但您需要将年份作为参数传递到您的经理方法中。为此,我会在管理器上使用单独的方法,而不是覆盖 get_query_set - 事实上,向 SchoolYearManager 添加另一个方法:

    class SchoolYearManager(models.Manager):
        def live_events(self, start_date, end_date):
           return self.filter(status=self.model.LIVE).filter(event_date__range=(start_date, end_date))
    
        def this_year(self):
            now = datetime.datetime.now()
            current_year = now.year
            start_date = datetime.date(current_year, 7, 1)
            end_date = datetime.date((current_year + 1), 6, 30)
            return self.live_events(start_date, end_date)
    
        def from_year(self, year):
            start_date = datetime.date(year, 7, 1)
            end_date = datetime.date(year+1, 6, 30)
            return self.live_events(start_date, end_date)
    

    现在您只有一位经理,它不会覆盖 get_query_set,因此您甚至不需要保留默认一位 - 您可以将其保留为 objects。所以你可以这样做:

    Event.objects.this_year()  # all this year's events
    Event.objects.from_year(2010) # all events from 2010
    

    【讨论】:

    • 我明白你的意思。我的目标是选择一个特定的年份,并将其插入我的范围过滤器的开始和结束日期。然后,我想使用通用年份存档视图显示这些事件对象。如果经理不合适,我将如何使用方法做到这一点?
    • 有道理。因此,为了符合我使用通用年份存档视图的目标,我将如何将年份作为整数传递?例如,在我看来,这是我的查询集:return Event.objects.from_year(self.get_year()).order_by('event_date')。当我需要一个整数时,这将返回一个字符串。
    • 实际上,我相信我已经解决了最后一个问题。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    相关资源
    最近更新 更多