Opened 10 years ago

Closed 10 years ago

Last modified 6 years ago

#8633 closed Uncategorized (invalid)

Field default value force to unicode when create custom field.

Reported by: flytwokites Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


When create a custom field like document "" does:

class Hand(object):
    def __init__(self, north, east, south, west):
        self.north = north
        self.east = east
        self.south = south
        self.west = west

class HandField(...):
    def to_python(self, value):

class Foo(models.Model):
    hand = HandField(default=Hand(...))

f = Foo()
# This will use the default hand value, but value passed to HandField.to_python is string format of hand.
# If we not define a Hand.__str__ function, this string is like '<Hand instance at 0x????????>'.
# So the HandField.to_python not able to recognize this string value.
# So we must define a __str__ on Hand, and HandField must convert this string back to Hand instance.
# In some custom field value __str__ output is a human readable text, and difficult to convert back to a instance.
# So it is better to pass default value direct to to_python().

The code in django/db/models/fields/

class Field:
    def get_default(self):
        "Returns the default value for this field."
        if self.default is not NOT_PROVIDED:
            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 ""

Change History (3)

comment:1 Changed 10 years ago by flytwokites

Resolution: invalid
Status: newclosed

Ohh, i have a mistake.

comment:2 Changed 10 years ago by Carl Meyer

Just to document this further for anybody else who stumbles across this: the "mistake" here is in setting a Field's default value to any mutable object (a Hand instance, a list, a set, whatever). This is almost certainly not what you want to do, as a reference to the same _instance_ of that object would be used as the default value for that field in all new model instances. So Django instead forces that default value to unicode, which is immutable.

The correct approach is to instead use as the default a callable that returns a Hand instance (or list, or set, or whatever).

comment:3 Changed 6 years ago by Aymeric Augustin

Easy pickings: unset
Severity: Normal
Type: Uncategorized
UI/UX: unset

#18478 was a duplicate.

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