Forums

Template Does Not Exist

I'd like to ask for a little help. I've got a standalone file.py which has problems with rendering template to create email message. Everything is inside single file.py which suppose to execute periodic task.

message = render_to_string(
    template,
    context,
)

with template...

template = get_template('task.html')

or

template = get_template('tasks/task.html')

with same result

and context...

context = {
'overdue_objects': overdue_objects,
'current_week_objects': current_week_objects,
'next_week_objects': next_week_objects,
'current_month_objects': current_month_objects,
}

with settings...

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'templates'),
            '/home/RafalSzymanski/ab',
            '/home/RafalSzymanski/ab/tasks',
            '/home/RafalSzymanski/ab/templates/tasks'
        ],
        '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',
            ],
        },
    },
],

And I got error Template Does Not Exist. Why? What can I change?

How are you running your standalone code? Are you initialising all the Django stuff manually, or using a Django management command?

It's python file executed as scheduled task. It imports all this stuff:

from django.conf import settings
from django.core.mail import send_mail
from django.core.wsgi import get_wsgi_application
from django.template.loader import get_template, render_to_string

import os, sys

project_path = "/home/RafalSzymanski/"
sys.path.append(project_path)
ab_path = "/home/RafalSzymanski/ab/"
sys.path.append(ab_path)
tasks_path = "/home/RafalSzymanski/ab/tasks/"
sys.path.append(tasks_path)

from ab_k import ab_k, ab_EMAIL_HOST, ab_EMAIL_HOST_USER, ab_EMAIL_HOST_PASSWORD

settings.configure(
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
    SECRET_KEY = ab_k,
    DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'db.sqlite3'),
    }
},
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend',
EMAIL_USE_TLS = True,
EMAIL_HOST = ab_EMAIL_HOST,
EMAIL_HOST_USER = ab_EMAIL_HOST_USER,
EMAIL_HOST_PASSWORD = ab_EMAIL_HOST_PASSWORD,
EMAIL_PORT = '587',
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'templates'),
            '/home/RafalSzymanski/ab',
            '/home/RafalSzymanski/ab/tasks',
            '/home/RafalSzymanski/ab/templates/tasks'
        ],
        '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',
            ],
        },
    },
],
)

and in the end...

send_mail('subj', message, 'test@gmail.com', ['receiver@gmail.com'])

Which version of Django are you using? Some require an explicit call to django.setup, I think.

Alternatively, have you considered switching to using a Django management command? That might save you a certain amount of setup stuff.

I opened console dedicated to myvirtualenv and checked that it is django 1.9.0. I tried do django.setup() but another error appeared - no module or something. I saw somewhere that this error can rise when I have two different versions of django. I remeber that I upgraded django from 1.8 to 1.9 few months ago. I don't know how and where to check wheather I have two different versions. The management command are good solution I'm sure and I give it a try but to wriet few setting is not problem for this little experiment so I'd like to stay with it

Hmm. I think that django.setup is needed in 1.9, so that might be the problem. What is the exact exception you're getting?

in <module> django.setup() AttributeError: 'module' object has no attribute 'setup'

Are you sure you're running it inside a virtualenv with Django 1.9 installed?

No. File is executed with no use of virtualenv. I see what you are trtying to say me. So... should I write some management command inside this standalone file to run virtualenv? Is it how it should go?

No, the management command thing and the virtualenv are separate issues. A management command is a Django thing -- it's a way of writing a script so that Django does all of its setup without you having to call the setup function (and some associated stuff) yourself. Even if you were using one, you'd need to run it using a virtualenv.

Perhaps bullet points would help :-)

  • If you're using Django 1.9 on PythonAnywhere, you need to create a virtualenv and install it into that virtualenv.
  • When you run code that depends on that Django 1.9 installation, you need to do so inside the virtualenv:
  • If it's part of a website, you just specify the virtualenv on the "Web" tab.
  • If you're running it from a bash console, you need to activate the virtualenv before running it -- for example, if you created it using the virtualenvwrapper mkvirtualenv command, you would activate the virtualenv using workon ENVNAME before running the script.
  • If you're running it in a scheduled task, you can either put the workon command before the script name, eg. workon ENVNAME; python /path/to/script, or you can use the full path to the Python executable in the scheduled task's command line, eg. /home/myusername/.virtualenvs/myenv/bin/python /path/to/script.

Does that clarify things at all?

Yes! It looks so logic now. Thank you :)

Good luck :-)

I tried to run script as a scheduled task but failed.

when I run...

source /home/RafalSzymanski/.virtualenvs/novenv/bin/postactivate /home/RafalSzymanski/.virtualenvs/novenv/bin/python    /home/RafalSzymanski/ab/tasks/tasks.py

I receive empty first line and a comment in second line "-- Completed task, took 0.00 seconds, return code was 0."

when I run...

workon novenv /home/RafalSzymanski/.virtualenvs/novenv/bin/python /home/RafalSzymanski/ab/tasks/tasks.py

I receive "bash: workon: command not found -- Completed task, took 0.00 seconds, return code was 127.

when I run...

source /home/RafalSzymanski/.virtualenvs/novenv/bin/postactivate && /home/RafalSzymanski/.virtualenvs/novenv/bin/python /home/RafalSzymanski/ab/tasks/tasks.py

I recive white screen with no comment

Hi Rafal, the white screen could mean it was actually still running. You can view currently running tasks by clicking that "fetch process list" button on the schedule page.

Maybe it's finished running now?

For info, we set a 6-hour limit on scheduled tasks for paying users. (1 hour for free).

Right. Task was running and running... I killed the process and received "bash: line 1: 14181 Killed /home/RafalSzymanski/.virtualenvs/novenv/bin/python /home/RafalSzymanski/ab/tasks/tasks.py 2016-02-10 13:37:15 -- Completed task, took 668.00 seconds, return code was 137."

But it shouldn't last so long and give no result. There's nothing to do. Could I set DJANGO_SETTINGS_MODULE in not proper way?

Whole file looks like this.

#!/usr/local/bin/python3.4
import django
from django.core.mail import send_mail

import os, sys
ab_path = "/home/RafalSzymanski/ab/"
sys.path.append(ab_path)

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ab.settings.development")
django.setup()

send_mail('subj', 'bla', 'xxx@gmail.com', ['xxxxx@gmail.com'])

for your scheduled task, the command could just be

/home/RafalSzymanski/.virtualenvs/novenv/bin/python /home/RafalSzymanski/ab/tasks/tasks.py

maybe when u activate the virtualenv it puts you into an interactive bash shell or something.