different extend from different applications

146 Views Asked by At

I'm trying to create one template for all apps, but with different base (related to app).

i'm using django_hosts:

hosts.py:

from django_hosts import patterns, host

host_patterns = patterns('',
        host(r'app1', 'app1.urls', name = 'app1'),
        host(r'(app2|application2)','app2.urls', name = 'app2'),
)

tree:

templates/document.html
app1/templates/app1/base.html
app2/templates/app2/base.html

templates/document.html:

{% extends base %}

And the idea is:

when I go to http://app1.example.com/document/ i will see templates/document.html extended with app1/templates/app1/base.html, and if I go to http://app2.example.com/document/ or http://application2.example.com/document/ extended with app2/templates/app2/base.html

generally it works if I use in

app1/views.py:

 (...)
       context={ 'base' : 'app1/base.html' }
    return render(request,'document.html', context)

app2/views.py:

   (...)
        context={ 'base' : 'app2/base.html' }
    return render(request,'document.html', context)

But I want to remove context 'base' from every views' def .

I can't use app1/context_processors.py and app2/context_processors.py, because it would override themselves, because context_processors are global not app local.

There's an idea:

#main/contexts.py
from django.core.urlresolvers import resolve
def appname(request):
    return {'appname': resolve(request.path).app_name}

but i don't have urls.py with includes, because i have hosts definition....

2

There are 2 best solutions below

0
On

It was easier, than I supposed...

context_processors.py:

def appname(request):   
    return {'appname': request.host.name }

But 5 hours of searching are lost...

3
On

I can think of two approaches:

Approach 1

If you just want to make your views less verbose, one thing you could do is create your own render function which adds in the appropriate context, you would need to write one of these functions per app. e.g.

# app1.views
from django.shortcuts import render as _render

def render(request, template_name, context=None, *args, **kwargs):
    if context is None:
        context = {}
    context = {**context, 'base' : 'app1/base.html'}
    return _render(request, template_name, context, *args, **kwargs)

def some_view(request):
    ....
    return render(request, 'document.html', context)

This obviously assumes all your views are in one file, but you could have a utils.py for each app, and just import your render for that app from the corresponding utils.py.

Approach 2

Your idea of using a context proccessor, and using resolve could actually work. resolve takes an optional argument urlconf, and looking at the middleware for django-hosts (here)it looks like it sets this on the request, so you could do the following:

resolve(request.path, urlconf=request.urlconf).app_name

(I've not tested the above, but I can't see why it wouldn't work)