【问题标题】:Dealing with Irregular Embedded ArrayFields in Django在 Django 中处理不规则的嵌入式 ArrayFields
【发布时间】:2016-11-16 08:55:31
【问题描述】:

我目前正在使用 Django 和 PostgreSQL。我使用django-extensions 运行自定义脚本,将数据插入数据库。我有一个模型如下:

class Route(models.Model):
    """
    Bus routes of İzmir.
    """

    code = models.PositiveSmallIntegerField(
        unique=True,
        primary_key=True,
        verbose_name="Code"
    )

    stops = models.ManyToManyField(
        Stop,
        null=True,
        blank=True,
        related_name="routes",
        verbose_name="Stops"
    )

    terminals = ArrayField(
        models.CharField(
            null=False,
            blank=False,
            max_length=32,
        ),
        size=2,
        default=[],
        verbose_name="Terminals"
    )

    departure_times = ArrayField(
        ArrayField(
            models.TimeField(
                null=False,
                blank=False
            ),
            null=True, # This was added later to maybe solve the problem.
            default=[]
        ),
        default=[],
        size=6,
        verbose_name="Departure Times"
    )

    class Meta:
        verbose_name = "Route"
        verbose_name_plural = "Routes"
        ordering = ["code"]

如您所见,我在departure_times 中嵌入了另一个ArrayField。我的数据具有不规则的形状,如 Django documentation 中提到的 note。因此,自然会引发如下错误:

django.db.utils.DataError:多维数组必须有匹配维度的数组表达式

正如文档中提到的“基础字段应该可以为空”,我将null = True 添加到我嵌入的ArrayField 中。但是,我不理解文档注释中的以下声明:

用 None 填充的值

我头上的问题是

1) 我是否会处理这些数据,修改不规则列表的长度如下?

[a, b, c, None, None]
[a, b, None, None, None]
[a, b, c, d, e]

2) 有没有内置的方法来克服DataError


如果您认为查看脚本可以帮助您解决问题,here it is


环境

  • python 3.5.1
  • django 1.9.7
  • psycopg2 2.6.2
  • postgresql 9.5

【问题讨论】:

    标签: python arrays django postgresql python-3.x


    【解决方案1】:

    所以,这个问题似乎没有参与者。因此,我想分享我自己的解决方案。简而言之,我以上述问题 (1) 的方式修改了脚本,这意味着,我用填充符 None 值扩展了每个列表,以均衡每个列表的长度。

    假设我有如下数据:

    [
        [1, 2, 3],
        [4, 5],
        [6, 7, 8, 9, 10]
    ]
    

    期望的输出是:

    [
        [1, 2, 3, None, None],
        [4, 5, None, None, None],
        [6, 7, 8, 9, 10]
    ]
    

    所以,我刚刚创建了一个示例函数,以防将来有人需要,如下所示:

    def equalizer(data):
        largest_length = 0 # To define the largest length
    
        for l in data:
            if len(l) > largest_length:
                largest_length = len(l) # Will define the largest length in data.
    
        for i, l in enumerate(data):
            if len(l) < largest_length:
                remainder = largest_length - len(l) # Difference of length of particular list and largest length
                data[i].extend([None for i in range(remainder)]) # Add None through the largest length limit
    
        return data
    

    那么没有任何DataError 可以显示。如果没有更好的解决方案,此答案将在两天内被接受为有效。

    【讨论】:

      【解决方案2】:

      感谢您分享您的解决方案,它确实帮助了我。然而,我相信我找到了一个更优雅的解决方案。他是我的看法:

          def save(self, *args, **kwargs):
               max_lenght = max(len(element) for element in self.NestedArrays)
               [[element.append(None) for _ in range(max_lenght - len(element))] for element in self.NestedArrays if len(element) != max_lenght]
               super(ParentClass, self).save(*args, **kwargs)  # Call the "real" save() method.
      

      基本上我会覆盖默认的保存方法。然后修改 NestedArrays 属性,最后保存。此方法将添加到有此问题的模型类中。在这种情况下,我将其称为 ParentClass。

      更多关于覆盖模型方法here的信息。

      希望这对某人有所帮助!

      【讨论】:

        猜你喜欢
        • 2022-12-11
        • 1970-01-01
        • 2014-05-23
        • 1970-01-01
        • 1970-01-01
        • 2013-03-12
        • 2019-09-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多