The correct use would be:
<input type="email" required />
Currently in forms.py attributes cannot be specified without a value which
rely on the author knowing that a value of 'true' not being valid but
'required' being ok. it would be great if Django supports valueless
attributes.
Perhaps doing:
widget=forms.TextInput(
attrs={
'required': ''
}))
will result in an input of:
<input type="text" required />
--
Ticket URL: <https://code.djangoproject.com/ticket/20684>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0
Old description:
> There are a couple of form attributes such as required that was
> introduced in HTML5 that should not contain a value. For exaple
> required="required" is valid but for example required="true" will result
> in failed validation with true being marked as a bad value.
>
> The correct use would be:
>
> <input type="email" required />
>
> Currently in forms.py attributes cannot be specified without a value
> which rely on the author knowing that a value of 'true' not being valid
> but 'required' being ok. it would be great if Django supports valueless
> attributes.
>
> Perhaps doing:
>
> widget=forms.TextInput(
> attrs={
> 'required': ''
> }))
>
> will result in an input of:
>
> <input type="text" required />
New description:
There are a couple of form attributes such as required that was introduced
in HTML5 that should not contain a value. For exaple required="required"
is valid but for example required="true" will result in failed validation
with true being marked as a bad value.
The correct use would be:
{{{<input type="email" required />}}}
Currently in forms.py attributes cannot be specified without a value which
rely on the author knowing that a value of 'true' not being valid but
'required' being ok. it would be great if Django supports valueless
attributes.
Perhaps doing:
{{{
widget=forms.TextInput(
attrs={
'required': ''
}))
}}}
will result in an input of:
{{{<input type="text" required />}}}
--
Comment:
Description reformatted, please use preview when posting.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:1>
* stage: Unreviewed => Accepted
Comment:
Agreed. However I'd rather use `None` instead of the empty string to mean
no attribute value, because there might be cases where an empty value is
wanted.
At first sight, this seems rather trivial to implement in `flatatt`
(https://github.com/django/django/blob/master/django/forms/util.py#L15).
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:2>
Comment (by shai):
Actually, I'd rather use some special marker rather than None -- most such
attributes are essentially boolean, and None -- which is False when
evaluated as a boolean -- would come to mark True, and this can be
confusing.
I'd introduce a new constant, and call it NoValue -- probably along the
lines of `class NoValue(object): pass`. Then you could write
{{{
widget=forms.TextInput(
attrs={
'required': NoValue
}))
}}}
And also have correct behavior on things like `if
widget.attrs['required']: ...`
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:3>
Comment (by loic84):
As Shai pointed out, these *are* booleans
(http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#boolean-
attributes), why not treat them as such?
Value in python should be either True or False, False behing noop in
`flatatt()`
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:4>
* cc: loic@… (added)
* needs_better_patch: 0 => 1
* version: 1.5 => master
* easy: 0 => 1
* needs_docs: 0 => 1
* has_patch: 0 => 1
Comment:
POC: https://github.com/loic/django/compare/ticket20684
I'll write the docs for it if that's validated.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:5>
Comment (by charettes):
As @claudep initially suggested I would have chosen `None` for that but in
the light of @shai's comment I think @loic84's approach is the correct
one.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:6>
Comment (by loic84):
Interestingly comments on a feature branch get lost upon forced pushes.
@charettes wasn't convinced that the `False` value was necessary.
I brought up the use case of setting the value programmatically with an
expression like `'required': is_required()` and we agreed that it could be
useful.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:7>
Comment (by shai):
Yes, this makes a lot of sense; the reason I suggested a special marker is
backwards-compatibility -- if code exists which relies on the value being
converted to string, and so expects that attr=True will manifest in HTML
as `attr="True"`, this may very well break it.
I still find it preferable to use a special marker -- but I guess
`NoValue` is a bad name.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:8>
* cc: shai@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:9>
Comment (by loic84):
A special marker is a bit overkill IMO and it's not exactly convenient
since you have to import it before using it.
Also relying on the implicit conversion of `True` to `"True"` is not a
pattern we should encourage, we could list the change as backward
incompatible in the release notes.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:10>
Comment (by shai):
Replying to [comment:10 loic84]:
>
> Also relying on the implicit conversion of `True` to `"True"` is not a
pattern we should encourage,
Why not? Especially in `data-` attributes?
> we could list the change as backward incompatible in the release notes.
>
Yes, but exactly because of the `"required": is_required()` pattern you
brought up, uses may be hard to detect.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:11>
Comment (by loic84):
Replying to [comment:11 shai]:
> Replying to [comment:10 loic84]:
> >
> > Also relying on the implicit conversion of `True` to `"True"` is not a
pattern we should encourage,
>
> Why not? Especially in `data-` attributes?
Because explicit is better than implicit, people who really want `"True"`
should cast the boolean to a string.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:12>
Comment (by charettes):
Replying to [comment:11 loic84]:
> A special marker is a bit overkill IMO and it's not exactly convenient
since you have to import it before using it.
It is also overkill IMO. W3 defined the semantic of boolean attributes and
I think we should try to stick to it. As pointed out by @loic84 a release
note concerning backward compatibility should be enough.
Replying to [comment:12 loic84]:
> Because explicit is better than implicit, people who really want
`"True"` should cast the boolean to a string.
Agreed that `True` -> `"True"` implicit conversion is not a pattern we
should encourage.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:13>
Comment (by shai):
I don't feel very strongly about this, but I'm also not convinced. In my
opinion, we shouldn't make code stop working unless it's required to fix a
bug, or the code that gets broken can be seen as a bug. IMO, this feature
is not important enough, and the implicit conversion is not buggy enough,
to justify a breaking change.
But maybe that's just me.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:14>
Comment (by claudep):
I can see the point of Shai, but I'd tend to agree with the boolean
version also.
We are not in a hurry though, so let's see if others have strong opinions
about this.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:15>
Comment (by anonymous):
Having slept about it,
(a) I concede that the implicit conversion should not be encouraged, and
(b) I agree that a special marker would be, essentially, interface cruft
that we would keep just for the benefit of something we don't really want.
But backwards compatibility still is a problem; I suggest to solve it with
a deprecation cycle. Given (a) above, I think even an expedited cycle may
be enough.
So,
Django 1.7:
`{'attr':True}` becomes `attr="True"`, with `DeprecationWarning('The
meaning of Boolean values for widget attributes will change in Django
1.8')`
Django 1.8:
`{'attr':True}` becomes `attr`
What do you think?
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:16>
Comment (by shai):
(comment:16 is me, of course).
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:17>
Comment (by claudep):
@shai: good idea, however I don't see anything preventing us from
advancing the planning: Deprecation on 1.6 and change in 1.7.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:18>
Comment (by loic84):
+1 I'll write the doc for the original patch and I'll write another one
that simply raises a DeprecationWarning against the 1.6 branch.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:19>
Comment (by shai):
Replying to [comment:18 claudep]:
> I don't see anything preventing us from advancing the planning:
Deprecation on 1.6 and change in 1.7.
I was under the impression that 1.6 was feature-frozen at this stage.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:20>
Comment (by loic84):
There wouldn't be any new feature, only a `DeprecationWarning`.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:21>
Comment (by carljm):
I'd always been under the impression that new deprecations should not be
introduced after the beta, either (unless absolutely necessary, e.g. a
security fix). The point of the feature freeze is to avoid regressions
after the beta, so that people can test their codebase on 1.6 beta and
trust (as much as possible) that it will still work without further
changes on 1.6 final. Adding a deprecation breaks this (for some people
it's a blocker or even breaks CI if their codebase begins to emit a
warning). I would hesitate to even add a `PendingDeprecationWarning` post-
beta, let alone an accelerated `DeprecationWarning`.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:22>
Comment (by loic84):
@carljm: That feature will completely stall until 1.8 otherwise, 1.9 even
if it doesn't go through an accelerated cycle.
I think we are being extra cautious already by offering a deprecation
path, I don't think we should delay it by a couple of years.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:23>
Comment (by shai):
@loic84: Django is now moving to a shorter version cycle; if all goes
well, 1.6 will come only ~8 months after 1.5.
More generally, I don't see why this feature is so urgent. Yes, it's nice,
but it doesn't even really enable new functionality.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:24>
Comment (by charettes):
@loic84: I agree with @shai that this feature is not that urgent, users
can still ''workaround'' it by specifying `'required': 'required'` and
output valid markup.
We've lived with `'checked': 'checked'` and `'selected': 'selected'` for a
while now.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:25>
Comment (by claudep):
OK, then do we agree on the fast Deprecation process as proposed in
comment:16 ? Let's consider that we are still talking about corner cases.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:26>
Comment (by Claude Paroz <claude@…>):
In [changeset:"1116df0751cc0d5862590b08adfffe7bacd6bf43"]:
{{{
#!CommitTicketReference repository=""
revision="1116df0751cc0d5862590b08adfffe7bacd6bf43"
Deprecate usage of boolean value for widget attributes
Django 1.7 will loudly warn when widget attributes are assigned
boolean values. In Django 1.8, False will mean attribute is not
present while True will mean attribute present without value.
Refs #20684.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:27>
Comment (by jacob):
This is a pretty bad error message - `'The meaning of boolean values for
widget attributes will change in Django 1.8'` doesn't give anyone any
clues about *what* will change, what it'll change *to*, and what they
should do about it.
Can we think a bit and change this error message to something more user-
friendly?
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:28>
Comment (by jcd):
Here are some thoughts on the deprecation warning text.
One option is to name the feature that we are implementing (HTML5 boolean
attributes).
"Starting in Django 1.x, widget attributes with boolean values will
render according to the rules for HTML5 boolean attributes."
If they don't know what that means, they have the search term for HTML5
boolean attributes. I admit this is still a little obtuse for users who
aren't familiar with all the rules for HTML5, but it's also terse.
Explaining the new feature in the DeprecationWarning will be a bit verbose
for a one-line warning, but could be done:
"Starting in Django 1.x, the rendering of attributes with boolean
values will change; Attributes marked True will render as the name of the
attribute, and attributes marked False will not render at all [in
accordance with the rules for HTML5 boolean attributes."
Alternatively, we could separate out true and false values into separate
DeprecationWarnings, so we can be explicit about exactly what will happen
and why, while still being terse..
True: "Starting in Django 1.x, widget attributes set to 'True' will
render as the name of the attribute with no value, in accordance with the
rules for HTML5 boolean attributes."
False: "Starting in Django 1.x, widget attributes set to 'False' will
not be rendered, in accordance with the rules for HTML5 boolean
attributes."
I think my preference would be for separate True and False
DeprecationWarnings.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:29>
Comment (by jcd):
For more verbosity (to answer @jacob's question of what they should do
about it):
(4) True: "Starting in Django 1.x, widget attributes set to True will
render as the name of the attribute with no value, in accordance with the
rules for HTML5 boolean attributes. If you want your HTML attribute set
to the value "True", use the string 'True' instead of the boolean True.
False: "Starting in Django 1.x, widget attributes set to False will
not be rendered, in accordance with the rules for HTML5 boolean
attributes. If you want your HTML attribute set to the value "False" use
the string 'False' instead of the boolean False.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:30>
* cc: jcd@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:31>
Comment (by shai):
Constant string: `Starting from Django 1.8, boolean values to widget
attributes will determine if the attribute appears (with no value). To
preserve current behavior, use string values explicitly`.
Or, taking the approach of @jcd -- why not go all the way?
When value is True: `Starting from Django 1.8, widget attribute
%(attr_name)s=True will be rendered as '%(attr_name)s'. To preserve
current behavior, use the string 'True' instead of the boolean True.`
When value is False: `Starting from Django 1.8, widget attribute
%(attr_name)s=False will be not be rendered. To preserve current behavior,
use the string 'False' instead of the boolean False.`
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:32>
Comment (by Tim Graham <timograham@…>):
In [changeset:"8165c2cfd1922bb9d56a9e68e6456736acacf445"]:
{{{
#!CommitTicketReference repository=""
revision="8165c2cfd1922bb9d56a9e68e6456736acacf445"
Improved deprecation warning for change in form boolean values.
refs #20684
Thanks jacob, jcd, and shai for the suggestions.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:33>
* easy: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:34>
Comment (by timo):
This ticket can now move forward on master. Loic, if you'd like to update
your branch and write the documentation, I'll merge it.
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:35>
* needs_better_patch: 1 => 0
* needs_docs: 1 => 0
Comment:
PR https://github.com/django/django/pull/2462
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:36>
* status: new => closed
* resolution: => fixed
Comment:
In [changeset:"e61d99d96daedfea2f6ba071945ef0d2f86883c7"]:
{{{
#!CommitTicketReference repository=""
revision="e61d99d96daedfea2f6ba071945ef0d2f86883c7"
Fixed #20684 -- Added support for HTML5 boolean attributes to form
widgets.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/20684#comment:37>