Davey Browne
Davey Browne

Reputation: 35

Django importing Models from template

In my django project, I have a base.html from which all my templates {% extends 'base.html' %}. In that base template I want to do this to a list of all my algorithms.

{% for algorithm in algorithms %}
   # list them out as links in nav bar
{% endfor %}

But I'm not passing algorithms to the base since it's just extending other templates.

I don't know how to solve this. My thought was to use {% load %} in the base template which would basically.

from algorithms.models import Algorithm
from django import template


register = template.Library()

def GetAlgorithmObjects():

  a = Algorithm.objects.all()

  return {'algorithms': a}

I'm not sure of how load works which would explain this failure. How would you actually implement this or should I go a different path.

Upvotes: 3

Views: 4311

Answers (2)

VStoykov
VStoykov

Reputation: 1740

You can make it with inclusion tag https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#inclusion-tags

In your app algorithms create directory templatetags and put a file in it named algorithms_tags.py (of course in this directory there must be a file named __init__.py)

Then the content of the file is similar to what you wrote:

from algorithms.models import Algorithm
from django import template

register = template.Library()

@register.inclusion_tag('algorithms/show_algorithms.html')
def show_algorithms():
    a = Algorithm.objects.all()
    return {'algorithms': a}

Then you need a template located at algorithms/templates/algorithms/show_algorithms.html with the following content:

{% for algorithm in algorithms %}
   # list them out as links in nav bar
{% endfor %}

You can use it in your base.html as follows:

{% load algorithms_tags %}

{% show_algorithms %}

Some explanations:

  • In {% load algorithms_tags %} "algorithms_tags" is the name of the .py file created in the templatetags directory (without the extension)
  • In {% show_algorithms %} "show_algorithms" is the name of the function decorated with register.inclusion_tag in inclusion_tag.py

Upvotes: 2

Aaron Lelevier
Aaron Lelevier

Reputation: 20818

You would actually want to make a context processor to supply the algorithm objects to all templates. context_processors are just functions that return objects to be used as context within any view. So here is the code you need:

For this example, my app is called core. I have a python file in the app called context_processors and the function is myuser. Here is my function code:

from django.contrib.auth.models import User
from .models import MyUser

def myuser(request):
    try:
        user = User.objects.get(pk=request.user.pk)
    except User.DoesNotExist:
        user = None

    if user:
        myuser = MyUser.objects.get(user=user)
        return {'myuser': myuser}
    else:
        # load a default user for testing
        myuser = MyUser.objects.all()[0]
        return {'myuser': myuser}

The myuser() function just returns my extended User model. I created this so I could have the MyUser object available in all templates.

Then add this context_processor to you settings.py:

settings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    # other default context processors
    'core.context_processors.myuser',
    )

Upvotes: 2

Related Questions