Opened 3 years ago

Closed 3 years ago

Last modified 3 years 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

Description

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 3 years ago.

Download all attachments as: .zip

Change History (7)

comment:1 Changed 3 years 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 3 years 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 3 years 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 3 years ago by timo

comment:4 Changed 3 years ago by timo

  • Cc timograham@… added
  • Has patch set

comment:5 Changed 3 years 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 3 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