Как удалить определенный элемент в 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}
]

this this delete view:

    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 item['date'] != date
    ]
    log.save()
    return Response(status=status.HTTP_200_OK)

Однако если данные структурированы, как, похоже, в ваших данных JSON, в реляционной базе данных лучше работать с дополнительной моделью, так:

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

Фактически, в этом случае log не имеет смысла, и вы можете ссылаться на UserProfile напрямую. Это сделает обновление базы данных более эффективным, и, кроме того, база данных может проверять данные, например, предотвращая сохранение в поле date того, что не является датой.

Если используется JSON-блоб, мы полностью десериализуем блоб, удаляем запись, а затем снова сериализуем результат. Таким образом, масштабирование происходит линейно по размеру всего блоба, а не по размеру удаляемой записи.


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.

Вернуться на верх