Reputation: 23
I'm trying to run and validate a form but having some problem. Instead of displaying the form it renders the template which I put to display when the form is not valid.
Here is my Model:
class Preference(models.Model):
CLASS_CHOICES = [('1', '1'), ('2', '2'), ('3', '3')]
BOARD_CHOICES = [('C', 'CBSE'), ('I', 'ICSE'), ('S', 'State Board')]
SLOT_CHOICES = [('M', 'Morning'), ('A', 'AfterNoon'), ('E', 'Evening')]
SUBJECT_CHOICES = [('H', 'HINDI'), ('M', 'MATH'), ('E', 'ENGLISH')]
LOCATION_CHOICES = [('M', 'My Home'), ('T', 'I am willing to travel')]
GENDER_CHOICES = [('M', 'Male'), ('F', 'Female'), ('B', 'Both are Fine')]
Class = models.CharField(max_length=2, choices=CLASS_CHOICES, default='1', blank=False)
Board = models.CharField(max_length=2, choices=BOARD_CHOICES, default='C', blank=False)
Subject = models.CharField(max_length=2, choices=SUBJECT_CHOICES, default='M', blank=False)
Frequency = models.IntegerField(default=7)
Slot = models.CharField(max_length=2, choices=SLOT_CHOICES, default='E', blank=False)
Location = models.CharField(max_length=2, choices=LOCATION_CHOICES, default='M', blank=False)
Gender = models.CharField(max_length=2, choices=GENDER_CHOICES, default='M', blank=False)
Address = models.CharField(max_length=250, blank=True)
Travel = models.IntegerField(default=5)
Name = models.CharField(max_length=50, blank=True)
Contact = models.IntegerField(default=100)
Here is my form:
class PreferenceForm(forms.ModelForm):
class Meta:
model = Preference
fields = ['Class', 'Board', 'Subject', 'Frequency', 'Slot', 'Location', 'Gender', 'Address',
'Travel', 'Name', 'Contact']
widgets = {
'Board': forms.RadioSelect(),
'Subject': forms.CheckboxSelectMultiple(),
'Slot': forms.CheckboxSelectMultiple(),
'Location': forms.CheckboxSelectMultiple(),
'Gender': forms.RadioSelect()}
And here is my view:
def pref2(request):
form = PreferenceForm(request.POST or None)
if form.is_valid():
prefer = form.save(commit=False)
prefer.save()
return HttpResponse('Thank You!')
else:
print(form.errors)
return render(request, 'website/tutors.html')
When I run the app, it renders the 'tutors.html' template without showing the form and form.errors
display no error.
All help/suggestions are appreciated, thanks.
Upvotes: 0
Views: 230
Reputation: 12086
[EDIT]: The validation error you get is explained very well here. In order to make it work, you should add 3 more models:
class Subject(models.Model):
SUBJECT_CHOICES = [('H', 'HINDI'), ('M', 'MATH'), ('E', 'ENGLISH')]
name = models.CharField(max_length=2, choices=SUBJECT_CHOICES, default='M', blank=False)
def __str__(self):
return self.name
class Slot(models.Model):
SLOT_CHOICES = [('M', 'Morning'), ('A', 'AfterNoon'), ('E', 'Evening')]
name = models.CharField(max_length=2, choices=SLOT_CHOICES, default='E', blank=False)
def __str__(self):
return self.name
class Location(models.Model):
LOCATION_CHOICES = [('M', 'My Home'), ('T', 'I am willing to travel')]
name = models.CharField(max_length=2, choices=LOCATION_CHOICES, default='M', blank=False)
def __str__(self):
return self.name
Now, in your Preference
model, change it to:
class Preference(models.Model):
CLASS_CHOICES = [('1', '1'), ('2', '2'), ('3', '3')]
BOARD_CHOICES = [('C', 'CBSE'), ('I', 'ICSE'), ('S', 'State Board')]
GENDER_CHOICES = [('M', 'Male'), ('F', 'Female'), ('B', 'Both are Fine')]
Class = models.CharField(max_length=2, choices=CLASS_CHOICES, default='1', blank=False)
Board = models.CharField(max_length=2, choices=BOARD_CHOICES, default='C', blank=False)
subjects = models.ManyToManyField(Subject)
Frequency = models.IntegerField(default=7)
slots = models.ManyToManyField(Slot)
locations = models.ManyToManyField(Location)
Gender = models.CharField(max_length=2, choices=GENDER_CHOICES, default='M', blank=False)
Address = models.CharField(max_length=250, blank=True)
Travel = models.IntegerField(default=5)
Name = models.CharField(max_length=50, blank=True)
Contact = models.IntegerField(default=100)
Also, please, rename your fields to lower case (address
instead of Address
). First-letter-uppercase is used for Class names.
After that, run ./manage.py makemigrations
and ./manage.py migrate
to apply the changes.
[END EDIT]
It seems that you do not display your form in your tutors.html
template. That is, you're not taking in advantage the PreferenceForm
class you just made.
So, inside the tutors.html
, write this:
<form method="post">{% csrf_token %}
{{ form }}
<input type="submit" name="submit_preference">
</form>
But this will not work alone. You must pass the form
variable from the pref2
view to your template (in order for {{ form }}
to be populated).
Change to:
return render(request, 'website/tutors.html', locals())
Also, the
prefer = form.save(commit=False)
prefer.save()
is reduntant. Since there is no data manipulation between these two lines (i.e you're not modifying the prefer
form in some way), you can just make it one, like this:
prefer = form.save()
Upvotes: 1