带有默认和自定义编码器的 Django JSONField

Posted

技术标签:

【中文标题】带有默认和自定义编码器的 Django JSONField【英文标题】:Django JSONField with default and custom encoder 【发布时间】:2021-01-15 22:55:12 【问题描述】:

Django 版本:3.1.0,mysql 后端

我的模型上有一个JSONField

class Employee(models.Model):
    address = models.JSONField(
        encoder=AddressEncoder,
        dedocer=AddressDecoder,
        default=address_default
    )

那么encoder 看起来像这样:

class AddressEncoder(DjangoJSONEncoder):
    def default(self, o):
        if isinstance(o, Address):
            return dataclasses.asdict(o)
        raise TypeError("An Address instance is required, got an 0".format(type(o)))

那么address_default 看起来像这样:

def address_default():
    encoder = AddressEncoder()
    address = Addres(...)
    return encoder.encode(address)

目前我已将address_default 设置为返回dict。虽然它实际上应该返回一个 Address 实例。当我更改它以使address_default 返回Address 的实例时,将引发错误TypeError: Object of type Address is not JSON serializable。但是,在地址实际上是Address 的实例的代码的其他部分中,不会引发错误。所以自定义的AddressEncoder似乎并没有用在address_default提供的值上。

Employee 上的地址attribute 设置为例如string,不会引发错误。这可能与Why is Django not using my custom encoder class 中的解释有关。 AddressEncoder中的代码没有被执行。

问题:

设置address_defaultEncoder/Decoder 以使address 属性可以而且只能是Address 的实例的正确方法是什么?

【问题讨论】:

【参考方案1】:

我解决了这个问题。这与我的迁移有关。我的一个迁移包含一个没有编码器的address-field 的定义。因此,将address_default 更改为返回非 json 可序列化对象会引发相应的错误。

我必须手动查找并更改迁移,以便 address 字段的定义包含自定义编码器。

检查isinstance(self.address, Address) 然后在Employee 模型上的覆盖save() 方法中完成。

【讨论】:

以上是关于带有默认和自定义编码器的 Django JSONField的主要内容,如果未能解决你的问题,请参考以下文章

带有 CORS 和自定义标头的 AngularJS

无法使用用户名/密码登录令牌端点:drf 令牌身份验证和自定义用户模型,Django

tabBar 默认和自定义图像对齐

带有 StackPane 和自定义控件的 Javafx TabPane

Django 和自定义表单验证

Django 1.5:UserCreationForm 和自定义身份验证模型