I would propose to change the behavior the following way:
Have `_html_output` produce a context and don't actually perform a render.
have each `as_XYZ` method get the context and perform a template based
render.
This allows to overwrite or add a new `as_XY` method and inject something
into the context or change the template.
This is also an opportunity to simplify the code. Since templates to
render attributes already exist.
--
Ticket URL: <https://code.djangoproject.com/ticket/31026>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* has_patch: 0 => 1
Comment:
I drafted something, to add more context, to what I am proposing:
https://github.com/django/django/pull/12133/files
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:1>
* stage: Unreviewed => Accepted
Comment:
I think that it makes sense. It'd be great if you could do a bit of
research on #15667 to figure if this was simply overlooked or if there was
a reason for not doing it in the first place.
I think there's also a ticket out there to allow `Form.__str__()` to use
`as_p` or `as_ul` instead of `as_table` by default. If we were using
template based rendering we could simply define a
`django/forms/default.html` that `{% include "django/forms/table.html"
%}`, use it in `.__str__()` and document that the former must be
overridden to achieve the desired behaviour.
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:2>
Comment (by Johannes Hoppe):
Yes, I'll take some time next week to do some research.
The default idea, is great. That would make it even more versatile, love
it!
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:3>
Comment (by Johannes Hoppe):
With that change I'd also like to drop
[error_class]https://docs.djangoproject.com/en/2.2/ref/forms/api
/#customizing-the-error-list-format support, since this would be a
template too. However, this is a documented API, though not widely used. I
will work around it for now, but I'd really like to remove it.
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:4>
Comment (by Johannes Hoppe):
Ok, I have a working patch now. It does not change tests, or removes much
code to prove its backwards compatible.
However, I'd like to introduce some changes, to improve the resulting
architecture and output.
1. Change the position of hidden inputs. Currently, they are injected at a
certain index. I'd like to simply amend them. It would greatly simplify
the templates. Since they are hidden, it shouldn't change browser
rendering.
2. I'd like to deprecate the now unused
`django.forms.BaseForm._html_output`. Yes, it is private, but we have
tests running against it and it's referenced in some tickets. This gives
me the impression is more commonly used than we'd like.
3. I'd like to deprecate `django.forms.boundfield.BoundField.label_tag`.
The label can be generated with a template with a simple include. I
believe this to be the better implementation.
4. Errors I would not change. I am not 100% happy with the design,
however, it is based on templates now, which makes adding changes simple.
I haven't written any documentation yet, this will be another monster
task. I'd like to get some feedback on the code side first, to avoid back
and forth.
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:5>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:6>
* needs_better_patch: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:7>
* needs_docs: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:8>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:9>
* needs_better_patch: 1 => 0
* needs_docs: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:10>
Comment (by Carlton Gibson):
I'm looking at the PR now, but I'll put this initial comment here, so it
doesn't get lost:
> Change the position of hidden inputs. Currently, they are injected at a
certain index. I'd like to simply amend them. It would greatly simplify
the templates. Since they are hidden, it shouldn't change browser
rendering.
From experience with Crispy Forms, I'm doubtful that we can just move
hidden fields to the end. Rendering, yes, would be unaffected. But the
resultant data-dict would not be. With multi-value field, as first
thought, order does matter. (I can't count the number of times we've seen
issues resolving around exact rendered field order on Crispy Forms...)
Open to be shown wrong here but... 😬
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:11>
Comment (by Carlton Gibson):
OK, scrub that last comment: existing rendering is **already** placing
hidden fields last, so data-dict is unaffected too.
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:12>
Comment (by Johannes Hoppe):
Yes, I can confirm this is the case. I actually prefer the new HTML
output, since we don't just amend hidden fields within the parent of
another field.
So all this needs is a thorough review ;) Can't review it myself, but I am
trading :P
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:13>
* needs_better_patch: 0 => 1
* needs_tests: 0 => 1
* needs_docs: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:14>
* needs_better_patch: 1 => 0
* needs_tests: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:15>
* needs_docs: 1 => 0
Comment:
I'm going to uncheck the Needs Documentation to put this back in the
review queue.
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:16>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:17>
* needs_better_patch: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:18>
* owner: nobody => Johannes Maron
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:19>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:20>
* owner: Johannes Maron => David Smith
* needs_better_patch: 1 => 0
Comment:
[https://github.com/django/django/pull/14819 New PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:21>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"91e8b95d5ba8e296148ba6e2a1c856319c6e6ebc" 91e8b95d]:
{{{
#!CommitTicketReference repository=""
revision="91e8b95d5ba8e296148ba6e2a1c856319c6e6ebc"
Refs #31026 -- Moved Template tests to separate class.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:22>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"4ca508a68916dd43da45fd6e8b9004824a62d9c8" 4ca508a6]:
{{{
#!CommitTicketReference repository=""
revision="4ca508a68916dd43da45fd6e8b9004824a62d9c8"
Refs #31026 -- Added extra form render tests.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:23>
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:24>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"456466d932830b096d39806e291fe23ec5ed38d5" 456466d]:
{{{
#!CommitTicketReference repository=""
revision="456466d932830b096d39806e291fe23ec5ed38d5"
Fixed #31026 -- Switched form rendering to template engine.
Thanks Carlton Gibson, Keryn Knight, Mariusz Felisiak, and Nick Pope
for reviews.
Co-authored-by: Johannes Hoppe <in...@johanneshoppe.com>
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:25>
Comment (by GitHub <noreply@…>):
In [changeset:"881a4799114fccefbc0f56c6524110ede2682e16" 881a479]:
{{{
#!CommitTicketReference repository=""
revision="881a4799114fccefbc0f56c6524110ede2682e16"
Refs #31026 -- Fixed forms_tests if Jinja2 is not installed.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:26>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"bc1fa8ebcd9adbe969261b07337d1cad4852edfb" bc1fa8eb]:
{{{
#!CommitTicketReference repository=""
revision="bc1fa8ebcd9adbe969261b07337d1cad4852edfb"
[4.0.x] Refs #31026 -- Fixed forms_tests if Jinja2 is not installed.
Backport of 881a4799114fccefbc0f56c6524110ede2682e16 from main
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:27>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"9be36f8044c3bdfe5d1819d4b3b62bee64a039e3" 9be36f8]:
{{{
#!CommitTicketReference repository=""
revision="9be36f8044c3bdfe5d1819d4b3b62bee64a039e3"
Refs #31026 -- Improved BoundField.label_tag() docs.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:28>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"fc325a198169663c67939c210a538029eea728f7" fc325a19]:
{{{
#!CommitTicketReference repository=""
revision="fc325a198169663c67939c210a538029eea728f7"
[4.0.x] Refs #31026 -- Improved BoundField.label_tag() docs.
Backport of 9be36f8044c3bdfe5d1819d4b3b62bee64a039e3 from main
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:29>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"78f062f63e7dea09c219fd1310d43950817f4c78" 78f062f6]:
{{{
#!CommitTicketReference repository=""
revision="78f062f63e7dea09c219fd1310d43950817f4c78"
Refs #31026 -- Updated TemplatesSetting docs to refer to forms.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:30>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"a0e01b000a0d1960cf23f35daf9c60f812671f3b" a0e01b00]:
{{{
#!CommitTicketReference repository=""
revision="a0e01b000a0d1960cf23f35daf9c60f812671f3b"
[4.0.x] Refs #31026 -- Updated TemplatesSetting docs to refer to forms.
Backport of 78f062f63e7dea09c219fd1310d43950817f4c78 from main
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:31>
Comment (by GitHub <noreply@…>):
In [changeset:"03a648811615cb623affc2d79dccd4b05919319e" 03a64881]:
{{{
#!CommitTicketReference repository=""
revision="03a648811615cb623affc2d79dccd4b05919319e"
Refs #31026 -- Changed @jinja2_tests imports to be relative.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:32>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"3f5d43ce5489f44959a57018d8ea89df799ca3d5" 3f5d43ce]:
{{{
#!CommitTicketReference repository=""
revision="3f5d43ce5489f44959a57018d8ea89df799ca3d5"
[4.0.x] Refs #31026 -- Changed @jinja2_tests imports to be relative.
Backport of 03a648811615cb623affc2d79dccd4b05919319e from main
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:33>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"31878b4d7387835c5cec5e7fc5b473b737065a58" 31878b4d]:
{{{
#!CommitTicketReference repository=""
revision="31878b4d7387835c5cec5e7fc5b473b737065a58"
Refs #31026 -- Removed ability to return string when rendering
ErrorDict/ErrorList.
Per deprecation timeline.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:35>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"182d25eb7a227206746bfa30aab13aaa34d1de84" 182d25e]:
{{{
#!CommitTicketReference repository=""
revision="182d25eb7a227206746bfa30aab13aaa34d1de84"
Refs #31026 -- Removed BaseForm._html_output() per deprecation timeline.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:34>
Comment (by GitHub <noreply@…>):
In [changeset:"f1697ec7c8fc851baa9c890a605acb67f04210f2" f1697ec]:
{{{
#!CommitTicketReference repository=""
revision="f1697ec7c8fc851baa9c890a605acb67f04210f2"
Refs #31026 -- Simplified BaseForm.get_context().
bf.errors returns an ErrorList. Access this directly and avoid creating
a new instance in BaseForm.get_context()
Calling str() on the ErrorList can also be deferred to when the
variable used in the template.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31026#comment:36>