#20154: Inconsistent model save behavior when assigning model instances to
CharFields
-------------------------------------+-------------------------------------
Reporter: adsva | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):
* status: new => closed
* resolution: => fixed
Old description:
> Hi,
>
> When I assign a model instance to a CharField on a model and save the
> instance, it gets saved as the string representation of the instance on
> insert, but as the string representation of the instance's pk on update.
> {{{
> from django.db import models
>
> class Country(models.Model):
> name = models.CharField(max_length=100)
> def __unicode__(self):
> return name
>
> class Address(models.Model):
> country = models.CharField(max_length=100)
> }}}
> {{{
> >>> c = Country.objects.get(name='Sweden')
> >>> a = Address.objects.create(country=c)
> >>> Address.objects.get(pk=a.pk).country
> >>> u'Sweden'
> >>> a.save()
> >>> Address.objects.get(pk=a.pk).country
> >>> '1'
> }}}
>
> I do realize I should assign c.name instead if c, but it feels like a bug
> to treat values differently on insert vs update.
>
> The reason seems to be that `SQLUpdateCompiler.as_sql` preps the value
> using `val.prepare_database_save` if available, whereas
> `SQLInsertCompiler.as_sql` always uses `field.get_db_prep_save`.
New description:
Hi,
When I assign a model instance to a CharField on a model and save the
instance, it gets saved as the string representation of the instance on
insert, but as the string representation of the instance's pk on update.
{{{
from django.db import models
class Country(models.Model):
name = models.CharField(max_length=100)
def __unicode__(self):
return self.name
class Address(models.Model):
country = models.CharField(max_length=100)
}}}
{{{
>>> c = Country.objects.get(name='Sweden')
>>> a = Address.objects.create(country=c)
>>> Address.objects.get(pk=a.pk).country
>>> u'Sweden'
>>> a.save()
>>> Address.objects.get(pk=a.pk).country
>>> '1'
}}}
I do realize I should assign c.name instead if c, but it feels like a bug
to treat values differently on insert vs update.
The reason seems to be that `SQLUpdateCompiler.as_sql` preps the value
using `val.prepare_database_save` if available, whereas
`SQLInsertCompiler.as_sql` always uses `field.get_db_prep_save`.
--
Comment:
This is fixed in Django 1.9. The test in the shell session will now given
an error message, "TypeError: Tried to update field
tix20154.Address.country with a model instance, <Country: Sweden>. Use a
value compatible with CharField." (and similar for the test provided in
the link of comment 2).
--
Ticket URL: <https://code.djangoproject.com/ticket/20154#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/063.d8f27fa7f0fcfcb6c7191054375e182f%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.