如何删除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.
这是我的模型:
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 theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.