summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorDavid Smith <smithdc@gmail.com>2022-11-02 20:13:16 +0000
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-03-24 10:16:30 +0100
commitcad376f844c7bdeeee7607a7c0ea8ae52061309b (patch)
tree674bcfb8a4b99c752bff23c029494987ed62f5ef /django
parentd33368b4ab6ae0c01e83d525f7e1655156a640d1 (diff)
downloaddjango-cad376f844c7bdeeee7607a7c0ea8ae52061309b.tar.gz
Fixed #34077 -- Added form field rendering.
Diffstat (limited to 'django')
-rw-r--r--django/forms/boundfield.py19
-rw-r--r--django/forms/fields.py2
-rw-r--r--django/forms/jinja2/django/forms/div.html11
-rw-r--r--django/forms/jinja2/django/forms/field.html10
-rw-r--r--django/forms/renderers.py1
-rw-r--r--django/forms/templates/django/forms/div.html11
-rw-r--r--django/forms/templates/django/forms/field.html10
-rw-r--r--django/forms/utils.py23
8 files changed, 58 insertions, 29 deletions
diff --git a/django/forms/boundfield.py b/django/forms/boundfield.py
index 6764276148..39b0aaf97b 100644
--- a/django/forms/boundfield.py
+++ b/django/forms/boundfield.py
@@ -1,7 +1,7 @@
import re
from django.core.exceptions import ValidationError
-from django.forms.utils import pretty_name
+from django.forms.utils import RenderableFieldMixin, pretty_name
from django.forms.widgets import MultiWidget, Textarea, TextInput
from django.utils.functional import cached_property
from django.utils.html import format_html, html_safe
@@ -10,8 +10,7 @@ from django.utils.translation import gettext_lazy as _
__all__ = ("BoundField",)
-@html_safe
-class BoundField:
+class BoundField(RenderableFieldMixin):
"A Field plus data"
def __init__(self, form, field, name):
@@ -26,12 +25,7 @@ class BoundField:
else:
self.label = self.field.label
self.help_text = field.help_text or ""
-
- def __str__(self):
- """Render this field as an HTML widget."""
- if self.field.show_hidden_initial:
- return self.as_widget() + self.as_hidden(only_initial=True)
- return self.as_widget()
+ self.renderer = form.renderer
@cached_property
def subwidgets(self):
@@ -81,6 +75,13 @@ class BoundField:
self.name, self.form.error_class(renderer=self.form.renderer)
)
+ @property
+ def template_name(self):
+ return self.field.template_name or self.form.renderer.field_template_name
+
+ def get_context(self):
+ return {"field": self}
+
def as_widget(self, widget=None, attrs=None, only_initial=False):
"""
Render the field by rendering the passed widget, adding any HTML
diff --git a/django/forms/fields.py b/django/forms/fields.py
index 003fb5ca6b..0143296533 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -107,6 +107,7 @@ class Field:
localize=False,
disabled=False,
label_suffix=None,
+ template_name=None,
):
# required -- Boolean that specifies whether the field is required.
# True by default.
@@ -164,6 +165,7 @@ class Field:
self.error_messages = messages
self.validators = [*self.default_validators, *validators]
+ self.template_name = template_name
super().__init__()
diff --git a/django/forms/jinja2/django/forms/div.html b/django/forms/jinja2/django/forms/div.html
index 6de0bb038e..f297874e4a 100644
--- a/django/forms/jinja2/django/forms/div.html
+++ b/django/forms/jinja2/django/forms/div.html
@@ -4,16 +4,7 @@
{% endif %}
{% for field, errors in fields %}
<div{% set classes = field.css_classes() %}{% if classes %} class="{{ classes }}"{% endif %}>
- {% if field.use_fieldset %}
- <fieldset>
- {% if field.label %}{{ field.legend_tag() }}{% endif %}
- {% else %}
- {% if field.label %}{{ field.label_tag() }}{% endif %}
- {% endif %}
- {% if field.help_text %}<div class="helptext">{{ field.help_text|safe }}</div>{% endif %}
- {{ errors }}
- {{ field }}
- {% if field.use_fieldset %}</fieldset>{% endif %}
+ {{ field.as_field_group() }}
{% if loop.last %}
{% for field in hidden_fields %}{{ field }}{% endfor %}
{% endif %}
diff --git a/django/forms/jinja2/django/forms/field.html b/django/forms/jinja2/django/forms/field.html
new file mode 100644
index 0000000000..56ffa1ad83
--- /dev/null
+++ b/django/forms/jinja2/django/forms/field.html
@@ -0,0 +1,10 @@
+{% if field.use_fieldset %}
+ <fieldset>
+ {% if field.label %}{{ field.legend_tag() }}{% endif %}
+{% else %}
+ {% if field.label %}{{ field.label_tag() }}{% endif %}
+{% endif %}
+{% if field.help_text %}<div class="helptext">{{ field.help_text|safe }}</div>{% endif %}
+{{ field.errors }}
+{{ field }}
+{% if field.use_fieldset %}</fieldset>{% endif %}
diff --git a/django/forms/renderers.py b/django/forms/renderers.py
index 30f8141dee..58abe9ed02 100644
--- a/django/forms/renderers.py
+++ b/django/forms/renderers.py
@@ -19,6 +19,7 @@ def get_default_renderer():
class BaseRenderer:
form_template_name = "django/forms/div.html"
formset_template_name = "django/forms/formsets/div.html"
+ field_template_name = "django/forms/field.html"
def get_template(self, template_name):
raise NotImplementedError("subclasses must implement get_template()")
diff --git a/django/forms/templates/django/forms/div.html b/django/forms/templates/django/forms/div.html
index 0328fdf8d3..c20eead4aa 100644
--- a/django/forms/templates/django/forms/div.html
+++ b/django/forms/templates/django/forms/div.html
@@ -4,16 +4,7 @@
{% endif %}
{% for field, errors in fields %}
<div{% with classes=field.css_classes %}{% if classes %} class="{{ classes }}"{% endif %}{% endwith %}>
- {% if field.use_fieldset %}
- <fieldset>
- {% if field.label %}{{ field.legend_tag }}{% endif %}
- {% else %}
- {% if field.label %}{{ field.label_tag }}{% endif %}
- {% endif %}
- {% if field.help_text %}<div class="helptext">{{ field.help_text|safe }}</div>{% endif %}
- {{ errors }}
- {{ field }}
- {% if field.use_fieldset %}</fieldset>{% endif %}
+ {{ field.as_field_group }}
{% if forloop.last %}
{% for field in hidden_fields %}{{ field }}{% endfor %}
{% endif %}
diff --git a/django/forms/templates/django/forms/field.html b/django/forms/templates/django/forms/field.html
new file mode 100644
index 0000000000..8f26213782
--- /dev/null
+++ b/django/forms/templates/django/forms/field.html
@@ -0,0 +1,10 @@
+{% if field.use_fieldset %}
+ <fieldset>
+ {% if field.label %}{{ field.legend_tag }}{% endif %}
+{% else %}
+ {% if field.label %}{{ field.label_tag }}{% endif %}
+{% endif %}
+{% if field.help_text %}<div class="helptext">{{ field.help_text|safe }}</div>{% endif %}
+{{ field.errors }}
+{{ field }}
+{% if field.use_fieldset %}</fieldset>{% endif %}
diff --git a/django/forms/utils.py b/django/forms/utils.py
index e0888b6e85..f4fbf3e241 100644
--- a/django/forms/utils.py
+++ b/django/forms/utils.py
@@ -58,6 +58,29 @@ class RenderableMixin:
__html__ = render
+class RenderableFieldMixin(RenderableMixin):
+ def as_field_group(self):
+ return self.render()
+
+ def as_hidden(self):
+ raise NotImplementedError(
+ "Subclasses of RenderableFieldMixin must provide an as_hidden() method."
+ )
+
+ def as_widget(self):
+ raise NotImplementedError(
+ "Subclasses of RenderableFieldMixin must provide an as_widget() method."
+ )
+
+ def __str__(self):
+ """Render this field as an HTML widget."""
+ if self.field.show_hidden_initial:
+ return self.as_widget() + self.as_hidden(only_initial=True)
+ return self.as_widget()
+
+ __html__ = __str__
+
+
class RenderableFormMixin(RenderableMixin):
def as_p(self):
"""Render as <p> elements."""