返回实例时,序列化程序崩溃

时间:2019-07-10 23:36:12

标签: python django django-rest-framework serializer

我正在尝试在端点中添加一个新变量。 在使用cliente之前,但现在我想添加user(用于查找cliente)。问题是user不在我的Pedido模型中,所以我使用user = serializers.IntegerField()添加。我可以毫无问题地在方法中使用它,但是当返回实例pedido时,出现了问题。

serializers.py

class PedidoWriterSerializer(serializers.ModelSerializer):
    user = serializers.SerializerMethodField()
    lineas = DetallePedidoSimpleSerializer(many=True, required=False)
    class Meta:
        model = Pedido
        exclude = ('monto','entrega_realizada','pedido_confirmado', 'cliente',)
        extra_kwargs = { 'user': {'write_only': True} }

    def create(self, validated_data):
        if 'lineas' in validated_data:
            lineas = validated_data.pop('lineas')
        if 'entrega_solicitada' in validated_data:
            entregas_solicitadas = validated_data.pop('entrega_solicitada')
        user = self._kwargs.get('data').get('user')
        bandera = True
        c = Cliente.objects.get(usuario_id=user)
        validated_data['cliente'] = c
        if (not c.habilitado):
            bandera = False
        if bandera:
            total = 0
            for l in lineas:
                print(2)
                print(l)
                p = Producto.objects.get(pk=l['producto'].id)
                if ((not p.activo) or (not p.stock) or (not(l['cantidad']>0 and
                    l['cantidad'] <1000))):
                    bandera = False
                else:
                    today = datetime.now()
                    prom = p.ofertas.filter(activa=True,
                                                  desde__lte=today,
                                                  hasta__gte=today).last()
                    if prom:
                        monto_descuento = (p.precio * prom.descuento) / 100
                        total = (p.precio - monto_descuento) * l['cantidad']\
                                + \
                                total
                    else:
                        total = p.precio * l['cantidad'] + total
            if total < c.ciudad.monto_minimo:
                bandera = False
        if bandera:
            for e in entregas_solicitadas:
                he = Horario_Entrega.objects.get(pk=e.id)
                if (not he.activo):
                    bandera = False
        if bandera:
            pedido = Pedido.objects.create(cliente=c)
            for linea in lineas:
                linea['pedido'] = pedido
                Detalle_Pedido.objects.create(**linea)
            for entrega in entregas_solicitadas:
                pedido.entrega_solicitada.add(entrega)
            print('algo')
            self._kwargs.get('data').pop('user')
            pedido.save()
            # Everything is ok until this line 
            return pedido
        else:
            return None

viewset.py

class PedidoViewSet(viewsets.ModelViewSet):
    queryset = Pedido.objects.select_related('cliente',
                                             'entrega_pactada').prefetch_related('entrega_solicitada')
    serializer_class = PedidoSerializer
    filter_backends = (DjangoFilterBackend,)
    filter_fields = ('cliente__id',)
    authentication_classes = [JSONWebTokenAuthentication, ]
    permission_classes = [permissions.IsAuthenticated, ]

    def get_serializer_class(self):
        if self.action == 'retrieve':
            return PedidoSerializer
        if self.action == 'list':
            return PedidoSerializer
        return PedidoWriterSerializer

    def get_queryset(self):
        queryset = super(PedidoViewSet,self).get_queryset()
        today = timezone.now()
        queryset = queryset.filter(fecha__gte = today - timedelta(days=30),
                                   cliente__usuario__dni = self.request.user.dni).order_by(
        '-fecha')
        return queryset

这是错误消息:

ERROR Internal Server Error: /pedido/
Traceback (most recent call last):
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/rest_framework/fields.py", line 444, in get_attribute
    return get_attribute(instance, self.source_attrs)
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/rest_framework/fields.py", line 103, in get_attribute
    instance = getattr(instance, attr)
AttributeError: 'Pedido' object has no attribute 'user'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/rest_framework/viewsets.py", line 90, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/rest_framework/views.py", line 489, in dispatch
    response = self.handle_exception(exc)
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/rest_framework/views.py", line 449, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/rest_framework/views.py", line 486, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/rest_framework/mixins.py", line 22, in create
    headers = self.get_success_headers(serializer.data)
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/rest_framework/serializers.py", line 534, in data
    ret = super(Serializer, self).data
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/rest_framework/serializers.py", line 263, in data
    self._data = self.to_representation(self.instance)
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/rest_framework/serializers.py", line 488, in to_representation
    attribute = field.get_attribute(instance)
  File "/home/pedro/.virtualenvs/superEnv/lib/python3.5/site-packages/rest_framework/fields.py", line 463, in get_attribute
    raise type(exc)(msg)
AttributeError: Got AttributeError when attempting to get a value for field `user` on serializer `PedidoWriterSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Pedido` instance.
Original exception text was: 'Pedido' object has no attribute 'user'.

1 个答案:

答案 0 :(得分:0)

问题是您正在为用户字段使用SerializerMethodField()。这些类型的字段假定您在序列化器中将有一个具有相同名称的方法,并且该方法的返回值是用于该字段的值。

示例

class PedidoWriterSerializer(serializers.ModelSerializer):
    user = serializers.SerializerMethodField()

    def get_user(self, obj):
        return "any logic needed to get the user value"

    class Meta:
         model = PedidoWriter

因此,当您获得序列化信息时,将有一个名为“ user”的字段,其中包含第二个参数“ obj”是ModelSerializer的实例,因此您可以使用以下方式访问Model的任何其他字段:该变量。