Django从Manager访问模型属性

时间:2013-09-01 19:16:24

标签: django django-managers

我有以下型号:

class Hospitalization(models.Model):
    patient = models.ForeignKey(Patient)
    room = models.ForeignKey(Room)
    date_in = models.DateField()
    date_out = models.DateField(blank=True, null=True)
    ...

我想列出目前的住院治疗方案。所以我添加了一个@property'is_current':

@property
def is_current(self):
    today = date.today()
    if self.date_in and self.date_out:
        if self.date_in <= today and self.date_out >= today:
            return True
    if self.date_in and not self.date_out:
        if self.date_in <= today:
            return True

尝试从我的views.py中的过滤器调用属性时,我遇到以下错误:*无法将关键字'is_current'解析为字段。选择是:date_in,date_out,id,patient,room *

然后我想我可以和经理一起做这件事。所以我添加了一个经理:

class Hospitalization(models.Model):
    def get_query_set(self):
        today = date.today()
        if self.date_in and self.date_out:
            return qs.filter(date_in__lte=today, date_out__gte=today)
        if self.date_in and not self.date_out:
            return qs.filter(date_in__lte=today)

但这也不起作用:* AttributeError:'HospitalizationManager'对象没有属性'date_in'*

Django推荐的解决方法是什么?

1 个答案:

答案 0 :(得分:3)

您的Manager

存在各种问题
  • 您是Model的子类,而不是Manager
  • 您正在使用您的模型属性,就好像它们属于Manager,它们不是
  • 您的自定义get_queryset未调用超类方法,因此它使用的是未定义的qs属性。

定义经理的正确方法是:

class CurrentHospitalizationManager(models.Manager):
    def get_query_set(self):
        qs = super(CurrentHospitalizationManager, self).get_query_set()
        today = date.today()    
        return qs.filter(
            # we can use Q objects here to check if the date_out exists or not
            # and compare against the current date if necesary
            models.Q(date_out__isnull=True) | models.Q(date_out__gte=today),
            date_in__lte=today                
        )

然后您应该将经理分配给模型上的类属性,例如

class Hospitalization(models.Model):
    current_objects = CurrentHospitalizationManager()
    ...

并在你的代码中使用它:

Hospitalization.current_objects.get(...) # or filter, or whatever

我不建议您将此自定义管理器分配给默认管理器attr(objects),因为您将无法访问Hospitalization不是“当前”的实例。

Custom Manager's documentation