Django JSONField的自动转换思路详解(django自定义模型字段)

 更新时间:2023年06月08日 11:47:20   作者:西京刀客  
如果想实现JSONField的自动转换,可以使用Django REST framework的JSONField,或者自定义一个字段类并覆盖from_db_value()和get_prep_value()方法来实现这个功能,这篇文章主要介绍了Django JSONField的自动转换(django自定义模型字段)问题,需要的朋友可以参考下

Django JSONField的自动转换(django自定义模型字段)

背景

Django v3.1的主要更新之一便是完善了对JSON数据存储的支持,新增models.JSONField和forms.JSONField,可在所有受支持的数据库后端上使用。

通过models.JSONField可指定此字段为存储类型为JSON格式。null=True表示此字段可以为空。

from django.db import models
class Hello(models.Model):
    name = models.CharField(max_length=200)
    data = models.JSONField(null=True)
    def __str__(self):
        return self.name

思路

如果您想实现JSONField的自动转换,可以使用Django REST framework的JSONField,或者自定义一个字段类并覆盖from_db_value()和get_prep_value()方法来实现这个功能。

DRF的JSONField更简单,但使用上相对复杂一些。自定义字段类的方法更轻量,但需要我们自己完成一定的编码工作。

这里推荐使用自定义字段类的方法!

使用DRF的JSONField

要使用DRF的JSONField,主要是在Serializer中导入并应用于需要自动转换JSON的字段,然后在视图进行序列化和反序列化,JSONField会自动完成与之相关的所有转换工作。

自定义一个字段类并覆盖from_db_value()和get_prep_value()方法

直接使用JSONField不会自动转换,是因为:

  • JSONField只是一个简单的继承自TextField的字段
  • 它本身并未实现from_db_value()和get_prep_value()方法
  • 所以当我们访问instance.JSONField时,得到的仅是JSON编码后的字符串,而非Python对象
  • 它也不会在保存实例时自动将Python对象重新转换为JSON字符串

覆盖模型字段的from_db_value()和get_prep_value()方法可以实现「自动转换」的效果。

  • from_db_value()方法用于数据库读取值时将值转换为Python对象
  • get_prep_value()方法用于数据库保存值前将Python对象转换为值
    通过覆盖这两个方法,我们可以实现自定义的转换逻辑,从而达到自动转换的效果。

django自定义模型字段 @models.register_field()

@models.register_field()是一个模型注册装饰器。使用它可以注册自定义字段,使其可以像内置字段一样在模型中使用。

例如,使用了这个装饰器的JSONField可以在模型中像此使用:
python
class Product(models.Model):
info = models.JSONField()
而不用导入字段类:
python
from .fields import JSONField

class Product(models.Model):
info = JSONField()

总结:这样的话,就不用单独导入字段类了(我们只需要在django启动入口的位置,如apps.py中 导入JSONField。目的是为了使用@models.register_field装饰器注册这个字段,使其在Django知道并可以在任何模型中像内置字段一样使用)。如果不使用这个装饰器,我们必须导入字段类后才能在模型中使用它。

另外,即使使用了@models.register_field装饰器,我们也可以直接导入JSONField字段类并在模型中使用。

举例:apps.py导入了,在具体的模型类中又单独引入了这个JSONField,用的是哪个?
在这种情况下,Django会使用您在模型中直接导入的JSONField字段类。
也就是说,apps.py中的导入会被忽略,模型中导入的字段类会生效并在模型中实际使用。
这是因为:

  • Django会根据实际使用解析哪个字段类,而不是根据哪个被导入了。
  • 如果同一个字段类被 imports 了两次,Python也只会使用最后一个导入的那个。

使用@models.register_field()带来的好处是:

  • 使自定义字段的使用看起来像内置字段,较为简洁直接,易于理解。
  • 不用导入自定义字段类,模型可以独立定义,解耦了字段的导入依赖。
  • 自动处理字段的参数,无需在模型中传递,使用起来像内置字段。
  • 方便第三方库的集成,可直接在模型中使用第三方提供的自定义字段。

另外,需要注意的一点是,您使用了@models.register_field装饰器,将JSONField注册为了一个可以像内建字段一样使用的模型字段。
但是,Django在首次运行时需要导入这个字段类,才知道JSONField代表什么字段。
所以,您需要在首次使用JSONField的模型对应的apps.py中导入这个字段类。

经过测试Django-4.2.1,里没有register_field装饰器。

因此总结起来,直接定义自定义模型字段类,使用时单独引入即可,这样也不污染环境(不用在不用入口apps.py导一次,IDE还报灰色),即用即可,感觉更清晰。

到此这篇关于Django JSONField的自动转换(django自定义模型字段)的文章就介绍到这了,更多相关django自定义模型字段内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 序列化Python对象的方法

    序列化Python对象的方法

    这篇文章主要介绍了序列化Python对象的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-08-08
  • numpy 实现返回指定行的指定元素的位置索引

    numpy 实现返回指定行的指定元素的位置索引

    这篇文章主要介绍了numpy 实现返回指定行的指定元素的位置索引操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • Python常见加密模块用法分析【MD5,sha,crypt模块】

    Python常见加密模块用法分析【MD5,sha,crypt模块】

    这篇文章主要介绍了Python常见加密模块用法,结合实例形式较为详细的分析了MD5,sha与crypt模块加密的相关实现方法与操作技巧,需要的朋友可以参考下
    2017-05-05
  • 使用pip安装python库的多种方式

    使用pip安装python库的多种方式

    这篇文章主要介绍了使用pip安装python库的几种方式,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07
  • Python pandas dataframe之重命名相同列名

    Python pandas dataframe之重命名相同列名

    这篇文章主要介绍了Python pandas dataframe之重命名相同列名方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • python求解三角形第三边长实例

    python求解三角形第三边长实例

    这篇文章主要介绍了python求解三角形第三边长实例,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • Mysql数据库反向生成Django里面的models指令方式

    Mysql数据库反向生成Django里面的models指令方式

    这篇文章主要介绍了Mysql数据库反向生成Django里面的models指令方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • python爬虫beautifulsoup库使用操作教程全解(python爬虫基础入门)

    python爬虫beautifulsoup库使用操作教程全解(python爬虫基础入门)

    这篇文章主要介绍了python爬虫beautifulsoup库使用操作全解(python爬虫基础入门),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • Python网络编程之TCP与UDP协议套接字用法示例

    Python网络编程之TCP与UDP协议套接字用法示例

    这篇文章主要介绍了Python网络编程之TCP与UDP协议套接字用法,结合实例形式较为详细的分析了Python网络编程中TCP与UDP协议客户端、服务器端相关实现及使用技巧,需要的朋友可以参考下
    2018-02-02
  • Pyecharts V1和V0.5之间相互切换的方法

    Pyecharts V1和V0.5之间相互切换的方法

    这篇文章主要介绍了Pyecharts V1和V0.5之间相互切换的方法,Pyecharts这个可视化库火爆,官方如是说:Echarts 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可,下面和小编一起进入文章了解具体内容吧
    2022-02-02

最新评论