首页 > 解决方案 > Django 自定义 JSONField 没有属性“名称”

问题描述

JSONFields知道我必须每次旅行encodedecode问题是我得到的很少,所以我试图制作一个这样的自定义字段:

    class JSONField(models.JSONField):
        """A Field to encode & decode JSONField."""

        def __init__(self, default=dict, encoder=None, decoder=None):
            self.encoder = encoder
            self.decoder = decoder
            self.default = default

        def get_prep_value(self, value: Any) -> Any:
            if value is None:
                return value
            return json.dumps(value, default=self.default, cls=self.encoder)

        def from_db_value(self, value, expression, connection):
            if value is None:
                return value
            return json.loads(value, cls=self.decoder)

但是当我在模型上使用它时

    class Employee(models.Model):
        time_log = JSONField()

我收到这个错误AttributeError: 'JSONField' object has no attribute 'name'

    File "/Users/mac/Documents/Payroll/payroll/models.py", line 106, in <module>
        class Employee(models.Model):
    File "/Users/mac/Documents/Payroll/env/lib/python3.9/site-packages/django/db/models/base.py", line 161, in __new__
        new_class.add_to_class(obj_name, obj)
    File "/Users/mac/Documents/Payroll/env/lib/python3.9/site-packages/django/db/models/base.py", line 326, in add_to_class
        value.contribute_to_class(cls, name)
    File "/Users/mac/Documents/Payroll/env/lib/python3.9/site-packages/django/db/models/fields/__init__.py", line 781, in contribute_to_class
        self.set_attributes_from_name(name)
    File "/Users/mac/Documents/Payroll/env/lib/python3.9/site-packages/django/db/models/fields/__init__.py", line 768, in set_attributes_from_name
        self.name = self.name or name
    AttributeError: 'JSONField' object has no attribute 'name'

我该如何解决这个问题?

标签: djangodjango-modelsserializationorm

解决方案


__init__的不完整。您只定义字段self.default, self.encoder,self.decoder而不是其他应该存在的字段,例如self.null, self.blank,self._unique等,它们应该是任何 Django 模型字段的属性,无论它们只是 None 还是具有值,它们仍然应该是可以被其类的对象访问的属性。您的自定义类缺少此属性,因此在访问它们时会出错。

实际上,假定的用法应该包括您在自定义类中缺少的models.JSONField任意**options(在代码中命名)。**kwargs

因此,您的自定义 JSONField 应如下所示:

    from django.core.serializers.json import DjangoJSONEncoder

    class JSONField(models.JSONField):
        """A minimal Field to encode & decode JSONField."""

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)

        def get_prep_value(self, value: Any)-> Any:
            if value is None:
                return value
            return json.dumps(value, cls=DjangoJSONEncoder)

        def from_db_value(self, value: Any, expression, connection) -> Any:
            if value is None:
                return value
            return json.loads(value, cls=None)

        def to_python(self, value: Any)-> Any:
            if isinstance(value, JSONField):
                return value

            if value is None:
                return value

            return json.loads(value, cls=None)

在这里阅读更多:

Django 文档

Django 代码


推荐阅读