Adding to all templates context via Middleware

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Adding to all templates context via Middleware

Bernd Wechner
This interests me:

    https://teamtreehouse.com/community/django-how-can-i-retrieve-a-value-from-the-middleware

alas no answer there, and time has changed things.

I have checked form experience, that stuff added to response.context_data in middleware is not seen in templates (perhaps comes too late!).

Another pager here:

    https://mlvin.xyz/django-templates-context-processors.html

describes how to add to context used context processors. Searching the web is nightmare in this space because of how Django has changed over time and the different methods in different versions.

The problem I have with that sample above is he's replicating code by including in settings.py:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates"),],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                # our custom context processor
                'utils.context_processors.active_shows',
            ],
        },
    },
]

most of which is standard. Is there not a much more DRY way to add a context processor? Would this work?

TEMPLATES = [
    {
        'OPTIONS': {
            'context_processors': [
                'utils.context_processors.active_shows',
            ],
        },
    },
]

Probably not at a guess.  But is there a nicer way to do it?

Another way might be to patch the response.content in the middleware but that too seems messy.

Surely there's a nice way for middlware to take some timing stats around the:

        response = self.get_response(request)

invocation that typically returns a response (and which I presume has already been through the whole template processing and has finalised response.content by the time it's done, so taking a timestamp after it's done is easy but making the result available in the templates via a context variable like {{execution_time}} would seem structurally impossible if context processing has already happened.

I can only imagine a trick using another context key like %%execution_time%% say and replacing that response.content.

I wonder if I'm on the right track here? Or if someone has a better idea?

Regards,

Bernd.


--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/aa664e82-187c-4c4b-907d-9ef2aa335e13%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Adding to all templates context via Middleware

Daniel Roseman-2
On Thursday, 3 May 2018 01:36:26 UTC+1, Bernd Wechner wrote:
This interests me:

    <a href="https://teamtreehouse.com/community/django-how-can-i-retrieve-a-value-from-the-middleware" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fteamtreehouse.com%2Fcommunity%2Fdjango-how-can-i-retrieve-a-value-from-the-middleware\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFlQg1mgPloZrBDWo5LZfloQ35g_Q&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fteamtreehouse.com%2Fcommunity%2Fdjango-how-can-i-retrieve-a-value-from-the-middleware\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFlQg1mgPloZrBDWo5LZfloQ35g_Q&#39;;return true;">https://teamtreehouse.com/community/django-how-can-i-retrieve-a-value-from-the-middleware

alas no answer there, and time has changed things.

I have checked form experience, that stuff added to response.context_data in middleware is not seen in templates (perhaps comes too late!).

Another pager here:

    <a href="https://mlvin.xyz/django-templates-context-processors.html" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fmlvin.xyz%2Fdjango-templates-context-processors.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHmL_DQt0BynjU2qDxsf4rNZ9-Ogw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fmlvin.xyz%2Fdjango-templates-context-processors.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHmL_DQt0BynjU2qDxsf4rNZ9-Ogw&#39;;return true;">https://mlvin.xyz/django-templates-context-processors.html

describes how to add to context used context processors. Searching the web is nightmare in this space because of how Django has changed over time and the different methods in different versions.

The problem I have with that sample above is he's replicating code by including in settings.py:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates"),],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                # our custom context processor
                'utils.context_processors.active_shows',
            ],
        },
    },
]

most of which is standard. Is there not a much more DRY way to add a context processor? Would this work?

TEMPLATES = [
    {
        'OPTIONS': {
            'context_processors': [
                'utils.context_processors.active_shows',
            ],
        },
    },
]

Probably not at a guess.  But is there a nicer way to do it?

Another way might be to patch the response.content in the middleware but that too seems messy.

Surely there's a nice way for middlware to take some timing stats around the:

        response = self.get_response(request)

invocation that typically returns a response (and which I presume has already been through the whole template processing and has finalised response.content by the time it's done, so taking a timestamp after it's done is easy but making the result available in the templates via a context variable like {{execution_time}} would seem structurally impossible if context processing has already happened.

I can only imagine a trick using another context key like %%execution_time%% say and replacing that response.content.

I wonder if I'm on the right track here? Or if someone has a better idea?

Regards,

Bernd.



I don't understand what you mean about "repeating code" in settings.py. There's no need to repeat anything; that TEMPLATES setting replaces what's there already. You just need to edit the existing value and add that extra context processor.
--
DR.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/8a3fb41d-0396-46fb-b896-b468fb103a2b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Adding to all templates context via Middleware

Bernd Wechner
Daniel,

The backend code contains:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates"),],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
How is including all that in settings.py not a breach of DRY? When all you want is to add a context processor to that list?

By the by, as there is no way to inject this into context I am convinced as performance stats are not fully collected until the whole response is rendered. To wit I have done it by inserting stats just before </body> tag as a safe and clean bet.

The result is here:

https://github.com/bernd-wechner/CoGs/blob/develop/django_stats_middleware/__init__.py

Works well for me and is a good hook for inserting any kind of stats really that can be collected in the middleware layer.

Regards,

Bernd.

On Thursday, 3 May 2018 19:55:14 UTC+10, Daniel Roseman wrote:
On Thursday, 3 May 2018 01:36:26 UTC+1, Bernd Wechner wrote:
This interests me:

    <a href="https://teamtreehouse.com/community/django-how-can-i-retrieve-a-value-from-the-middleware" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fteamtreehouse.com%2Fcommunity%2Fdjango-how-can-i-retrieve-a-value-from-the-middleware\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFlQg1mgPloZrBDWo5LZfloQ35g_Q&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fteamtreehouse.com%2Fcommunity%2Fdjango-how-can-i-retrieve-a-value-from-the-middleware\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFlQg1mgPloZrBDWo5LZfloQ35g_Q&#39;;return true;">https://teamtreehouse.com/community/django-how-can-i-retrieve-a-value-from-the-middleware

alas no answer there, and time has changed things.

I have checked form experience, that stuff added to response.context_data in middleware is not seen in templates (perhaps comes too late!).

Another pager here:

    <a href="https://mlvin.xyz/django-templates-context-processors.html" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fmlvin.xyz%2Fdjango-templates-context-processors.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHmL_DQt0BynjU2qDxsf4rNZ9-Ogw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fmlvin.xyz%2Fdjango-templates-context-processors.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHmL_DQt0BynjU2qDxsf4rNZ9-Ogw&#39;;return true;">https://mlvin.xyz/django-templates-context-processors.html

describes how to add to context used context processors. Searching the web is nightmare in this space because of how Django has changed over time and the different methods in different versions.

The problem I have with that sample above is he's replicating code by including in settings.py:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates"),],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                # our custom context processor
                'utils.context_processors.active_shows',
            ],
        },
    },
]

most of which is standard. Is there not a much more DRY way to add a context processor? Would this work?

TEMPLATES = [
    {
        'OPTIONS': {
            'context_processors': [
                'utils.context_processors.active_shows',
            ],
        },
    },
]

Probably not at a guess.  But is there a nicer way to do it?

Another way might be to patch the response.content in the middleware but that too seems messy.

Surely there's a nice way for middlware to take some timing stats around the:

        response = self.get_response(request)

invocation that typically returns a response (and which I presume has already been through the whole template processing and has finalised response.content by the time it's done, so taking a timestamp after it's done is easy but making the result available in the templates via a context variable like {{execution_time}} would seem structurally impossible if context processing has already happened.

I can only imagine a trick using another context key like %%execution_time%% say and replacing that response.content.

I wonder if I'm on the right track here? Or if someone has a better idea?

Regards,

Bernd.



I don't understand what you mean about "repeating code" in settings.py. There's no need to repeat anything; that TEMPLATES setting replaces what's there already. You just need to edit the existing value and add that extra context processor.
--
DR.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/1a7977fa-4022-4ebe-ad8f-cda88f49cfe6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Adding to all templates context via Middleware

Daniel Roseman-2
I still don't understand what is being repeated or why. You need to specify that in your settings, and you can add whatever context processors you like. You don't need to specify it twice, so nothing is being repeated.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/098abd87-885a-4e86-b1c7-1114ee148771%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Adding to all templates context via Middleware

Melvyn Sopacua
On maandag 7 mei 2018 17:59:02 CEST Daniel Roseman wrote:
> I still don't understand what is being repeated or why. You need to specify
> that in your settings, and you can add whatever context processors you
> like. You don't need to specify it twice, so nothing is being repeated.

What Bernd means is that if you don't specify it, Django will create such
dictionary, just not with the special context processor.

This is basically a matter of authority and circular import avoidance:
1) Suppose I don't want any context processors, I'd have no way to specify
that if my settings isn't deemed authoritative and Django just fills in what it
thinks it's missing
2) If you want to "edit defaults in project settings" you are bound to run
into circular imports as the Django settings needs to load your settings and
you want to import the Django settings.


--
Melvyn Sopacua

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/1999975.3yudL1jLur%40fritzbook.
For more options, visit https://groups.google.com/d/optout.