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 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.