Opened 16 years ago

Closed 16 years ago

Last modified 12 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: dev
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

Description

When create a custom field like document "http://www.djangoproject.com/documentation/custom_model_fields/" 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().
f.save()

The code in django/db/models/fields/init.py

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 by flytwokites, 16 years ago

Resolution: invalid
Status: newclosed

Ohh, i have a mistake.

comment:2 by Carl Meyer, 16 years ago

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

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