imkost
imkost

Reputation: 8163

Site menu using django

I want a menu on my web site. I want this menu to be editable via django admin. So, I need to create a model for it.

Once I've created model for my menu, I can use it in my views.py:

def main(request):
    menu_items = MenuItem.objects.all()
    return direct_to_template(request, 'main.html', {'menu_items': menu_items})

It is ok. But... wait a minute... If I have several pages, it will look like:

def main(request):
    menu_items = MenuItem.objects.all()
    return direct_to_template(request, 'main.html', {'menu_items': menu_items})

def page1(request):
    menu_items = MenuItem.objects.all()
    return direct_to_template(request, 'page1.html', {'menu_items': menu_items})

def page2(request):
    menu_items = MenuItem.objects.all()
    return direct_to_template(request, 'page2.html', {'menu_items': menu_items})`

Is there any way not to write the same code everytime I create new function?

Upvotes: 1

Views: 1537

Answers (2)

vutran
vutran

Reputation: 2175

Ok, Timmy suggested you a Django way and it works great. By the way, I know a pythonic way that you can use decorators like this:

def apply_menu(func):
    def wrapper(*args, **kwargs):
        request = args[0]
        menu_items = MenuItem.objects.all()
        vars = {'menu_items': menu_items}
        if kwargs:
            page, template_var = func(*args, **kwargs)
        else: page, template_var = func(*args)
        vars.update( template_var)
        return return direct_to_template(request, page, vars)
    return wrapper

And then use the decorator this way:

@apply_menu
def main(request):
    your_extra_vars = {}
    return 'main.html', your_extra_vars

Upvotes: 3

Timmy O'Mahony
Timmy O'Mahony

Reputation: 53971

Yep, create a context processor and your menu will be available on every page

Inside one of your apps create a file menu_context_processor.py (or similar)

from myapp.models import MenuItem
def menu(request):
    return {'menu': MenuItem.objects.all() }

and add it to your TEMPLATE_CONTEXT_PROCESSOR setting in settings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    ...,
    'myapp.menu_context_processor.menu'
)

and now, in every template, you will have access to {{ menu }}. These are used to make {{ STATIC_URL }} and `{{ MEDIA_URL }}' available to you throughout your application and are useful for variables you want to include everywhere.

Upvotes: 8

Related Questions