logged user in create view

Hello every body,
I have the following model:

class Venta(models.Model):
    """
    Venta de sobres al coleccionista.
    Los atributos edicion, coleccionista y cantidad no cumplen estrictamente con la normalización
    ya que no conciernen estrictamente a la venta sino a los sobres,
    pero la experiencia demostró que facilita las consultas y otras operaciones sobre el modelo.
    Esto se bede a la política de vender sobres de solo una coleccion por venta
    """
    fecha = models.DateField(default=timezone.now)
    edicion = models.ForeignKey(Edicion, on_delete=models.CASCADE, related_name='ventas', null=True)
    detallista = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name= 'ventas',
        null = True
    )
    
    coleccionista = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='compras',
        null=True
    )

    cantidad = models.SmallIntegerField()
    
    def __str__(self):
        return f'{self.id} / {self.fecha} / {self.coleccionista}'
    
    def get_absolute_url(self):
        return reverse('venta_list')

    @property
    def coleccion(self):
        return self.edicion.coleccion


    def clean(self):
        """
        se consultan los sobres en el inventario del detallista
        para saber si hay suficientes para la venta, en caso contrario se genera
        error de validación
        """

        sobres_disponibles = Sobre.objects.filter(
                venta__isnull = True,
                paquete__edicion = self.edicion,
                paquete__compra__detallista = self.detallista
            ).order_by('ordinal')
        print(self.cantidad)
        if sobres_disponibles.count() <= self.cantidad:

            raise ValidationError(
                f'Inventario insuficiente: quedan {sobres_disponibles} sobres disponibles en inventario'
            )

The model’s clean method have to verify that there are enough ‘sobres’ in stock to create the record, in this case, an instance of the model Venta.

This is the genric view I’m using to create a new record:

class VentaCreateView(LoginRequiredMixin, CreateView):
    model = Venta
    fields = ('edicion', 'coleccionista', 'cantidad')

    def get_form(self, *args, **kwargs):
        form  =  super(VentaCreateView, self).get_form(*args, **kwargs)
        ediciones = Edicion.objects.filter(promocion__fecha_de_finalizacion__gte = timezone.now())
        coleccionistas = CustomUser.objects.filter(tipo_de_usuario = 1)
        form.fields['coleccionista'].queryset = coleccionistas
        form.fields['edicion'].queryset = ediciones
        return form

    def form_valid(self, form):
        form.instance.detallista = self.request.user
        return super().form_valid(form)

As you can see I’ m trying to set the current user into the detallista atribute of the model, using the form_valid method of the view.
Now the thing is that when a try to create a new record it raises the validation error that says ‘There are not enough stock’, when there are in fact enough stock. I’d appreciate some help with this. Pd: Using a print statement I found that in the clean method of the model, the value of detallista is set to None.

That’s correct, because the clean is being performed as part of the is_valid test. So the test is being performed before you’re assigning the value of the user to the instance of the form.

What you probably want to do here is instead of overriding form_valid, override get_form. Call super first, then modify the form you get back from the super call before returning the modified form.
(You can then delete your modified version of form_valid.)

It worked perfectly! Thank you again you’re a crack!