Opened 5 years ago

Closed 3 years ago

#20154 closed Bug (fixed)

Inconsistent model save behavior when assigning model instances to CharFields

Reported by: adsva Owned by: nobody
Component: Database layer (models, ORM) Version: master
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 Tim Graham)


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):

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(
>>> u'Sweden'
>>> Address.objects.get(
>>> '1'

I do realize I should assign 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 Changed 5 years ago by schmilblick

Cc: schmilblick added

comment:2 Changed 5 years ago by Matt

Cc: Matt added
Triage Stage: UnreviewedAccepted
Version: 1.4master

This also seems odd to me. Here's a test case to demonstrate it:


comment:3 Changed 3 years ago by Tim Graham

Description: modified (diff)
Resolution: fixed
Status: newclosed

This is fixed in Django 1.9. The test in the shell session will now given an error message, "TypeError: Tried to update field with a model instance, <Country: Sweden>. Use a value compatible with CharField." (and similar for the test provided in the link of comment 2).

Note: See TracTickets for help on using tickets.
Back to Top