试图理解Django postgresq的JSONField

2024-05-16 23:44:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在阅读JSONField上的the docs,这是一种特殊的postgresql字段类型。由于我打算创建一个自定义字段,它子类JSONField,并添加了能够转换Lifts类的功能:

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)

我读过hereto_python()和{}是{}类上的两个方法,它们涉及从数据库加载值并反序列化它们。另外,在^{} class上的to_python()方法的docstring中,它表示应该由子类重写。所以,我查了JSONField。你猜怎么着,它不会覆盖它。而且,from_db_value()甚至没有在Field上定义(也没有在JOSNField上定义)。在

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

我的问题摘要:

  1. 为什么to_python()JSONField中被重写?在
  2. 为什么from_db_value()JSONField中被重写?在
  3. 为什么from_db_value()甚至没有在Field上定义?在
  4. JSONField如何以python dict为例,将其转换为JSON字符串,并将其存储在数据库中?在
  5. 它是如何反其道而行之的呢?在

很抱歉有很多问题,但我真的很想了解这一点,而且文件在我看来有点欠缺


Tags: tonameselfjsoninitdefbeactivity
1条回答
网友
1楼 · 发布于 2024-05-16 23:44:05

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

如果在JSONField上有一个自定义字段,内部python可能是LiftSerie实例,表单表示json字符串,发送到数据库的值是json字符串,从数据库接收的值是psycopg2从postgres返回的字符串转换而来的json结构。在

关于你的问题:

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

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

  3. from_db_value没有在基Field类中定义,但是如果它存在,它肯定会被考虑在内。如果您看一下implementation of ^{},如果Field有一个这样命名的属性,from_db_value就会被添加到其中。

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

  5. psycopg2自动从数据库类型转换为python类型。它叫做adaptationDocumentation for JSON adaptation解释了它的工作原理和可定制的方式。

请注意,在实现自定义字段时,我建议在开发过程中为其编写测试,尤其是在机制尚未完全理解的情况下。您可以在django-localflavor中获得此类测试的灵感。在

相关问题 更多 >