[Django] #32541: Separate context and rendering in forms

0 views
Skip to first unread message

Django

unread,
Mar 12, 2021, 3:05:41β€―AM3/12/21
to django-...@googlegroups.com
#32541: Separate context and rendering in forms
------------------------------------------------+------------------------
Reporter: Dylan Verheul | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: Forms | Version: 3.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 |
------------------------------------------------+------------------------
I've been working on packages that generate HTML based on Django forms for
a while. I find myself duplicating certain parts of Django code, because
there is no clear separation of the context (as in template context) that
is being generated, and the HTML output. A small example of this is the
code that renders the HTML for a label.

https://github.com/django/django/blob/76c0b32f826469320c59709d31e2f2126dd7c505/django/forms/boundfield.py#L133

This code takes arguments for and then generates contents (based on actual
contents and a suffix) and attrs and then generates HTML. It doe snot
always generate a label tag, which I find weird but is besides the point
of this issue.

My suggestion would be to split these kind of functions into a context
generator

{{{
def get_label_tag_context(self, contents=None, attrs=None,
label_suffix=None):
...
return {
"contents": ...,
"suffix": ...,
"attrs": ...,
}
}}}

And the actual rendering of the tag

{{{
def get_label_tag(self, contents=None, attrs=None, label_suffix=None):
context = self.get_label_tag_context(contents=contents, attrs=attrs,
label_suffix=label_suffix)
attrs = flatatt(context["attrs"]) if context["attrs"] else ""
return format_html('<label{}>{}</label>', attrs, context["contents"])
}}}

Now, if I want to write my own label renderer, I can get the exact same
context that Django uses.

For widgets, I would like to see the same solution. The context for a
widget is now part of the rendering process, and contains code that cannot
be rached unless you use Django rendering. If you want to apply different
rendering to a widget on a per widget basis, you have to duplicate code or
hack the generated HTML.

https://github.com/django/django/blob/76c0b32f826469320c59709d31e2f2126dd7c505/django/forms/boundfield.py#L80

Here, a split in generating context and rendering the context would also
help third party form packages to work with the same data Django has.

I'm creating this ticket to get feedback on the idea, and to see if a PR
separating context and rendering in the forms section of Django would be
welcome. I'd be willing to work on this.

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

Django

unread,
Mar 14, 2021, 3:03:55β€―AM3/14/21
to django-...@googlegroups.com
#32541: Separate context and rendering in forms
-------------------------------------+-------------------------------------

Reporter: Dylan Verheul | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Forms | Version: 3.1
Severity: Normal | Resolution:

Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Chris Jerdonek):

> I'm creating this ticket to get feedback on the idea, and to see if a PR
separating context and rendering in the forms section of Django would be
welcome. I'd be willing to work on this.

It's probably better to ask for feedback on the Django developers list:
https://docs.djangoproject.com/en/dev/internals/mailing-lists/#django-
developers
https://groups.google.com/g/django-developers

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

Django

unread,
Mar 14, 2021, 4:31:15β€―PM3/14/21
to django-...@googlegroups.com
#32541: Separate context and rendering in forms
-------------------------------------+-------------------------------------

Reporter: Dylan Verheul | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Forms | Version: 3.1
Severity: Normal | Resolution:

Keywords: | Triage Stage:
| Unreviewed
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 we need to be mindful of ticket #31026 and the associated
[https://github.com/django/django/pull/12133 pr] which moves forms to a
template render. For items such as labels they will be able to be
customised via overriding a temple, which could be enough here?

For widgets, there is already the ability to over ride templates, and if
you want to go futher I find that a boundfield's `subwidgets` usually has
the information needed to render each widget. For example, it can include
`selected` and built `attrs`. It's not clear from your ticket what extra
context you would need that is only available via django rendering?

Here's an example of the information available in a subwidget.

β”‚ choice_label = 1
β”‚ data = {
β”‚ 'name': 'checkbox_select_multiple',
β”‚ 'value': 1,
β”‚ 'label': 1,
β”‚ 'selected': True,
β”‚ 'index': '0',
β”‚ 'attrs': {'id': 'id_checkbox_select_multiple_0',
'checked': True},
β”‚ 'type': 'checkbox',
β”‚ 'template_name':
'django/forms/widgets/checkbox_option.html',
β”‚ 'wrap_label': True
β”‚ }
β”‚ id_for_label = 'id_checkbox_select_multiple_0'

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

Django

unread,
Mar 15, 2021, 1:32:56β€―AM3/15/21
to django-...@googlegroups.com
#32541: Separate context and rendering in forms
-------------------------------------+-------------------------------------

Reporter: Dylan Verheul | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: Forms | Version: 3.1
Severity: Normal | Resolution: duplicate

Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Dylan Verheul):

* status: new => closed
* resolution: => duplicate


Comment:

Thank you for pointing out #31026. This seems to at least partly resolve
the problem I describe, and it would be better to sit that one out before
taking any further action.

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

Django

unread,
Mar 16, 2021, 3:14:40β€―AM3/16/21
to django-...@googlegroups.com
#32541: Separate context and rendering in forms
-------------------------------------+-------------------------------------

Reporter: Dylan Verheul | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: Forms | Version: 3.1
Severity: Normal | Resolution: duplicate

Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Carlton Gibson):

Thanks both.

> I think we need to be mindful of ticket #31026...

Exactly right.

I loathe to say when anything might happen but, #31026 is β‰ˆtop of my long-
list for 4.0 so … πŸ˜€ β€”Β if you follow there Dylan you can see what remains
once we merge that.

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

Django

unread,
Mar 16, 2021, 4:47:25β€―AM3/16/21
to django-...@googlegroups.com
#32541: Separate context and rendering in forms
-------------------------------------+-------------------------------------

Reporter: Dylan Verheul | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: Forms | Version: 3.1
Severity: Normal | Resolution: duplicate

Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Dylan Verheul):

πŸ‘ Thanks both!

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

Reply all
Reply to author
Forward
0 new messages