如何删除django jsonfield中的特定项目

How to delete a specific item ​in django jsonfield

这是我的模型:

class Log(models.Model):
    user = models.OneToOneField(UserProfile, verbose_name='user', on_delete=models.CASCADE)
    log = models.JSONField(verbose_name='log', default=list, null=True, blank=True)

    def __str__(self):
        return self.user.username

数据(log.log)像这样:

[
  {"date": "2021-1-1", "volume": 123},
  {"date": "2021-2-1", "volume": 456}, // if post date is 2021-2-1, i want delete this
  {"date": "2021-3-1", "volume": 789}
]

这个删除视图:

    def delete(self, request, *args, **kwargs):
        date = request.data.get('date', None)
        if not date:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        user = request.user
        log = Log.objects.filter(user=user).first()
        if not log:
            return Response(status=status.HTTP_404_NOT_FOUND)
        
        # delete data based on date
        # data = json.dumps(log.log)
        ...
        return Response(status=status.HTTP_200_OK)

我不擅长json,尝试了几种方法都失败了。

非常感谢任何答案

def delete(self, request, *args, **kwargs):
    date = request.data.get('date', None)
    if not date:
        return Response(status=status.HTTP_400_BAD_REQUEST)
    user = request.user
    log = Log.objects.filter(user=user).first()
    if not log:
        return Response(status=status.HTTP_404_NOT_FOUND)
    
    log.log = [
        item for item in log.log
        if <strong>item['date'] != date</strong>
    ]
    log.save()
    return Response(status=status.HTTP_200_OK)

但是,如果数据是结构化的,就像您的 JSON 数据中的情况一样,最好在关系数据库中使用额外的模型,因此:

class LogEntry(models.Model):
    log = models.<strong>ForeignKey(</strong>Log, on_delete=models.CASCADE<strong>)</strong>
    date = models.DateField()
    volume = models.IntegerField()

其实那样的话log就没有意义了,直接参考UserProfile就可以了。这将使对数据库的更新更有效,而且数据库可以验证数据,例如通过防止您在 date 字段中存储非日期的内容。

如果使用 JSON blob,我们将完全反序列化 blob,删除条目,然后再次序列化结果。因此,这与 整个 blob 的大小呈线性关系,而不是要删除的记录的大小。


Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.