I have a model that allows my client to create menus for his restaurant. Everything works great except I would like to set the explicit ordering by the string value of a model. For instance; he is creating sections like Salads, Pastas, Pizzas etc.. but they are displayed through the template in the order they are added to the system. How can I add a sort to my query that I can set the order manually? Below is my current snippet.
I am using Django 1.10.5, Wagtail 1.9, Python 3.5x
@register.inclusion_tag('tags/_lunch-menu-list.html', takes_context=True)
def lunch_products(context):
sections = Section.objects.all().prefetch_related('product').filter(product__lunch_menu=True).distinct()
return {
'sections': sections,
'request': context['request'],
}
I don't think Django queryset has a mechanism to order by a list of field value.
Option 1:
Order in Python. Keep it mind it will return a list, not a queryset anymore (inspired from this answer) and that you end up using magic strings (what if the user uses Entrées
instead of Starters
?):
sections = Section.objects.all()
order = ['Starters', 'Salads', 'Desserts']
order = {key: i for i, key in enumerate(order)}
ordered_sections = sorted(sections, key=lambda section: order.get(section.name, 0))
Option 2:
Add a menu_order
integer field on the Section
object and order_by
on this field. This is not the best UX though since you'll need to edit each section to set the order and will have to remember what number you've used for each of them.
Option 3:
Create a Menu
object with orderable sections (see how they order carousel item in the demo app), but this looks a bit overkill for you since it seems you will always ever have 1 order.