I need to bulk update ("is_read" = True) Message instanses by given list of ids in one request with this code:
{"ids": [11, 4, 7]}
Model:
class Message(models.Model):
text = models.TextField(max_length=500, verbose_name=_("Text"))
sender = models.ForeignKey(
to=User,
on_delete=models.CASCADE,
related_name="sender_message",
verbose_name=_("User"),
)
thread = models.ForeignKey(
to="Thread",
on_delete=models.CASCADE,
related_name="thread_message",
verbose_name=_("Thread"),
)
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Updated"))
is_read = models.BooleanField(default=False, verbose_name=_("Is read"))
I have this serializer:
class MessageIsReadSerializer(serializers.ModelSerializer):
class Meta:
model = Message
fields = ("id", "text", "sender", "is_read")
And method in views.py:
class MessageIsRead(APIView):
permission_classes = (AllowAny,)
queryset = Message.objects.all()
def put(self, request, *args, **kwargs):
id_list = request.data['ids']
instances = []
for item in id_list:
obj = self.queryset.filter(id=item)
obj.is_read = True
instances.append(obj)
serializer = MessageIsReadSerializer(instances, many=True)
return Response(serializer.data)
urls.py
urlpatterns = [
path("messages-read/", MessageIsRead.as_view()),
]
But as a result of running this query I get an error:
AttributeError at /messages-read/
Got AttributeError when attempting to get a value for field `text` on serializer
`MessageIsReadSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the
`QuerySet` instance.
Original exception text was: 'QuerySet' object has no attribute 'text'.
What is wrong?
With help of Bartosz Stasiak I've fixed my verion of put method.
def put(self, request, *args, **kwargs):
id_list = request.data['ids']
instances = []
for item in id_list:
obj = self.queryset.get(id=item)
obj.is_read = True
obj.save()
instances.append(obj)
serializer = MessageIsReadSerializer(instances, many=True)
return Response(serializer.data)
CodePudding user response:
First: here you are getting a queryset, not an instance, so later in your code you are appending querysets to the instances
list. If you want to access single instance you should use get
instead of filter
single_instance = self.queryset.get(id=item)
If you want to update multiple items you can use:
def put(self, request, *args, **kwargs):
id_list = request.data['ids']
instances = self.queryset.filter(id__in=id_list)
instances.update(is_read=True)
serializer = MessageIsReadSerializer(instances, many=True)
return Response(serializer.data)