【问题标题】:Django custom JSONField has no attribute 'name'Django 自定义 JSONField 没有属性“名称”
【发布时间】:2021-10-17 14:11:58
【问题描述】:

我得到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'

我该如何解决这个问题?

【问题讨论】:

    标签: django django-models serialization orm


    【解决方案1】:

    您的__init__ 不完整。您只定义字段self.defaultself.encoderself.decoder,而不定义其他应该存在的字段,例如self.nullself.blankself._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 documentation

    Django code

    【讨论】:

    • 没错!我让它与 kwargs 和子类化 to_python 一起工作。我可以编辑答案并发布您的解释的简单版本吗?
    猜你喜欢
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多