Home > Enterprise >  How to display multiple views in a Django project's template?
How to display multiple views in a Django project's template?

Time:04-27

I have a Django project with multiple apps and I would like to manage the template from the project root folder.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        "DIRS": [os.path.join(BASE_DIR, "templates")],
        'APP_DIRS': True,
        'OPTIONS': {...}
    }]

In the homepage index.html of the project I'm trying to display num_exchanges and num_accounts generated in the views.py of app1 and app2. The problem is that only num_exchanges is printed not the second variable. If I switch the include in urlpatterns then the second variable is generated not the first one.

How can I print both variables ?

urls.py (project)

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r"^", include("app1.urls"), name='app1'),
    url(r"^", include("app2.urls"), name='app2'),
]

index.html (project)

{% load static %}
{% block content %}
  <h2>Stats</h2>
  <ul>
    <li><strong>Exchanges:</strong> {{ num_exchanges }}</li>
    <li><strong>Account:</strong> {{ num_accounts }}</li>
  </ul>
{% endblock %}

views.py (app1)

from django.shortcuts import render
from app1.models import Exchange


def app1_stats(request):
    num_exchanges = Exchange.objects.count()

    context = {
        'num_exchanges': num_exchanges
    }
    return render(request, 'index.html', context=context)

urls.py (app1)

from django.urls import path
from app1.views import app1_stats


urlpatterns = [
    path('', app1_stats, name='index'),
]

views.py (app2)

from django.shortcuts import render
from app2.models import Account


def app2_stats(request):
    num_accounts = Account.objects.count()

    context = {
        'num_accounts': num_accounts
    }
    return render(request, 'index.html', context=context)

urls.py (app2)

from django.urls import path
from app2.views import app2_stats


urlpatterns = [
    path('', app2_stats, name='index'),
]

CodePudding user response:

You'll have to write a new view which loads both variables. Django only supports one view per page load.

This view could call both of the other views. In order for this to work you'll need to replace render with TemplateResponse for both of the stats views.

def combined_stats(request):
    response1 = app1_stats(request)
    response2 = app2_stats(request)
    return render('index.html', {
        **response1.context_data,
        **response2.context_data
    })

Personally I would consider getting the context data for app1_stats and app2_stats in functions outside the view which can be called in combined_stats.

def combined_stats(request):
    return render('index.html', {
        **get_app1_stats_context(),
        **get_app2_stats_context()
    })

An extreme alternative would be to create a context processor for the two apps. This does make the context available (and executes two extra queries) on every page on your website. I wouldn't recommend this, but I guess it is an option if you need to emphatically keep the two apps apart.

  • Related