I’ve written an abstract base class which groups together common fields for some of my tables. I would like to be able to query all of those fields in the same way, using a manager.
class TemporalModel(models.Model):
objects = models.Manager()
today = TodayManager()
time = models.DateTimeField()
class Meta:
abstract = True
get_latest_by = 'time'
One simple example of this, as shown above, is to be able to query subclasses of TemporalModel (which all have a ‘time’ field) for the entries today.
I thus wrote a manager:
class TodayManager(models.Manager):
def get_query_set(self):
now = timezone.now()
today = datetime(now.year, now.month, now.day, tzinfo=now.tzinfo)
tomorrow = today + timedelta(days=1)
qs = models.Manager.get_query_set(self).filter(time >= today)
qs = qs.filter(time < tomorrow)
return qs
Attempting to use this fails with a NameError (time not defined). I presume that this is for the same reason as in this question – the field is not on the abstract class, but rather on the subclass.
However, I’m never actually calling this on the abstract class. If I have something like the following:
class SomeTemporalThing(TemporalModel):
pass # I'm a real table! :)
then I want to be able to call, eg, SomeTemporalThing.today.all(), and have django perform the time >= today / time < tomorrow lookups on the child table.
Is it possible to achieve this without moving the manager definition to the child class (which would result in repetition)?
My reading of the custom manager documentation suggests that it should be possible, but I’m stumped as to how.
What you’re doing should be possible. The error you are seeing is not related to inheritance of the
Managerobjects, but rather an incorrect specification to thefilter()function of theQuerySet.Instead of
it should be
The same applies to your
time < tomorrowfilter parameter.See QuerySet API documentation.