0

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....

Tomasz Brzezina
  • 1,452
  • 5
  • 21
  • 44
  • Don't know about Django hosts, but I would extend the default engine and inject another loader that loads base from a host-specific directory or even the database. See here for [details](https://docs.djangoproject.com/en/3.1/howto/custom-template-backend/). –  Dec 19 '20 at 00:26
  • @Melvyn I think this is to complex solution. I just need to get name, which is set in django-hosts as name https://django-hosts.readthedocs.io/en/latest/reference.html#django_hosts.defaults.patterns – Tomasz Brzezina Dec 19 '20 at 00:33

2 Answers2

0

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)

tim-mccurrach
  • 6,395
  • 4
  • 23
  • 41
  • can't use urlconf, because app_name in classic urls is set in "main" urls.py, where apps urls.py are selected (based on url) and there app_name can be set. But in hosts "main" urls.py is ignored and apps urls.py are selected based on domain regex – Tomasz Brzezina Dec 19 '20 at 00:58
  • @TomaszBrzezina I'm not sure (and I have never used django-hosts) but having a quick read of the code, it looks like django-hosts actually sets `request.urlconf` to use the appropriate `urls.py` in the correct app. – tim-mccurrach Dec 19 '20 at 01:01
  • yes, but the name is set at include in "main" urls.py, which with hosts is never used – Tomasz Brzezina Dec 19 '20 at 01:41
0

It was easier, than I supposed...

context_processors.py:

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

But 5 hours of searching are lost...

Tomasz Brzezina
  • 1,452
  • 5
  • 21
  • 44