Opened 23 months ago

Closed 20 months ago

Last modified 20 months ago

#18478 closed Cleanup/optimization (fixed)

Field.get_default will stringify everything that isn't a callable

Reported by: enrico Owned by: nobody
Component: Documentation Version: 1.4
Severity: Normal Keywords:
Cc: timograham@… Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


I'm using a JSON-encoded field that can take any python data structure as default, this way:

info = fields.ContactInfoField("Contact info", blank=True, default={"a":u"I ♥ Django"})

and found out that I was getting "{'a': u'I \\u2665 Django'}" as a default value in my model objects.

I tracked it down to Field.get_default, which stringifies all non-callables:

    def get_default(self):
        Returns the default value for this field.
        if self.has_default():
            if callable(self.default):
                return self.default()
            return force_unicode(self.default, strings_only=True)
        if (not self.empty_strings_allowed or (self.null and
                   not connection.features.interprets_empty_strings_as_nulls)):
            return None
        return ""

Indeed this works as expected:

info = fields.ContactInfoField("Contact info", blank=True, default=lambda:{{"a":u"I ♥ Django"})

I cannot understand the reason for the different treatment of values and callables, and comments don't help. Field documentation does not mention this behaviour either. From what little I can understand, this looks like a bug,

Attachments (1)

18478.diff (898 bytes) - added by timo 20 months ago.

Download all attachments as: .zip

Change History (7)

comment:1 Changed 22 months ago by aaugustin

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to duplicate
  • Status changed from new to closed

Duplicate of #8633, and the reason is explained there.

comment:2 Changed 22 months ago by enrico

Thanks for linking this to #8633, I'm sorry I didn't find it myself.

I reckon the information in #8633 is rather relevant for people creating custom field types. Would it make sense to have it mentioned in the Field documentation, rather than hidden in an old bug log?

comment:3 Changed 22 months ago by aaugustin

  • Component changed from Uncategorized to Documentation
  • Resolution duplicate deleted
  • Status changed from closed to reopened
  • Triage Stage changed from Unreviewed to Accepted
  • Type changed from Uncategorized to Cleanup/optimization

Well, it took me a bit of time to find it, and I wasn't aware of this reason :)

Accepting as a documentation issue.

Changed 20 months ago by timo

comment:4 Changed 20 months ago by timo

  • Cc timograham@… added
  • Has patch set

comment:5 Changed 20 months ago by Tim Graham <timograham@…>

  • Resolution set to fixed
  • Status changed from reopened to closed

In [6e2bb344e40dafdf462f6fb660837fa061faf549]:

Fixed #18478 - Documented how to use a mutable default in a model field.

comment:6 Changed 20 months ago by Tim Graham <timograham@…>

In [cd5181f84c7d4f2002efb777b6cf042771135f7a]:

[1.4.X] Fixed #18478 - Documented how to use a mutable default in a model field.

Backport of 6e2bb344e4 from master

Add Comment

Modify Ticket

Change Properties
<Author field>
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'

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

Note: See TracTickets for help on using tickets.