Vihaan
Vihaan

Reputation: 31

Django forms: object has no attribute cleaned data

I'm fairly new to Django. I have been getting this error when I try to use form.cleaned_data. Everywhere I've checked online says that this is because you might not be using the is_valid function which I am. My objective is to create a set of records which stores the student ID and the subject ID as foreign keys in a model called Sub_and_stu. I'm open to any other (as simple?) ways of achieveing this.

views.py

@csrf_protect
def select_subs(request):
   form1 = Sub_selection1(request.POST)
   form2 = Sub_selection2(request.POST)
   form3 = Sub_selection3(request.POST)
   form4 = Sub_selection4(request.POST)
   user = request.user

   if form1.is_valid  and form2.is_valid and form3.is_valid and form4.is_valid:
       data1 = form1.cleaned_data
       sub1=data1['subject_id']
       Sub_and_stu.objects.create(student_id=user,subject_id=sub1)
       data2 = form2.cleaned_data
       sub2=data2['subject_id']
       Sub_and_stu.objects.create(student_id=user,subject_id=sub2)
       data3 = form3.cleaned_data
       sub3=data3['subject_id']
       Sub_and_stu.objects.create(student_id=user,subject_id=sub3)
       data4 = form4.cleaned_data
       sub4=data4['subject_id']
       Sub_and_stu.objects.create(student_id=user,subject_id=sub4)


   context={'form1':form1,'form2':form2,'form3':form3,'form4':form4}
   return render(request,'select_subs.html',context)

models.py

class Subject(models.Model):                       
   subject_id=AutoSlugField(unique=True)
   name = models.CharField(max_length=50)

   def __str__(self):
       return self.name

class Sub_and_stu(models.Model):
    record_id=AutoSlugField(unique=True)
    student_id=models.ForeignKey(User,on_delete=models.CASCADE)
    subject_id=models.ForeignKey(Subject,on_delete=models.CASCADE)

class Sub_and_teachers(models.Model):
   record_id=AutoSlugField(unique=True)
   teacher_id=models.ForeignKey(User,on_delete=models.CASCADE)
   subject_id=models.ForeignKey(Subject,on_delete=models.CASCADE)

forms.py

class Sub_selection1(ModelForm):
class Meta:
    model = Sub_and_stu
    fields=['subject_id']
#Other subject selection forms are basically a copy of this. I need the user to pick multiple subejcts at the same time

snippet from select_subs.html

<form>
{%csrf_token%}
<h3>Subject 1</h3>
{% render_field form1.subject_id class='pure-input-1 pure-input-rounded'  }
<h3>Subject 2</h3>
{% render_field form2.subject_id class='pure-input-1 pure-input-rounded'  }
<h3>Subject 3</h3>
{% render_field form3.subject_id class='pure-input-1 pure-input-rounded'  }
<h3>Subject 4</h3>
{% render_field form4.subject_id class='pure-input-1 pure-input-rounded'  }
<button type="submit" class="pure-button pure-button-primary" 
name='subjects'>Submit</button>
</form>

Upvotes: 2

Views: 1680

Answers (1)

Jimmy Pells
Jimmy Pells

Reputation: 714

You should be calling is_valid() with the parentheses.

Right now you are just checking if there is an attribute is_valid, which the existence of the method means it is True.

is_valid is the method

is_valid() with the parentheses is how you call the method to actually see if the form is valid or not. When you call the method it generates the cleaned_data for you.

You can read more about the is_valid method in the documentation https://docs.djangoproject.com/en/4.0/ref/forms/api/#django.forms.Form.is_valid

Upvotes: 7

Related Questions