Reputation: 3
I am trying to add a new variable in my endpoint.
Before I used cliente
, but now I want to add user
(for finding the cliente
). The problem is that user
is not in my Pedido
model, so I add using user = serializers.IntegerField()
. I can use it in the method without a problem, but when return the instance pedido
, something is wrong.
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
this is the error messages:
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'.
Upvotes: 0
Views: 197
Reputation: 168
The problem is that you are using a SerializerMethodField() for the user field. These kind of fields assume that you will have a method in the serializer with the same name and the return of that method is the value used for that field.
Example
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
So then when you get the serialized information you will have a field called "user" with that information, by the way the second argument "obj" is an instance of the ModelSerializer so you can access any other field of the Model using that variable.
Upvotes: 1