[Django] #34077: Make BoundField renderable.

17 views
Skip to first unread message

Django

unread,
Oct 8, 2022, 4:59:11 AM10/8/22
to django-...@googlegroups.com
#34077: Make BoundField renderable.
-----------------------------------------+------------------------
Reporter: David Smith | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 4.1
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+------------------------
As of Django 4.1 Forms and Widgets (i.e. its `<input>`) are renderable
using the template engine. Django also has a strong concept of a field
with the `BoundField` class. This contains all of the information required
to render a field such as its label, errors, help text and its Widget.

Currently something like this is possible:

{{{
{% for field in form %}
{{ field.label_tag }}
{{ field }} # Note this is the widget!
{{ field.help_text }}
{% endfor %}
}}}

The current limitation is that each component of each field needs to be
rendered individually. It's fine when they are rendered all in the same
way as we can put them in a nice loop like above.

However, a reasonable request could be to have the `first name` and `last
name` on the same row (say). This would result in needing to do something
like the following. This would become even more verbose with errors being
introduced too:

{{{
<div class="row">
<div class="col">
{{ form.first_name.label }}
{{ form.first_name }}
{{ form.first_name.help_text }}
</div>
<div class="col">
{{ form.last_name.label }}
{{ form.last_name }}
{{ form.last_name.help_text }}
</div>
</div>
<div>
# more fields here
</div>
}}}

The proposal is that the `BoundField` should be a renderable object, this
could either be done by a new method (e.g. `field.as_field`) or maybe a
template filter (e.g `field|as_field`). We need the `as_field` (or another
function name) as the field on it's own currently renders the fields
widget rather than the whole field (i.e. incl label, help text , errors).

This would allow the above to be written as:

{{{
<div class="row">
<div class="col">
{{ form.first_name|as_field }}
</div>
<div class="col">
{{ form.last_name|as_field }}
</div>
</div>
<div>
# more fields here
</div>
}}}

A few initial thoughts on a possible implementation approach. This is not
fully thought out, but should hopefully be a helpful rough guide.

1. [https://github.com/django/django/blob/main/django/forms/fields.py#L82
Field] would learn a `template_name` attribute which can also be set via
it's `__init__`. Therefore in a form you would have:

{{{
class MyForm(forms.Form)
first_name = forms.CharField(max=10,
template_name="my_template_name.html")
}}}

2. Add a new method, either as a filter or as a new method to
[https://github.com/django/django/blob/d795259ea96004df0a2469246229a146307bcd2c/django/forms/boundfield.py#L14
BoundField] which renders the `BoundField` with it's fields template
(`boundfield.field.template_name`)

3. Consider if we need to provide a default implementation of this. If so
we should replicate the `div.html` templates. Specifically
[https://github.com/django/django/blob/d795259ea96004df0a2469246229a146307bcd2c/django/forms/templates/django/forms/div.html#L5-L21
these lines]. The `div.html` template can be updated to use this new
method.

4. If we do step 3 then the errors will likely be an issue as they
currently get rendered to a str in the form's
[https://github.com/django/django/blob/d795259ea96004df0a2469246229a146307bcd2c/django/forms/forms.py#L328-L348
get_context]. This may need breaking out into a separate function so it
can be called when rendering a field. `BoundField` know's about it's
associated form (`BoundField.Form`)

--
Ticket URL: <https://code.djangoproject.com/ticket/34077>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Oct 10, 2022, 3:33:01 AM10/10/22
to django-...@googlegroups.com
#34077: Make BoundField renderable.
-----------------------------+------------------------------------

Reporter: David Smith | Owner: nobody
Type: New feature | Status: new
Component: Forms | Version: 4.1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------
Changes (by Carlton Gibson):

* type: Uncategorized => New feature
* component: Uncategorized => Forms
* stage: Unreviewed => Accepted


Comment:

Yes, thanks David. I think this is the logical next/final? step in the
form rendering adjustments. +1

--
Ticket URL: <https://code.djangoproject.com/ticket/34077#comment:1>

Django

unread,
Oct 22, 2022, 2:19:24 PM10/22/22
to django-...@googlegroups.com
#34077: Make BoundField renderable.
-----------------------------+------------------------------------
Reporter: David Smith | Owner: skidipap
Type: New feature | Status: assigned

Component: Forms | Version: 4.1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------
Changes (by skidipap):

* owner: nobody => skidipap
* status: new => assigned


--
Ticket URL: <https://code.djangoproject.com/ticket/34077#comment:2>

Django

unread,
Oct 30, 2022, 1:09:16 PM10/30/22
to django-...@googlegroups.com
#34077: Make BoundField renderable.
-----------------------------+------------------------------------
Reporter: David Smith | Owner: skidipap
Type: New feature | Status: assigned
Component: Forms | Version: 4.1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------

Comment (by David Smith):

>I think this is the logical next/final? step in the form

I think so.

@skidipap -- How are you getting on with this. I had made a tentative
start, but then realised you have claimed the ticket and therefore wanted
to avoid duplicate work. Maybe if you have some work to share I could help
with comments on a PR?

--
Ticket URL: <https://code.djangoproject.com/ticket/34077#comment:3>

Django

unread,
Nov 16, 2022, 2:19:56 AM11/16/22
to django-...@googlegroups.com
#34077: Make BoundField renderable.
-----------------------------+---------------------------------------
Reporter: David Smith | Owner: David Smith

Type: New feature | Status: assigned
Component: Forms | Version: 4.1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+---------------------------------------
Changes (by David Smith):

* owner: skidipap => David Smith


--
Ticket URL: <https://code.djangoproject.com/ticket/34077#comment:4>

Django

unread,
Mar 1, 2023, 5:37:42 AM3/1/23
to django-...@googlegroups.com
#34077: Make BoundField renderable.
-----------------------------+---------------------------------------
Reporter: David Smith | Owner: David Smith
Type: New feature | Status: assigned
Component: Forms | Version: 4.1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-----------------------------+---------------------------------------
Changes (by Carlton Gibson):

* needs_better_patch: 0 => 1
* has_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/34077#comment:5>

Django

unread,
Mar 21, 2023, 10:45:40 AM3/21/23
to django-...@googlegroups.com
#34077: Make BoundField renderable.
-----------------------------+---------------------------------------
Reporter: David Smith | Owner: David Smith
Type: New feature | Status: assigned
Component: Forms | Version: 4.1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-----------------------------+---------------------------------------

Comment (by Carlton Gibson <carlton.gibson@…>):

In [changeset:"051d5944f86400b9b3476db60bc73de7e9964810" 051d594]:
{{{
#!CommitTicketReference repository=""
revision="051d5944f86400b9b3476db60bc73de7e9964810"
Refs #33134, Refs #34077 -- Adjusted form rendering recursion test.

Adjusted recursion depth test to use str() rather than the form or
field’s render() method.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/34077#comment:6>

Django

unread,
Mar 24, 2023, 5:17:20 AM3/24/23
to django-...@googlegroups.com
#34077: Make BoundField renderable.
-----------------------------+---------------------------------------------

Reporter: David Smith | Owner: David Smith
Type: New feature | Status: assigned
Component: Forms | Version: 4.1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for checkin

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------+---------------------------------------------
Changes (by Mariusz Felisiak):

* needs_better_patch: 1 => 0
* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/34077#comment:7>

Django

unread,
Mar 24, 2023, 7:43:26 AM3/24/23
to django-...@googlegroups.com
#34077: Make BoundField renderable.
-----------------------------+---------------------------------------------
Reporter: David Smith | Owner: David Smith
Type: New feature | Status: closed
Component: Forms | Version: 4.1
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Ready for checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+---------------------------------------------
Changes (by Mariusz Felisiak <felisiak.mariusz@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"cad376f844c7bdeeee7607a7c0ea8ae52061309b" cad376f8]:
{{{
#!CommitTicketReference repository=""
revision="cad376f844c7bdeeee7607a7c0ea8ae52061309b"
Fixed #34077 -- Added form field rendering.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/34077#comment:8>

Django

unread,
Mar 25, 2023, 11:53:26 PM3/25/23
to django-...@googlegroups.com
#34077: Make BoundField renderable.
-----------------------------+---------------------------------------------
Reporter: David Smith | Owner: David Smith
Type: New feature | Status: closed
Component: Forms | Version: 4.1
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Ready for checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+---------------------------------------------

Comment (by Rami Boutassghount):

Many thanks to all who made this possible. Now I can add my CSS classes to
my field label tags or at least try 😅

--
Ticket URL: <https://code.djangoproject.com/ticket/34077#comment:9>

Reply all
Reply to author
Forward
0 new messages