Django ModelForm is_valid method always false

68 Views Asked by At

i'am getting an error using Django ModelForm. The method form.is_valid is always false and i don't understand why. After have put all the values in the form it doesn't enter inside the method and then nothing happens when i press the submit button.

This is my code.

** models.py **

    class Product(models.Model):
    image= models.ImageField(blank=True, null=True)
    name= models.CharField(max_length=200)
    type=models.CharField(max_length=30)
    product_code=models.CharField(max_length=20, unique=True)
    productor= models.CharField(max_length=50) 
    color= models.CharField(max_length=40)
    size=models.CharField(max_length=100)
    weight=models.FloatField(default=0)
    full_price= models.FloatField(default=0)
    discount=models.PositiveIntegerField(default=0)
    final_price=models.FloatField(default=0)
    quantity= models.PositiveIntegerField(default=0)
    supplier= models.ForeignKey(User,on_delete=models.CASCADE) #Utente staff che ha inserito il prodotto
    recensioni = models.ManyToManyField(Recensione)
    
    def __str__(self):
        return self.nameclass   
                                                                                      
Computer(Product):
    display_size= models.FloatField(default=0)
    display_resolution= models.CharField(max_length=20)
    cpu= models.CharField(max_length=50)
    ram= models.PositiveIntegerField(default=0)
    disk_size= models.FloatField(default=0)
    disk_type= models.CharField(max_length=20) 
    operating_system= models.CharField(max_length=100)
    graphic_card= models.CharField(max_length=50) 
    battery_autonomy= models.FloatField(default=0)
    additional_function= models.CharField(max_length=1000)

** forms.py **

class ComputerForm(forms.ModelForm):

    class Meta:
        model=Computer
        fields=['image','name','product_code','productor','color','size','weight','full_price','discount','quantity',
                'display_size',
                'display_resolution',
                'cpu',
                'ram',
                'disk_size',
                'operating_system',
                'graphic_card',
                'battery_autonomy',
                'additional_function']

** views.py **

#Aggiunta nuovo Prodotto
@login_required
def add_product(request,category):
    templ="products/product_form.html"
    
    form=ComputerForm()
    if request.method == "POST":
        form=ComputerForm(request.POST, request.FILES )

        #Controllo campi form siano validi
        if form.is_valid():
            print("Valid")
            form.save()

            return redirect("products:all_products")


    return render(request,template_name=templ,context={"form":form})
  

** product_form.html **

<div class="col-4" style= "width:30%;right:+20px;">
                <h3> <b> Dati prodotto: </b> </h3>
                
                <form method='POST'>
                    {% csrf_token %}
                    {% crispy form %}
                    <br>
                    <input type="submit" class="btn btn primary" style="background-color:blue;color:white;" value="Aggiungi Prodotto">
                </form>

            </div>

1

There are 1 best solutions below

3
Noel Nagy On

The main problem should that crispy forms generates a new for tag that defaults to a GET request. Make a form helper object according to the official documentation. Be sure to include self.helper.form_tag = False. This should solve your problem. Here is the documentation: https://django-crispy-forms.readthedocs.io/en/latest/form_helper.html

Note: If you have a file or image upload in your form, you should add enctype="multipart/form-data" to your HTML form tag like this:

<form method='POST' enctype="multipart/form-data">
    {% csrf_token %}
    {% crispy form %}
    <br>
    <input type="submit" class="btn btn primary" style="background-color:blue;color:white;" value="Aggiungi Prodotto">
</form>

This is necessary if you want users to upload files like images and by the form I assume you do.