Reputation: 468
I have a Opening Times table, and I need to sort the items according to the "opening time", so it will show 'open now', and then 'closed now' items. But I can't filter by a model method.
models.py
class Company(ImageBaseModel):
class Meta:
verbose_name = _(u"Empresa")
verbose_name_plural = _(u"Empresas")
ordering = ('order',)
user = ForeignKey('auth.User', verbose_name=_(u"Responsável"), null=True, blank=True)
# Admin fields
slug = SlugField(verbose_name=_(u'Slug / URL'), blank=True, null=True)
order = PositiveIntegerField(verbose_name=_(u"Ordem"), null=True, blank=True)
def __unicode__(self):return u'%s'%self.title
def get_address(self):
if self.cep and self.address and self.city and self.number: return True
def isopen(self):
now = datetime.now()
nowTime = time(now.hour, now.minute, now.second)
ohs = self.opening_times.filter(company__slug=self.slug)
status = False
for oh in ohs:
is_open = False
# start and end is on the same day
if oh.weekday == now.isoweekday() and oh.fromHour <= nowTime and nowTime <= oh.toHour:
is_open = oh
# start and end are not on the same day and we test on the start day
if oh.weekday == now.isoweekday() and oh.fromHour <= nowTime and ((oh.toHour < oh.fromHour) and (nowTime < datetime.time(23, 59, 59))):
is_open = oh
# start and end are not on the same day and we test on the end day
if (oh.weekday == (now.isoweekday()-1)%7 and oh.fromHour >= nowTime and oh.toHour >= nowTime and oh.toHour < oh.fromHour):
is_open = oh
#print " 'Special' case after midnight", oh
if is_open is not False:
status = True
return status
def hasOt(self): #have opening times registry
return len(self.opening_times.all()[:1]) == 1
class OpeningHours(Model):
class Meta:
verbose_name = _(u"Horário de Abertura")
verbose_name_plural = _(u"Horários de Abertura")
unique_together = ('company', 'weekday')
company = ForeignKey(Company, related_name="opening_times", verbose_name=_(u"Empresa"))
weekday = IntegerField(choices=WEEKDAYS, verbose_name=_(u"Dia da Semana"))
fromHour = TimeField(verbose_name=_(u"Abre ás:"), null=True, blank=True)
toHour = TimeField(verbose_name=_(u"Fecha ás:"), null=True, blank=True)
def __unicode__(self):
return "%s %s (%s - %s)" % (self.company, self.weekday, self.fromHour, self.toHour)
views.py
def home(request):
companies = Company.objects.filter(published=True).order_by('opening_times')
food_companies = companies.all()[0:5] #here I'll have to filter only food companies open now.
I need to something like food_companies.order_by('open_now_first'), but I don't know how can I do that.
Upvotes: 0
Views: 47
Reputation: 25478
order_by
is applied at the database level (ie in the raw SQL) so you can't call a function with it. You can get all your food_companies
and sort them using isopen
as a key, though. Something like:
sorted_companies = sorted(food_companies.objects.all(),
key=lambda food_company: food_company.isopen())
Upvotes: 1