Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#18478 closed Cleanup/optimization (fixed)

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

Reported by: Enrico Zini 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 Tim Graham 4 years ago.

Download all attachments as: .zip

Change History (7)

comment:1 Changed 4 years ago by Aymeric Augustin

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset
Resolution: duplicate
Status: newclosed

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

comment:2 Changed 4 years ago by Enrico Zini

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 4 years ago by Aymeric Augustin

Component: UncategorizedDocumentation
Resolution: duplicate
Status: closedreopened
Triage Stage: UnreviewedAccepted
Type: UncategorizedCleanup/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 4 years ago by Tim Graham

Attachment: 18478.diff added

comment:4 Changed 4 years ago by Tim Graham

Cc: timograham@… added
Has patch: set

comment:5 Changed 4 years ago by Tim Graham <timograham@…>

Resolution: fixed
Status: reopenedclosed

In [6e2bb344e40dafdf462f6fb660837fa061faf549]:

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

comment:6 Changed 4 years 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

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