update (), выбрасывающий TypeError: serializer.update () получил неожиданный аргумент ключевого слова 'data' - PullRequest
1 голос
/ 27 октября 2019

Я пытаюсь обновить уже сохраненный в БД объект, как только он успешно отправил сообщение. для этого он вызывает метод update () класса сериализатора. Это модель, которая будет обновлять свой экземпляр:

class SMSMessages(models.Model):
    sms_number_to = models.CharField(max_length=14)
    sms_content = models.CharField(max_length=160)
    sending_user = models.ForeignKey("SMSUser", on_delete=models.PROTECT, related_name="user_that_sent")
    sent_date = models.DateTimeField(auto_now=True)
    delivery_status = models.BooleanField(default=False)

    class Meta:
        verbose_name_plural = "SMSMessages"

    def __str__(self):
        return str(self.sending_user)

Это класс сериализатора, который я использую:

class SMSMessagesSerializer(serializers.ModelSerializer):
    """
    A class for serializing the SMSMessages model's data. It sub-classes the
    ModelSerializer class from serializer's module.
    """

    class Meta:
        model = SMSMessages
        fields = '__all__'

        def update(self, instance, validated_data):
            """
            This method is used to update an instance of the SMSMessages's delivery_status attribute.
            It get's the value for delivery_status from the input parameter, updates the specific instance
            of the SMSMessagesSerializer, saves that instance and returns it.
            """
            instance = self.get_object()
            instance.delivery_status = validated_data.get('delivery_status', instance.delivery_status)
            instance.save()
            return instance

, и это класс APIView, который имеет метод POSTэто обновит сообщение, если сообщение успешно отправлено:

class SMSView(APIView):
    """
    This class is responsible for all the method operations of an sms. It provides implementations for the GET, POST, and OPTIONS methods.
    Each method provides it's own description.
    """

    serializer_class = SMSMessagesSerializer

    def get(self, request):
        """
        This method is used to GET all created instance of the SMSMessages class that are saved in the db.
        """
        queryset = SMSMessages.objects.filter(sending_user=request.user)
        while queryset:
            return Response(
                data={
                    queryset.values()
                    },
                status=status.HTTP_200_OK,
                content_type="application/json"
            )
        else:
            return Response(
                data={
                    "no sms has been sent"
                },
                status=status.HTTP_404_NOT_FOUND,
                content_type="application/json"
            )

    def post(self, request):
        """
        This method is used to create an instance of the SMSMessages indirectly by using the SMSMessagesSerializer.
        If that is valid it will be passed to the sender() method from the notification.sender module. The serializer
        will be saved, aka the object will be saved to the database, and then the sender() is called. It will run three
        times before it gives up and fails. Once that returns a True value the instance will be called, aka the object
        will be saved to the database, with a delivery_status value of True.
        """
        sms_messages_serializer = SMSMessagesSerializer(
            data={
                "sms_number_to": request.data.get("sms_number_to"),
                "sms_content": request.data.get("sms_content"),
                "sending_user": request.data.get("sending_user")
            }
        )
        permission_classes = (permissions.IsAuthenticated)

        if sms_messages_serializer.is_valid():
            data_to_send = {
                "number": sms_messages_serializer.validated_data[
                    "sms_number_to"
                ],
                "msg_text": sms_messages_serializer.validated_data[
                    "sms_content"
                ]
            }
            sms_messages_serializer.save()

        # TODO refactor this into it's own function
        max_retry = 0
        resp = Response()
        while max_retry < 3:
            max_retry += 1
            status_flag, status_response = sender(data_to_send)
            if not status_flag:
                resp = Response(
                    data={
                        "error": f"{status_response.text}"
                    },
                    status=status_response.status_code,
                    content_type="application/json"
                )
            else:
                sms_messages_serializer.update(
                    data={
                        "delivery_status": True
                    },
                    partial=True
                )
                resp = Response(
                    data={
                        "success": f"{status_response.json()}"
                    },
                    headers=status_response.headers,
                    status=status_response.status_code,
                    content_type="application/json"
                )
                return resp
        else:
            resp = Response(
                data={
                    "error": "unable to send sms"
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
                content_type="application/json"
            )
            return resp

К нему будет обращаться через следующий urlpattern:

urlpatterns = [
    path('sendsms/', SMSView.as_view(), name="send_sms"),
    path('viewsms/', SMSView.as_view(), name="view_sms"),
]

Но вместо успешного обновления экземпляра с помощью python sms_messages_serializer.update(data={"delivery_status": True}partial=True) оноthrows TypeError: serializer.update () получил неожиданный аргумент ключевого слова 'data' .

Я попытался изменить update в классе SMSMessagesSerializer безрезультатно и попытался переименоватьdata атрибут validated_data или value, но все равно он не работает. Мне нужно, чтобы обновить delivery_status до True, как только он отправит смс, как я могу это сделать?

1 Ответ

1 голос
/ 04 ноября 2019

для тех, кто может столкнуться с этой проблемой, я исправил ее, изменив метод sms_messages_serializer.update() в методе post () следующим образом:

 sms_messages_serializer.update(sms_object,{"delivery_status": True})

где sms_object=sms_object = sms_messages_serializer.save(), что означает экземпляр sms_messages_serializerпосле проверки и сохранения данных.

нет необходимости в атрибуте data или partial=True

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...