Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django. TemplateDoesNotExist in case of a custom widget

Tags:

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.

like image 768
MrBinWin Avatar asked Aug 23 '17 15:08

MrBinWin


Video Answer


2 Answers

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.

like image 145
user3763125 Avatar answered Sep 21 '22 04:09

user3763125


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

like image 31
Arpit Solanki Avatar answered Sep 19 '22 04:09

Arpit Solanki