Friday, December 19, 2014

Re: Model form with optional fields issue

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBCAAGBQJUlH8vAAoJEC0ft5FqUuEhlCUP/RgMmXmKdeeXZ6WDgpG6uT+9
zCMHWvscyGCEm3n63PExzdm9wDk7rRGoHW9+nlVWVW340Eg1uG/gJSdrHaWapGiI
rrd3lkiBMJ8bpi+HLKo6cW1hEjVQR7qUU8dpAN+ZEqIAmFbOE4gQEHRzQFGmlzDE
INzQE83eczky2b0hX6VOgbjJA/M/Dmy5+hD8A+0DKWnGyZ3kGMQhG+UIlVflWIiv
iMoH77D1ZW+5RAXjgM2CT6A7kFrhU5lxh963RmXRxEvTRBN5zSGKr5WgIzRwFY+f
qEtuloKt4yK+5b1N5nkbwnV/UH7fvl6yWW7WDzUnyUJuNYU0TswYCSoWbGWM9sFC
mlMq939sJr767KPie6CgjtvDA4q9l3/bD68A7lcXZIm4qeXI+tmZkUiECfdkh6va
ef3g9jd3MwzSTo9TVx/N/rLnyYpTUbF7vZxzS7H0NsqX/JD3djE62IIQXsKvZQMW
RVLCKTXJ5vRu2/9dHV2iwI1H5s7Gv8pyys3rucevYx2NK4LrqxCHhSmw1CGVPoxh
QBqbr32QkRAv9WmV7+hT/rwdUsyjURbWu2YczYo8SFwzFTSNDJ/Glq2iX5NcgQmC
8Fwt0ClnNpxeFp2aqpBk0eMMN/OLbAL1ToMEwKXVG+0AgDK4Ko8f7EwSTOY4TBHh
h1q1Q0tU3N4gY9mzgTjJ
=URrE
-----END PGP SIGNATURE-----
Hi Marcin,

On 12/19/2014 11:44 AM, marcin.j.nowak@gmail.com wrote:
> Hello!
>
> I have model form defined with all optional fields (required=False).
> I want use this form to update only provided fields leaving others
> unchanged.
> But Django replaces optional fields to empty values and removes data from
> models.
>
>
> A short example:
>
> class MyForm(forms.ModelForm):
> class Meta:
> model = User
> fields = ('username', 'email')
>
> def __init__(self, *args, **kw):
> super(MyForm, self).__init__(*args, **kw)
> for field in self.fields.values():
> field.required = False
>
>
> In [21]: admin = User.objects.get(username='admin')
>
> *In [22]: admin.email*
> *Out[22]: u'admin@example.com'*
>
> In [23]: form = MyForm(data={'username': 'admin'}, instance=admin)
>
> In [24]: form.is_valid()
> Out[24]: True
>
> In [25]: form.save()
> Out[25]: <User: admin>
>
> In [26]: admin = User.objects.get(username='admin')
>
> *In [27]: admin.email*
> *Out[27]: u''*
>
> In my opinion this is big, fat, ugly bug or a design misconception.
> If something is not provided does not mean that someting does not exist!
> Django should skip updating these unprovided fields by removig them from
> cleaned_data dict.
>
> You can even try to save this form without data (ok with data, but with
> unknown keys):
>
> form = MyForm(data={'unknownfield': 'some-value'}, instance=admin)
> form.is_valid()
>
> # form.cleaned_data has empty strings
>
> form.save()
>
>
> Username and email will be replaced with empty strings.
> Where is admin?, you'll ask... And you'll hear a strange voice - "admin is
> cooking borscht with ravioli, dude!"
>
> What do you think - is this expected?

Yes, this is expected. Django's form system is designed for use with
HTML forms, which do not provide partial data: unchanged field values
are sent too, so this problem does not occur.

That in itself wouldn't prevent switching to the behavior you want,
except that it is not compatible with how checkboxes are handled in HTML
forms. If a checkbox is unchecked, the browser will not send that
checkbox's name in the submitted POST data at all. So with the behavior
you're asking for, it would be impossible to ever change a boolean field
represented by a checkbox from True to False, using an HTML form.

Carl

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/54947F2F.9030304%40oddbird.net.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment