Question

I've got following model:

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

I'd like to list the current Hospitalizations. So I added a @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

When trying to call the property from a filter in my views.py however, I get following error though: *Cannot resolve keyword 'is_current' into field. Choices are: date_in, date_out, id, patient, room*

Then I thought I could do this with a Manager. So I added a Manager:

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)

But that doesn't work either: *AttributeError: 'HospitalizationManager' object has no attribute 'date_in'*

What would be the Django recommended way to fix this?

Was it helpful?

Solution

There are various things wrong with your Manager:

  • You're subclassing Model, not Manager.
  • You're using your model attributes as if they belonged to the Manager, which they don't.
  • Your custom get_queryset isn't calling the superclass method, so it's using an undefined qs attribute.

The correct way to define your manager would be:

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                
        )

Then you should assign the manager to a class attribute on your model, like this

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

And use it on your code like this:

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

I don't recommend you assign this custom manager to your default manager attr (objects), since you wouldn't be able to access the Hospitalization's instances that aren't "current".

Custom Manager's documentation

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top