【问题标题】:How do I make a custom model Field call to_python when the field is accessed immediately after initialization (not loaded from DB) in Django >=1.10?在 Django >=1.10 中初始化(未从数据库加载)后立即访问字段时,如何进行自定义模型字段调用 to_python?
【发布时间】:2016-09-08 13:30:49
【问题描述】:

从 Django 1.9 升级到 1.10 后,我体验到 django-geolocation 包提供的字段的行为发生了变化。

这是为 1.10 兼容性所做的更改,破坏了该行为:https://github.com/philippbosch/django-geoposition/commit/689ff1651a858d81b2d82ac02625aae8a125b9c9

以前,如果您使用 GeopositionField 初始化模型,然后立即访问该字段,您将返回一个 Geoposition 对象。现在您只需取回您在初始化时提供的字符串值。

您如何使用 Django 1.10 实现相同的行为?是否有另一种方法如from_db_value 需要被覆盖才能调用to_python

【问题讨论】:

  • 但是为什么要使用这个库呢??
  • @e4c5 它为您的管理页面提供了一个方便的谷歌地图小部件,以及一些数据验证。
  • 也许确实如此,但你可以通过 geodjango 和很多很多东西得到它

标签: python django django-models django-geoposition


【解决方案1】:

经过大量挖掘,事实证明,在 1.8 中,自定义字段的行为发生了变化,在分配给字段时不再调用 to_python

https://docs.djangoproject.com/en/1.10/releases/1.8/#subfieldbase

新方法不像 SubfieldBase 那样在赋值时调用 to_python() 方法。如果您需要这种行为,请在您的项目中从 Django 的源代码重新实现 Creator 类。

这是 Django 票证,其中包含有关此更改的更多讨论:https://code.djangoproject.com/ticket/26807

因此,为了保留旧行为,您需要执行以下操作:

class CastOnAssignDescriptor(object):
    """
    A property descriptor which ensures that `field.to_python()` is called on _every_ assignment to the field.
    This used to be provided by the `django.db.models.subclassing.Creator` class, which in turn
    was used by the deprecated-in-Django-1.10 `SubfieldBase` class, hence the reimplementation here.
    """

    def __init__(self, field):
        self.field = field

    def __get__(self, obj, type=None):
        if obj is None:
            return self
        return obj.__dict__[self.field.name]

    def __set__(self, obj, value):
        obj.__dict__[self.field.name] = self.field.to_python(value)

然后将这个添加到自定义字段中:

def contribute_to_class(self, cls, name):
    super(MyField, self).contribute_to_class(cls, name)
    setattr(cls, name, CastOnAssignDescriptor(self))

解决方案来自这个拉取请求:https://github.com/hzdg/django-enumfields/pull/61

【讨论】:

    猜你喜欢
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    • 2015-02-14
    • 1970-01-01
    • 2018-05-15
    • 2021-12-09
    • 2013-07-15
    • 2013-07-23
    相关资源
    最近更新 更多