Python 试图理解django postgresql的JSONField

Python 试图理解django postgresql的JSONField,python,django,Python,Django,我正在阅读JSONField,一种特殊的postgresql字段类型。由于我打算创建一个自定义字段,该字段子类为JSONField,具有能够转换我的类的附加功能: class Lifts(object): def __init__(self, series): for serie in series: if type(serie) != LiftSerie: raise TypeError("List passed

我正在阅读JSONField,一种特殊的postgresql字段类型。由于我打算创建一个自定义字段,该字段子类为
JSONField
,具有能够转换我的
类的附加功能:

class Lifts(object):
    def __init__(self, series):
        for serie in series:
            if type(serie) != LiftSerie:
                raise TypeError("List passed to constructor should only contain LiftSerie objects")
        self.series = series

class AbstractSerie(object):

    def __init__(self, activity, amount):
        self.activity_name = activity.name
        self.amount = amount

    def pre_json(self):
        """A dict that can easily be turned into json."""
        pre_json = {
            self.activity_name:
                self.amount
        }
        return pre_json

    def __str__(self):
        return str(self.pre_json())

class LiftSerie(AbstractSerie):

    def __init__(self, lift, setlist):
        """ lift should be an instance of LiftActivity.
            setList is a list containing reps for each set
            that has been performed.
        """
        if not (isinstance(setlist, collections.Sequence) and not isinstance(setlist, str)):
            raise TypeError("setlist has to behave as a list and can not be a string.")
        super().__init__(lift, setlist)
我已经读过
to_python()
from_db_value()
字段
类上的两个方法,它们涉及从数据库加载值并反序列化它们。另外,在上的
to_python()
方法的docstring中,它表示应该由子类重写。因此,我查看了
JSONField
。你猜怎么着,它不会覆盖它。此外,甚至在
字段
上也没有定义来自\u db\u value()
(在
JOSNField
上也没有定义)

这是怎么回事?这使得我们很难理解JSONField是如何获取值并将其转换为json并存储在数据库中的,而在查询数据库时,情况正好相反

我的问题摘要:

  • 为什么在
    JSONField
    中没有覆盖
    to_python()
  • 为什么在
    JSONField
    中没有覆盖来自\u db\u value()的
  • 为什么在
    字段
    上甚至没有定义
    from_db_value()
  • JSONField
    如何将python
    dict
    转换为JSON字符串并存储在数据库中
  • 它是如何做到相反的呢

  • 很抱歉提出了很多问题,但我真的很想理解这一点,而且文档在IMO中有点缺乏。

    对于Django数据库字段,有三种相同数据的相关状态/表示:表单、python和数据库。对于示例
    HandField
    ,表单/数据库表示是相同的字符串,python表示是
    Hand
    对象实例

    对于
    JSONField
    顶部的自定义字段,内部python可能是
    LiftSerie
    实例,表单表示为json字符串,发送给数据库的值为json字符串,从数据库接收的值为psycopg2从postgres返回的字符串转换而来的json结构,如果这有道理的话

    关于你的问题:

  • python值不是定制的,因此字段的python数据类型与预期输入相同。与
    手动字段
    示例不同,在该示例中,输入可以通过字符串或
    手动
    实例进行。在后一种情况下,只返回输入的基本
    字段.to_python()
    实现就足够了

  • Psycopg2已经将数据库值转换为json,请参见5。对于int/
    IntegerField
    等其他类型也是如此

  • 基本
    字段
    类中未定义
    from\u db\u值
    ,但如果它存在,则肯定会将其考虑在内。如果查看,
    from\u db\u值
    ,如果
    字段
    有这样一个名为

  • django.contrib.postgres.JSONField
    有一个可选的编码器参数。默认情况下,它使用将json结构转换为json字符串

  • psycopg2自动从数据库类型转换为python类型。它叫。解释如何工作以及如何定制


  • 请注意,在实现自定义字段时,我建议在开发过程中为其编写测试,特别是在不完全理解机制的情况下。例如,您可以从中获得此类测试的灵感。

    简短的回答是,to_python和from_db_value都返回python字符串,这些字符串应该序列化为JSON,并且没有编码错误,在所有条件相同的情况下

    如果您对字符串没有意见,那也没关系,但我通常重写Django的JSONFields的from_db_value方法,以返回dict或list,而不是用于代码中的字符串。我为此创建了一个自定义字段


    对我来说,Json字段的全部意义在于能够以dict或list的形式与它的值交互。

    非常感谢您花时间回答我的问题。在1:So上,由于
    to_python()
    是在
    clean()
    for forms期间运行的,这是否意味着
    JSONField
    希望从表单收集的值是正确的json字符串?会话将从字符串转换为json结构。如中所述进行自定义:从扩展自的字段更改功能。Psycopg2将从db字符串转换为python结构,forms.JSONFields将表单字符串转换为python结构。基本上相同的转换,但在不同的位置。到python: