1

Using Django 3.2

Have defined few global variables like

app/context_processors.py

from app.settings import constants

def global_settings(request):
    return {
        'APP_NAME': constants.APP_NAME,
        'APP_VERSION': constants.APP_VERSION,
        'STATIC_URL_HOST': constants.STATIC_URL_HOST
    }

and in settings.py file

TEMPLATES = [
    {
        ...
        'OPTIONS': {
            'context_processors': [
                ...
                'app.context_processors.global_settings',
            ],
        },
    },
]

Have used APP_NAME in the email template footer like

account/emails.py

def welcome_email(user):
  
    subject_file = 'account/email/welcome_subject.txt'
    body_text_file = 'account/email/welcome_message.txt'
    body_html_file = 'account/email/welcome_message.html'

    subject_text = get_template(subject_file)
    body_text = get_template(body_text_file)
    body_html = get_template(body_html_file)

    context = {
        'username': user.username,
    }

    subject_content = subject_text.render(context)
    body_text_content = body_text.render(context)
    body_html_content = body_html.render(context)

    to = [user.email]

    msg = EmailMultiAlternatives(
        subject=subject_content,
        body=body_text_content,
        from_email='{} <{}>'.format('Admin', 'admin@example.com'),
        to=to,
    )
    msg.attach_alternative(body_html_content, 'text/html')
    msg.send()

templates/account/welcome_message.html

Hi {{ username }},

Welcome to the application.

{{ APP_NAME }}

When the email is sent from the web portal, the APP_NAME is rendered fine, but when the email send is initiated from the Django shell

python manage.py shell

> from account.emails import welcome_email
> welcome_email(user)

Then the APP_NAME is not rendered in the email.

How the context processor can be rendered from the shell as well?

Anuj TBE
  • 9,198
  • 27
  • 136
  • 285

1 Answers1

1

A context processor takes as input an HttpRequest object, hence for a context processor to be run when a templates render method is called a request is needed to be passed to it like template.render(context, request). Your welcome_email function doesn't take request and naturally can't pass it.

If this function is called from some view all you need to do is take the request as an argument and pass it to the templates render method:

def welcome_email(user, request):
    ...
    subject_content = subject_text.render(context, request)
    body_text_content = body_text.render(context, request)
    body_html_content = body_html.render(context, request)
    ...

If it is called by some automated process which doesn't have a request object, well since your processor doesn't even need the request and the values you use are constant just pass them yourself from the function.

Abdul Aziz Barkat
  • 19,475
  • 3
  • 20
  • 33