I am developing a program that consists of sales.
I want that when registering a sale, the reduction of the stock of the sold product is deducted. When doing so, the quantity of the product is discounted but the sale is not created and I get this error:
The error now is: AttributeError at /ventas/create/ 'NoneType' object has no attribute '__dict__'
and in the console: url = self.success_url.format(**self.object.__dict__) AttributeError: 'NoneType' object has no attribute '__dict__'
forms.py:
class VentasForm(forms.ModelForm):
"""Formulario modelo de ventas."""
class Meta:
"""Meta class."""
model = Venta
fields = ('fecha', 'cliente', 'producto', 'cantidad', 'forma_pago')
def clean(self):
"""Verificar si hay stock del producto."""
data = super().clean()
producto = Product.objects.get(id=data['producto'].pk)
if producto.cantidad <= float(self.data['cantidad']):
raise forms.ValidationError('No hay suficiente stock del producto.')
return data
def save(self):
"""Restar stock."""
data = self.cleaned_data
producto = Product.objects.get(id=data['producto'].pk)
producto.cantidad -= float(data['cantidad'])
producto.save()
views.py:
class CreateVentasView(CreateView):
"""Registrar venta."""
template_name = 'ventas/create.html'
form_class = VentasForm
success_url = reverse_lazy('ventas:list')
context_object_name = 'venta'
and in the template: {{ form.as_p }}
CodePudding user response:
Your ModelForm
save()
method is throwing away the return value of the superclass save. You need to return it, eg.
def save(self):
"""Restar stock."""
data = self.cleaned_data
producto = Product.objects.get(id=data['producto'].pk)
producto.cantidad -= float(data['cantidad'])
producto.save()
return super().save()
As a general rule: If you know for SURE that a method you are overriding never returns anything, then you don't have to worry about returning anything. But if there's any chance that a method you are overriding could return something useful (now or in the future), then play it safe and return whatever they return. It'll save you a lot of headaches later on.
One thing to think about here, is that you have a small race condition, where if two people order within a few milliseconds of each other, it is possible that you could end up thinking that you have enough stock because customer #1 checked the stock.. it was ok.. then customer #2 checks the stock before customer #1's order was saved. This would cause both orders to be saved when there may be only enough stock for the first order.