diff options
author | David Smith <smithdc@gmail.com> | 2022-11-02 20:13:16 +0000 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2023-03-24 10:16:30 +0100 |
commit | cad376f844c7bdeeee7607a7c0ea8ae52061309b (patch) | |
tree | 674bcfb8a4b99c752bff23c029494987ed62f5ef /django | |
parent | d33368b4ab6ae0c01e83d525f7e1655156a640d1 (diff) | |
download | django-cad376f844c7bdeeee7607a7c0ea8ae52061309b.tar.gz |
Fixed #34077 -- Added form field rendering.
Diffstat (limited to 'django')
-rw-r--r-- | django/forms/boundfield.py | 19 | ||||
-rw-r--r-- | django/forms/fields.py | 2 | ||||
-rw-r--r-- | django/forms/jinja2/django/forms/div.html | 11 | ||||
-rw-r--r-- | django/forms/jinja2/django/forms/field.html | 10 | ||||
-rw-r--r-- | django/forms/renderers.py | 1 | ||||
-rw-r--r-- | django/forms/templates/django/forms/div.html | 11 | ||||
-rw-r--r-- | django/forms/templates/django/forms/field.html | 10 | ||||
-rw-r--r-- | django/forms/utils.py | 23 |
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.""" |