我有这个ModelViewset和一个ModelSerializer
class GenerarFacturaViewset(viewsets.ModelViewSet):
serializer_class = serializer.FacturaSerializer
def get_queryset(self):
self.queryset = []
_nro = self.request.query_params.get('nro', None)
venta_id = self.request.query_params.get('ventaid', None)
if (venta_id is None or _nro is None):
raise exceptions.ParseError("Parametros invalidos")
nro = int(_nro)
venta = models.Venta.objects.get(id=venta_id)
if models.Factura.objects.filter(numero=nro):
raise exceptions.ParseError("Ya existe una factura con ese numero")
venta.generar_factura(nro)
print("Factura generada con nro: ", nro)
self.queryset = models.Factura.objects.filter(numero=nro)
return self.queryset
然后,当第一次调用此ModelViewset时,每次正确工作直到返回句子,然后再次调用get_queryset方法。我想知道为什么?
其他细节是,当第一个get_queryset调用中引发第二个异常时,这将显示为rest框架正常模板,但如果它在第二个调用时引发,则会在django错误模板中显示回溯和错误消息。
提前致谢
编辑:我找到了一个我想要的最佳方式 Linovia的答案是正确的,然后我改善了一些事情。为了澄清,我需要两个参数“venta_id”和“numero”来创建一个对象“factura”。在我的第一次尝试中,我尝试从请求数据中获取此参数,验证它并调用模型方法来创建对象。全部都在get_queryset方法上。但我认为这不是一个好方法。
然后我为这个porpuse创建一个新视图和一个序列化器。
class AddProductoViewset(viewsets.ModelViewSet):
serializer_class = serializer.AddProductoSerializer
queryset = models.Venta.objects.all()
http_method_names = ['post', 'head']
def create(self, request, *args, **kwargs):
venta_id = request.data.get('venta_id', None)
producto_id = request.data.get('producto_id', None)
cantidad = request.data.get('cantidad', None)
serializer_r = serializer.AddProductoSerializer(data=request.data)
if (serializer_r.is_valid(raise_exception=True)):
print("Datos validos")
venta = models.Venta.objects.get(id=venta_id)
if models.Venta.productos.filter(id=producto_id):
vpd = VentaProductoDetalle.objects.filter(venta_id=venta_id, producto_id=producto_id)[0]
vpd.cantidad += int(cantidad)
vpd.save()
else:
vpd = VentaProductoDetalle()
vpd.venta = venta
vpd.producto = models.Producto.objects.get(id=producto_id)
vpd.cantidad = int(cantidad)
vpd.save()
queryset = models.Venta.objects.get(id=venta_id)
serializer_r = serializer.VentaSerializer(queryset)
return Response(serializer_r.data)
序列化程序类:
class PostFacturaSerializer(serializers.Serializer):
venta_id = serializers.IntegerField()
numero = serializers.IntegerField()
class Meta:
model = models.Factura
def validate(self, attrs):
try:
venta_id = attrs['venta_id']
numero = attrs['numero']
except KeyError as e:
print("Error: ", e)
raise serializers.ValidationError(
"Campos no recibidos correctamente")
if (models.Factura.objects.filter(numero=numero)):
print("ya existe")
raise serializers.ValidationError(
"Ya existe una factura con ese nombre"
)
return attrs
然后我删除了get_queryset覆盖方法,不再需要了。
现在,你怎么看,我在序列化器上验证数据,所以我只是在view的create方法上调用is_valid方法。我认为这是最好的方法。
P.D:为我糟糕的英语道歉。答案 0 :(得分:7)
然后,当第一次调用此ModelViewset时,每次正确工作直到返回句子,然后再次调用get_queryset方法。我想知道为什么?
如果您使用的是BrowsableAPI,它会再次调用get_queryset
以显示表单。
其他细节是,当第一个get_queryset调用中引发第二个异常时,这将显示为rest框架正常模板,但如果它在第二个调用时引发,则会在django错误模板中显示回溯和错误消息。
不知道那一个。这可能表示您在处理初始异常期间有另一个异常。
但是,get_queryset
不应该引发异常。