python - 如何访问自定义管理器中的模型属性?

标签 python django django-models filter

我有一个带有 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) 的目标是包装通用年份存档 View 以返回特定年份的日期范围内的事件。

为什么我无法在管理器中调用 self.model.event_date

我的处理方式正确吗?如果没有,更好的方法是什么?

最佳答案

这怎么行?它可能指的是哪个事件日期?当您调用 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,因此您甚至不需要保留默认管理器 - 您可以将其保留为对象。所以你可以这样做:

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

关于python - 如何访问自定义管理器中的模型属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7967476/

相关文章:

Python子进程仅将stdout Popen到变量

javascript - 每 10 秒翻转一次表格

python - Django 管理表单可以使用跨站请求伪造 (CSRF) 进行操作

python - 创建一个新模型,其中包含当前现有模型的所有字段

python - 在 Django 中使用这种多对多关系之前,对象需要具有字段 "id"的值

python - 如何像 Django 存储用户一样在 Django 的后端 session 中存储对象

python 请求从浏览器或 urllib 返回不同的网页

python - 在 Python 中将 XML/HTML 实体转换为 Unicode 字符串

django - 如何将django身份验证与react-router集成?

django - 最佳实践: Django multilanguage