Opened 12 years ago
Closed 9 years ago
#20154 closed Bug (fixed)
Inconsistent model save behavior when assigning model instances to CharFields — at Version 3
Reported by: | adsva | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | schmilblick, Matt | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
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
.
Change History (3)
comment:1 by , 12 years ago
Cc: | added |
---|
comment:2 by , 12 years ago
Cc: | added |
---|---|
Triage Stage: | Unreviewed → Accepted |
Version: | 1.4 → master |
comment:3 by , 9 years ago
Description: | modified (diff) |
---|---|
Resolution: | → fixed |
Status: | new → closed |
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).
This also seems odd to me. Here's a test case to demonstrate it: https://github.com/pegler/django/compare/20154
Best,
Matt