Home > Software design >  How to delete a specific item ​in django jsonfield
How to delete a specific item ​in django jsonfield

Time:03-14

here is my model:

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

the data(log.log) like this:

[
  {"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)

I'm not good at json, tried a few ways but failed.

Very grateful for any answer

CodePudding user response:

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)

However if the data is structured, as seems to be the case in your JSON data, it is better in a relational database to work with an extra model, so:

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

in fact, in that case log makes no sense, and you can refer to the UserProfile directly. This will make the update to the database more efficiently, and furthermore the database can validate data, for example by preventing that you store something that is not a date in the date field.

If one uses a JSON blob, we fully deserialize the blob, remove the entry, and then serialize the result again. This thus scales linear in the size of the entire blob, not in that of the record to remove.


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.

  • Related