Home > Mobile >  AttributeError in CreateView - Django
AttributeError in CreateView - Django

Time:11-20

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.

  • Related