开发者

How do I access unrelated models within a Django template?

I want to use an app to create a menu that is easy to edit with the admin interface. Something like this:

class Menu_item
        name = models.CharField()
        item_url = models.URLField()

My template looks something like this:

{% extends base.html %}

div ID="nav"

   {{ foo.navbar.? }}

/div

div ID="Content"

   {% block content %}{% endblock %}

/div

I want div#nav to contain a ul based upon the above model but just can't figure out how to accomplish this. It seems like an object_list generic view would be great but, the URL accesses the view for the model that populates div#content. Does anyo开发者_如何学Cne have any suggestions? Is there a way to access a generic view without a URL?

Thank you.


I have discovered a solution. Inclusion Tags.

What I did was create an inclusion tag, which amounts to a simple custom template tag (django provides a shortcut for you!).

Here is what I did:

  • Ignore views.py - It will not be used in this case
  • Create a sub-directory in the app's dir called "templatetags" containing init.py and get_navbar.py (or whatever you want your tag to be):

    mysite/
       navbar/
            templatetags/
                __ init__.py (without the space befire init)
                get_navbar.py
    
  • I changed my navbar.models to look like this:

    from django.db import models
    
    
    class Menu_choice(models.Model):
            name = models.CharField(max_length=30)
    
            def __unicode__(self):
                    return self.name
    
    class Menu_item(models.Model):
            name = models.CharField(max_length=20)
            navbar = models.ForeignKey(Menu_choice)
            item_url = models.CharField(max_length=200)
            item_desc = models.CharField(max_length=30)
    
            def __unicode__(self):
                    return self.name
    

    This allows me to create a Menu_choice object in the admin interface for each layer of navigation (primary, secondary, etc)

  • get_navbar.py looks like this:

    from navbar.models import Menu_choice, Menu_item
    from django import template
    
    register = template.Library()
    
    @register.inclusion_tag('navbar/navbar.html')
    def get_navbar(navBar):
            navbar = Menu_item.objects.filter(navbar__name=navBar)
            return { "navbar": navbar }
    

    (Note navBar as opposed to navbar)

  • Create the navbar.html template:
        <ul>
    {% for menu_item in navbar %} <li><a href="{{ menu_item.item_url }}">{{ menu_item.name }}&lt/a>&lt/li> {% endfor %} </ul>
  • Finally, I inserted the following into my base.html:
    {% load get_navbar %}

    And where I want primary navigation:

    {% get_navbar "primary" %}

    Note: the quotes around the string you are sending to your inclusion tag are important. I spent a ridiculously lengthy bit of time trying to make it work before I figured that out.

    Also a big thank you to dikamilo for the help.


    First, in you view, get data from db:

    def index(request):
        navbar = Menu_item.objects.all()
        return render_to_response( 'you_template.html', 
            { 'navbar': navbar }, context_instance = RequestContext (request ) )
    

    And in template:

    <div id="nav">
        <ul>
        {% for i in navbar %}
            <li><a href="{{ i.item_url }}">{{ i.name }}</a></li>
        {% endfor  %}
        </ul>
    </div>
    
  • 0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新问答

    问答排行榜