Home > Mobile >  How to make bulk_updates in Django using Queryset
How to make bulk_updates in Django using Queryset

Time:07-07

Here I am trying to do bulk updates in Django:

Problem: In a model, there is a column name position whose value changes according to the drag and drop of the record position. so I am creating the Queryset for that, but not getting the required result, I can update the value of the particular id that got dragged but according to that need to update further makes little tricky using Queryset.

Example:

id name position
 1 anil    1
 2 ABC     2
 3 XYZ     3
 4 def     4

now if I drag id 1 to 4th place then I need to shift else by position - 1, Like:

id name position
 2 ABC     1
 3 XYZ     2
 4 def     3
 1 anil    4

for this, I was using Queryset of bulk_update but not getting any correct way to do that, please let me know the best way to make update the positions. might be I elaborated on the question too long, but I posted this query thrice, in hope that now I will get the required result.

The model I am using:

class Device(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=1000)
    position = models.IntegerField(default=0)

    def __str__(self):
        return self.name

View.py: This is the View I am creating

def put(self, request):
    max_len = Device.objects.count()
    ids = int(request.query_params.get('id'))
    temp = ids
    old = int(request.query_params.get('old'))
    new = int(request.query_params.get('new'))

    if new == old:
        return Response("both are equal can't go ahead")

    elif new > max_len:
        return Response("Invalid Position")

    elif old < new:
        # code for this condition
   
    elif old > new:
        # code for this condition

This is how I was creating this.

Thanks in Advance

CodePudding user response:

I would suggest to use the F functionality from Django to update all objects in a queryset with arithmetic value rule

Something like:

Model.objects.filter(…).update(order=F('order') - 1)

https://docs.djangoproject.com/en/4.0/ref/models/expressions/

CodePudding user response:

from django.db.models import Case, When, F

from_position = 1
to_position = 4

# First update the row we are moving to have a position of -1
Orderable.objects.filter(position=from_position).update(position=-1)

# Then update all objects in between the from/to positions either up or down
# depending of if the row is moving up or down
Orderable.objects.filter(
    position__range=sorted([from_position, to_position])
).update(
    position=Case(
        When(position__range=(from_position, to_position), then=F('position') - 1),
        When(position__range=(to_position, from_position), then=F('position')   1),
    )
)

# Then update the position of the original row
Orderable.objects.filter(position=-1).update(position=to_position)

Docs for conditional expressions

  • Related