I have a Django model for an object with a DateField. I also have two managers that filter these objects for a specific date range.
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()
My first manager (SchoolYearManager) works as expected to return events within that date range. But when I try to do Event.past_school_year_events.all(), I get an Attribute error: “type object ‘Event’ has no attribute ‘event_date'”.
My goal with the second manager (PastSchoolYearEvents) is to wrap a generic year archive view to return events within a date range for a specific year.
Why can’t I call self.model.event_date within the manager?
Am I going about this the right way? If not, what’s the better way to do this?
How could this work? What event date could it be referring to? When you call
Event.past_school_year_events.all(), you don’t have a model instance.self.model, as the name implies, refers to the model class. So how could it know what date you mean?I can’t actually work out what it is you’re trying to do – where you are going to get the date from. Do you want to start from an event, then get all the other events in the same year as that one? In which case, I suspect you just want to make
past_school_year_eventsinto a model method, not a manager.Edit If you want to start from a specific year, a manager certainly is appropriate, but you’ll need to pass the year into your manager method as a parameter. For this, I’d use a separate method on the manager, rather than overriding
get_query_set– in fact, add another method toSchoolYearManager:Now you’ve got just one manager, that doesn’t override
get_query_set, so you don’t even need to preserve the default one – you can keep this one asobjects. So you can do: