21

I am attempting to override a built in widget template in Django 1.11. I seem to be doing everything that the docs say to do in this regard, but for the widget templates, Django is not looking in my project at all, and I get a TemplateDoesNotExist error.

Here's what I have for the override:

class MyFileWidget(widgets.FileInput):
    template_name = 'myapp/my_file_widget.html'

The template is definitely there. If I pass the template to a render call, it finds it fine. Problem is an issue of paths. When calling render from a view, it checks the following:

projectroot/templates/myapp/my_file_widget.html djangoroot/forms/templates/myapp/my_file_widget.html

When it finds the template in my project, it renders it. This is NOT happening when I provide the template path in the class above. In that case, it does not check in my project templates, where the file actually exists, and begins checking in the django path, where it does not. Hence the error message.

So I have no clue why this the loader would check my project templates on render calls, but then fail to do so when looking for the "template_name" of the widget override. Any ideas?

meesterguyperson
  • 1,726
  • 1
  • 20
  • 31

1 Answers1

38

By default, the FORM_RENDERER setting defaults to 'django.forms.renderers.DjangoTemplates'.

This checks your apps' templates directory (e.g. projectroot/myapp/templates/myapp/my_file_widget.html), but it does not check your project's template directories (e.g. projectroot/templates/myapp/my_file_widget.html).

If you want to use the same configuration as your TEMPLATES setting, then you should use the TemplatesSetting renderer.

FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'

You will also need to update your TEMPLATES setting so that Django can still use the built in widget templates. The easiest way to do this is to add django.forms to INSTALLED_APPS. See the docs for more info about this.

Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • 1
    Was just about to post an answer! That will do it. FYI, I didn't see that DjangoTemplates checked any of my project templates. Instead, seems to only look at Django templates, so don't know that that bit is correct. Another solution is to assign "default_renderer" on a per form basis, but of course, altering FORM_RENDERER is preferrable. – meesterguyperson Oct 19 '17 at 18:23
  • 1
    As I said, the `DjangoTemplates` doesn't check your project templates by design. It should check the template directories for all apps in your `INSTALLED_APPS`, regardless of whether they are `django.contrib` apps, third party, or part of your project. If you are storing your template in `projectroot/templates/myapp/my_file_widget.html`, then it sounds like `myapp` does not have a template directory `projectroot/myapp/templates/` to check. – Alasdair Oct 19 '17 at 18:34
  • Ah, gotcha. I think I misunderstood. Then looks good. Gracias! – meesterguyperson Oct 19 '17 at 18:41