Donald Backward compatibility can be maintained with just a log warning to give developer time to clean up code or throwing an exception when `settings.DEBUG=True` and only log warning when `False`; I am not sure how this ought to be implemented but again I am big +1 for this proposal.
On Thu, Jan 12, 2012 at 4:02 AM, Tai Lee <real.hu...@mrmachine.net> wrote: > Donald, > > Thanks for sharing your feedback with everyone. > > I do believe that there should be some kind of validation error or at > least a loud warning to the console or logs when a form is bound to > incomplete data. The only time when this should occur is for > "unsuccessful controls" such as unchecked radio buttons and > checkboxes. These shouldn't be a problem for Django, which already > normalises no value for a checkbox to False and any value for it to > True. > > I'm not sure that there is a widespread practice of submitting partial > forms with JS and still expecting the entire form to validate and save > is widespread, or even valid according to the RFC and HTML4 specs > which expect every successful control to be included in the form data. > > Sure, I can see that forms could be fully or even partially submitted > via JS to perform AJAX validation in real time, but I don't see how > the form as a whole being invalid and validation errors on the missing > fields would impact that. > > If we can't find a clear definition or distinction between null and an > empty string in the RFC or HTML4 specs, and we go to our browser (you > mentioned Chrome), I think you will find that they consider text input > fields with an empty string as the value are "successful controls", as > these are included in the form data. > > Before knocking back this proposal on the grounds of ambiguous specs > (multiple interpretations), I would like to know if there are actually > any UAs that behave as you fear they might. If there are, then this > change would definitely be a problem for those UAs. > > However, even in the event that this is deemed a backwards > incompatible change and the potential silent data loss issue is not > serious enough to override that, then a loud warning could still be > added without changing the current behaviour. > > Cheers. > Tai. > > > On Jan 12, 3:29 am, Donald Stufft <donald.stu...@gmail.com> wrote: > > I'm very much -1 on this change. > > > > To "fix" this change would require throwing an error anytime an > incomplete dictionary was passed as the data arg to a form. This would > break any existing code that relies on this (in particular it's common > practice to accept a subset of the fields via json). So this would be a > backwards incompatible change. > > > > Further more I disagree with the interpretation of the RFC as provided. > The RFC states that any UA may choose to not send along a form field if it > contains a null value. So the question then becomes what is a null value in > regards to the RFC? As I cannot find any mention of what constitutes a null > value in the RFC I went to my browser. Using javascript I executed > ``document.getElementById('textfield').value = null`` in the js console. > The result was that the value was set to "". So in my browser (Chrome on OS > X) it is treating null and "" with equivalence. > > > > Going by my personal interpretation of the RFC, and Chrome's behavior in > my javascript test I can only conclude that the proposed change would cause > Django forms to violate the RFC spec and while Violating the RFC spec in > and of itself isn't always the wrong thing to do I do believe that it > should only be done when RFC and implementations are at odds in a way that > are incompatible with each other. In this case they are not, and the RFC is > more permissive and should be followed as Django does not have a list of > supported browsers so we must strive to follow the RFC's where we can (and > where they are actually defined) and deviate only when the alternative is > being broken in major browsers. > > > > Additionally I believe in this case there are two major error conditions. > > > > A) The proposed change is made, a visitor is using a UA that I believe > follows the RFC and any Django forms with optional, and unfilled in values > stop working for this visitor. > > B) The proposed change is not made, and when an optional form field is > left off of a form (or json, or any partially incomplete dictionary of > values) the form assumes the default initial value of "". > > > > Neither error condition is optimal, however A has the additional > downside that this error is completely outside of the control of the > developer whereas B is the result of developer error and is under his > control. > > > > > > > > > > > > > > > > On Tuesday, January 10, 2012 at 8:38 PM, Tai Lee wrote: > > > There is a potential for data loss with optional form fields that are > > > (for whatever reason) omitted from an HTML template. > > > > > For example, if we take an existing model form and template that > > > works, add an optional character field to the model but fail to add a > > > corresponding field to the HTML template (e.g. human error, forgot > > > about a template, didn't tell the template author to make a change, > > > didn't realise a change needed to be made to a template), when that > > > form is submitted Django will assume that the user has provided an > > > empty string value for the missing field and save that to the model, > > > erasing any existing value. This is not a bug, but it is relatively > > > easy to trigger silent and unexpected data loss. > > > > > I have briefly discussed this with PaulM and dstufft on django-dev, > > > but could did not reach any consensus. > > > > > RFC1866 [1] says: > > > > > > The fields are listed in the order they appear in the > > > > document with the name separated from the value by `=' and > > > > the pairs separated from each other by `&'. Fields with null > > > > values may be omitted. In particular, unselected radio > > > > buttons and checkboxes should not appear in the encoded > > > > data, but hidden fields with VALUE attributes present > > > > should. > > > > > The HTML4 spec at W3C.org (http://W3C.org) [2] says: > > > > > > Users interact with forms through named controls. > > > > > > A control's "control name" is given by its name attribute. The scope > of the > > > > name attribute for a control within a FORM element is the FORM > element. > > > > > > Each control has both an initial value and a current value, both of > which are > > > > character strings. Please consult the definition of each control for > > > > information about initial values and possible constraints on values > imposed by > > > > the control. In general, a control's "initial value" may be > specified with the > > > > control element's value attribute. However, the initial value of a > TEXTAREA > > > > element is given by its contents, and the initial value of an OBJECT > element > > > > in a form is determined by the object implementation (i.e., it lies > outside > > > > the scope of this specification). > > > > > > The control's "current value" is first set to the initial value. > Thereafter, > > > > the control's current value may be modified through user interaction > and > > > > scripts. > > > > > > A control's initial value does not change. Thus, when a form is > reset, each > > > > control's current value is reset to its initial value. If a control > does not > > > > have an initial value, the effect of a form reset on that control is > > > > undefined. > > > > > > When a form is submitted for processing, some controls have their > name paired > > > > with their current value and these pairs are submitted with the > form. Those > > > > controls for which name/value pairs are submitted are called > successful > > > > controls. > > > > > as well as [3]: > > > > > > A successful control is "valid" for submission. Every successful > control has > > > > its control name paired with its current value as part of the > submitted form > > > > data set. A successful control must be defined within a FORM element > and must > > > > have a control name. > > > > > > However: > > > > > > * Controls that are disabled cannot be successful. > > > > * If a form contains more than one submit button, only the activated > submit > > > > button is successful. > > > > * All "on" checkboxes may be successful. > > > > * For radio buttons that share the same value of the name attribute, > only the > > > > "on" radio button may be successful. > > > > * For menus, the control name is provided by a SELECT element and > values are > > > > provided by OPTION elements. Only selected options may be > successful. When > > > > no options are selected, the control is not successful and neither > the name > > > > nor any values are submitted to the server when the form is > submitted. > > > > * The current value of a file select is a list of one or more file > names. Upon > > > > submission of the form, the contents of each file are submitted with > the > > > > rest of the form data. The file contents are packaged according to > the > > > > form's content type. > > > > * The current value of an object control is determined by the > object's > > > > implementation. > > > > > > If a control doesn't have a current value when the form is > submitted, user > > > > agents are not required to treat it as a successful control. > > > > > > Furthermore, user agents should not consider the following controls > > > > successful: > > > > > > * Reset buttons. > > > > * OBJECT elements whose declare attribute has been set. > > > > > > Hidden controls and controls that are not rendered because of style > sheet > > > > settings may still be successful. > > > > > I interpret the above to mean that any text input with a value > > > attribute (even `value=""`) is successful control, and should be > > > included in the encoded form data. This is what current versions of > > > Chrome and Firefox do, at least. I have not found any examples of > > > browsers which are known not to do this. > > > > > What I would like to change in Django is for it to stop assuming that > > > missing POST data for a character field is actually an empty string, > > > and instead raise a form validation error that would prevent the model > > > instance from being saved to the database (potentially causing data > > > loss for that field). > > > > > I don't see any benefit in the current behaviour, except to > > > potentially support undetermined and unspecified UAs which might treat > > > form fields as unsuccessful controls if the have an empty string as > > > their value, and if those UAs accordingly do not include those fields > > > in the encoded form data. Even if such UAs were found, I would argue > > > that the RFC and HTML4 specs show that text fields with a value (even > > > an empty string) are successful controls that should be included. > > > > > Failing that, I would like for Django to at least raise a loud warning > > > when a form is bound to data is missing values for character fields, > > > so that it will at least be easier to detect this silent and > > > unexpected data loss in a test environment, before it occurs in a > > > production environment. > > > > > Does anybody else have opposing or supporting arguments, or any > > > knowledge of actual UAs that do not include fields with empty values > > > in their encoded form data, or an alternative interpretation of the > > > RFC and HTML4 specs above? > > > > > Cheers. > > > Tai. > > > > > [1]http://www.rfc-editor.org/rfc/rfc1866.txt > > > [2]http://www.w3.org/TR/html4/interact/forms.html#h-17.2 > > > [3]http://www.w3.org/TR/html4/interact/forms.html#successful-controls > > > > > -- > > > You received this message because you are subscribed to the Google > Groups "Django developers" group. > > > To post to this group, send email to > django-developers@googlegroups.com (mailto: > django-developers@googlegroups.com). > > > To unsubscribe from this group, send email to > django-developers+unsubscr...@googlegroups.com (mailto: > django-developers+unsubscr...@googlegroups.com). > > > For more options, visit this group athttp:// > groups.google.com/group/django-developers?hl=en. > > -- > You received this message because you are subscribed to the Google Groups > "Django developers" group. > To post to this group, send email to django-developers@googlegroups.com. > To unsubscribe from this group, send email to > django-developers+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/django-developers?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.