Django 1.8 ignores DIRS, cannot find templates - python

Here is my TEMPLATES section in settings.py:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
},
},
]
I'm using template inside application directory and it works. But whenever I'm trying to extend it with layout from global templates directory (os.path.join(BASE_DIR, 'templates'), which exists, I tested), django raises TemplateDoesNotExist error. Here is Template-loader postmortem, which does not includes my DIRS directory:
Django tried loading these templates, in this order:
Using loader django.template.loaders.filesystem.Loader:
Using loader django.template.loaders.app_directories.Loader:
/usr/local/lib/python2.7/dist-packages/django/contrib/admin/templates/layouts/default.html (File does not exist)
/usr/local/lib/python2.7/dist-packages/django/contrib/auth/templates/layouts/default.html (File does not exist)
/home/foundation/public/foundation/foundation/event_request/templates/layouts/default.html (File does not exist)
**UPDATE: ** seems like apache loads django 1.5 instead of django 1.8. This might be a problem.

After log entry
Using loader django.template.loaders.filesystem.Loader:
loader should print all possible locations that it tried to find your template, like it was after similar log from app_directories loader. If there is no paths here, double check if your TEMPLATES setting is defined correctly, is not overwritten somewhere later in your settings or other files and if Django is loading that settings file correctly.
You can throw some exception to get 500 server error when DEBUG is set to True, on error page you will get handy list of all settings that Django sees.
Also check if your WSGI server is loading proper version of django, older versions doesn't have TEMPLATE setting (it was splitted between multiple settings).

Problem has to do with wrong virtualenv and actual use of Django 1.5.1 instead of 1.8. I'll save this post, maybe it will help someone with similar problem in future.

Related

Django. TemplateDoesNotExist in case of a custom widget

I'm trying to create a custom widget in Django admin. I created a class:
class FroalaWYSIWYGTextareaWidget(django.forms.widgets.Textarea):
template_name = 'froala_wysiwyg.html'
Then a simple model form:
class ArticleForm(django.forms.ModelForm):
class Meta:
fields = '__all__'
model = Article
widgets = {
'content': FroalaWYSIWYGTextareaWidget(),
}
Here are my settings:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_PATH, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.i18n',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Usualy everything works fine and Django can find templates in my /templates/ directory but in case of this widget I have a 500 Error:
TemplateDoesNotExist at /admin/article/article/1/change/
froala_wysiwyg.html
Request Method: GET
Request URL: http://127.0.0.1:8000/admin/article/article/1/change/
Django Version: 1.11.4
Exception Type: TemplateDoesNotExist
Exception Value: froala_wysiwyg.html
Exception Location: /home/username/.virtualenvs/sitename/lib/python3.5/site-packages/django/template/engine.py in find_template, line 148
Python Executable: /home/username/.virtualenvs/sitename/bin/python
Python Version: 3.5.2
I debugged django.filesystem.loader and found out that usually Loader.engine.dirs is a list:
['/home/username/python/sitename/templates']
so Loader.get_template_sources() works great
but in case of this custom widget this loader.engine.dirs contains only:
['/home/username/.virtualenvs/sitename/lib/python3.5/site-packages/django/forms/templates']
So it just ignores DIRS option from the settings and uses forms/templates instead. Is it a bug of Django or I have to change something in settings?
I don't understand where does this django/forms/templates path come from?
Thanks.
If you want to use a custom widget template stored somewhere under your "TEMPLATES" directory of your project then follow these steps:
a) Use the TEMPLATES settings that you have provided in your question
b) Set the FORM_RENDERER as following in the settings.py
FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
c) Add the app "django.forms" to the 'INSTALLED_APPS' list in settings.py
Also, be sure to assign the correct path of the custom widget template relative to your "TEMPLATES" directory to "template_name" attribute of your custom widget.
Its certainly not a bug
I don't understand where does this django/forms/templates path come from?
You can view the source code where you can see the line
[docs]class Textarea(Widget):
template_name = 'django/forms/widgets/textarea.html'
This was the source of your first question. Now second one
This renderer uses a standalone DjangoTemplates engine (unconnected to what you might have configured in the TEMPLATES setting). It loads templates first from the built-in form templates directory in django/forms/templates and then from the installed apps’ templates directories using the app_directories loader.
This is true for your form widget classes also. To make things work for you custom widget template you have to specify the path with same terminology like app_name/forms/widget/textarea.html

How can I have a template folder outside my Django project

I'm working on an Open Source Django app and created some design for it. Now a customer wants to use it's own, copyrighted, design. After reading the Django docs I created a separate, private, GIT repository that I want to use for the new design. I got it almost working by adding 2 items to the settings; an extra entry to look for templates in a folder "funder_custom_templates" and an extra entry to look for static files in the same location. This is how I configured TEMPLATES and STATICFILES_DIR:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(PROJECT_DIR, '..', '..', 'funder_custom_templates'),
os.path.join(PROJECT_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',
'fundraiser.context_processors.cart',
],
},
},
]
STATICFILES_DIRS = [
os.path.join(PROJECT_DIR, '..', '..', 'funder_custom_templates','static'),
os.path.join(PROJECT_DIR, 'static'),
]
This works for overriding the base design located in the PROJECT_DIR/templates/base.html, when I create funder_customer_templates/base.html and for all the static files as expected. But I also want to override app specific template files like blog/templates/blog/blog_index_page.html
I tried to put these files in the root of funder_custom_templates and I tried to mimic the app folders structure in funder_custom_templates but that doesn't load the app specific templates. Is there a way to solve this?
Example project files, with the folder structure, located at: https://github.com/acidjunk/funder/tree/develop/
Since you are using the app_directories.Loader class to load templates (specified by setting 'APP_DIRS': True,), then for app specfic templates Django will iterate over your INSTALLED_APPS setting looking for a specific template file. The important thing here is that it does so in order.
So if you want to override blog/templates/blog/blog_index_page.html then you will need to have a custom_blog/templates/blog/blog_index_page.html inside an application that comes before blog.
I recommend wrapping up all custom static resources in their own django application and python package. This way you can simply install the package from its private repo and add it to the list of installed apps to override any static content and templates.
See Django's docs for more details on template loading: https://docs.djangoproject.com/en/1.9/ref/templates/api/#django.template.loaders.app_directories.Loader

DoesNotExist at /admin/login/ after upgrading to Django 1.8

After upgrade from django 1.7 to 1.8, I can't able to access my admin portal. I get the following error:
DoesNotExist at /admin/login/
Site matching query does not exist.
As mentioned in other questions, I have change my TEMPLATES setting, but it does not help.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'MyANSRSource/templates/MyANSRSource/'),
os.path.join(BASE_DIR, 'employee/template/'),
os.path.join(BASE_DIR, 'employee/emp_photo/'),
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
# Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
#global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
# 'django.template.context_processors.request',
#),
# list if you haven't customized them:
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
},
},
]
If you don't have SITE_ID in your settings, Django 1.8, will try to use the hostname (e.g. 127.0.0.1:8000) to find the site. If you don't have a site with that domain name in your database, then you will get the error:
Site matching query does not exist.
You have a few options:
You might not require the sites framework. You could try removing it from 'django.contrib.sites' from your INSTALLED_APPS setting.
In your settings, set SITE_ID to the value of the site you want to use. SITE_ID = 1 will probably work, if you haven't made any changes to the sites in the database.
Change the domain of the site in the database (e.g. from example.com to 127.0.0.1:8000). This is the most fragile fix, because your project will now work for 127.0.0.1:8000, but not for localhost:8000.
Try to create a new user by running the command manage.py createsuperuser. Log in with this user, you should be able to access the admin panel now.
Then find your user object and make sure it has the correct permissions. as stated in the 1.8 changelog under Minor features.
When I upgraded I lacked the correct permission to access the admin panel.

Errno22 while setting up django (trying to use get_template)

I am using windows, new to Django, trying to learn it.
Right now I am just trying to set up a template, views, url - and load the template in my browser. Should be simple.
I have a project folder. An app folder. A templates folder. My templates folder contains page.html which is an html file that just says "hi".
my urls is properly configured to point to my views
I have 2 views.
def frontpage(request):
fp = open('C:/EclipseWorkspace64/Project/templates/page.html')
page = Template(fp.read())
return HttpResponse(page)
def otherpage(request):
page = get_template('page.html')
return HttpResponse(page)
The first view loads my template fine when I go to the URL.
The second view does not. It gives me: [Errno 22] Invalid argument: 'C:\EclipseWorkspace64\Project\:\page.html'
This is templates in my settings:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': 'C:/EclipseWorkspace64/Project/templates/',
'APP_DIRS': False,
'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',
],
},
},
]
I don't understand why I get this error. What am I doing wrong? Why does the first view load but the second one doesn't? I have followed instructions in the django book on how to set up my settings file to a tee.

Updating Django template settings from 1.7 to 1.8

So I've been tinkering with upgrading to the new version of Django (1.8). I'm currently on version 1.7 and I am struggling to get my production server to listen to the new settings in 1.8.
As of 1.8, any TEMPLATE_* settings have been deprecated according to the documentation and has been replaced with the TEMPLATES setting.
I'm trying to just continue as I was, but I wish to move to the new settings before the deprecation timeline ends.
In my 1.7 settings I have only got two of the old settings which are now deprecated as follows:
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS += ("django.core.context_processors.request",)
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'templates'),
)
In the new 1.8 settings I've got the following:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
# Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
# list if you haven't customized them:
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.request',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
},
},
]
However when I use these settings, my production server cannot locate the template files, yet my local works just fine.
EDIT: Turns out APP_DIRS setting being missing was playing havoc with openshift. I have all my templates in one directory, not in application dirs, but this seemed to resolve the issue.
It seems that openshift doesn't read the DIRS: setting unless APP_DIRS: is set as True
Doing this, fixed the issue.

Categories

Resources