Opened 13 months ago

Last modified 13 months ago

#20154 new Bug

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, pegler Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no



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

Attachments (0)

Change History (2)

comment:1 Changed 13 months ago by schmilblick

  • Cc schmilblick added
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

comment:2 Changed 13 months ago by pegler

  • Cc pegler added
  • Triage Stage changed from Unreviewed to Accepted
  • Version changed from 1.4 to master

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


Add Comment

Modify Ticket

Change Properties
<Author field>
as new
The owner will be changed from nobody to anonymous. Next status will be 'assigned'
as The resolution will be set. Next status will be 'closed'

E-mail address and user name can be saved in the Preferences.

Note: See TracTickets for help on using tickets.