#32364 closed Uncategorized (worksforme)
ModelAdmin.formfield_overrides drops TEMPLATES...DIRS while loading a custom widget template within a std admin form template
Reported by: | zoltan-ky | Owned by: | nobody |
---|---|---|---|
Component: | Template system | Version: | 3.1 |
Severity: | Normal | Keywords: | formfield_overrides |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | yes |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Using Django 3.1.5. This custom widget "idea" is a minimal demo-version based on https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_overrides.
So I'd like to use a MyTextArea widget with its mytextarea.html on models.TextField (myapp.Post.body) below and use it to edit Posts within the admin. (I know how to do it through forms, creating my form fields *and* my widgets, but that's a workaround).
When I 'runserver' and try to add a new Post under the admin a "django.template.exceptions.TemplateDoesNotExist: myapp/mytextarea.html" exception is thrown.
What am I missing in the test setup below?
I have traced the problem, as it is set up, (using pdb) to the EngineMixin class (django/forms/renderer.py:39) which has a 'hard-coded' backend ' named 'djangoforms'. This DjangoTemplates instance used to instantiate MyTextArea is different from the one used to find the admin form template. Somewhere, and I don't understand enough of what's going on here, the 'dirs' property of the first Engine (used for the form template) gets dropped and not passed to the Engine used to load the custom widget template.
To recreate (django 3.1.5): starting with a new: django-admin startproject myproject; ... startapp myapp. After creating the few small files below, migrate, createsuperuser for admin.
In the startproject-created *myproject/myproject/settings.py* the only changes are:
- 'myapp' is added to INSTALLED_APPS
- TEMPLATES...DIRS: [ BASE_DIR / 'templates' ],
to use project-wide templates.
The files:
myapp/admin.py:
from django.contrib import admin from django.db import models from myapp.models import Post from myapp.widgets import MyTextWidget # Register your models here. class PostAdmin(admin.ModelAdmin): formfield_overrides = { models.TextField: {'widget': MyTextWidget} } admin.site.register(Post, PostAdmin)
myapp/models.py:
from django.db import models # Create your models here. class Post(models.Model): body = models.TextField()
myapp/widgets.py:
from django import forms from django.contrib.admin import widgets class MyTextWidget(forms.Textarea): template_name = 'myapp/mytextarea.html'
<project>/templates/myapp/mytextarea.html:
{# based on django/forms/templates/django/forms/widgets/textarea.html #} <textarea name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}> <p>MY TEXTAREA</p> {% if widget.value %}{{ widget.value }}{% endif %}</textarea>
Change History (2)
comment:1 by , 4 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 4 years ago
Needs documentation: | set |
---|---|
Resolution: | invalid → worksforme |
My apologies. I should have posted on the support channel first and will do so in the future.
There is no mention of this need at https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_overrides and is the example I followed
Maybe that part of the admin documentation should be updated to avoid the trap.
See docs about Overriding built-in widget templates. You should use
FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
.Please don't use Trac as a support channel. Closing per TicketClosingReasons/UseSupportChannels.