Dybton
Dybton

Reputation: 75

Crispyforms throws validation error before submitting or filling out forms

I am using crispyforms to customise my forms in django. However, it gives me the validation error "this field is required" before I have written or submitted anything into the field. It should only me an error when submitting without filling the fields out.

How can get the validation error to show only after submit if forms are not filled out?

Thanks for reading

Validation error

HTML file

    <form method="post">
    {% csrf_token %}
    <div class="form-row">
      <div class="form-group">
        {{ form.name|as_crispy_field }}
      </div>
    </div>
    <div class="form-row">
      <div class="form-group">
        {{ form.interest_rating|as_crispy_field }}
      </div>
    </div>
      {{ form.interest|as_crispy_field }}
      <div class="form-row">
      <div class="form-group">
        {{ form.clarity_rating|as_crispy_field }}
      </div>
      <div class="form-group">
        {{ form.clarity|as_crispy_field }}
      </div>
      <div class="form-group ">
        {{ form.brevity_rating|as_crispy_field }}
      </div>
      <div class="form-group">
        {{ form.brevity|as_crispy_field }}
      </div>
      <div class="form-group ">
        {{ form.not_good|as_crispy_field }}
      </div>
      <div class="form-group ">
        {{ form.general_comments|as_crispy_field }}
      </div>
      </div>
    <button type="submit" class="btn btn-primary">Sign in</button>
  </form>
          <br/>
          <br/>
    </div>
  </div>
</div>

My forms.py

from django import forms
    from .models import Review

    class ReviewForm(forms.ModelForm):
        name = forms.CharField(widget=forms.Textarea)
        interest_rating = forms.ChoiceField(
            choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)])
        interest = forms.CharField(widget=forms.Textarea)
        clarity_rating = forms.ChoiceField(
            choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)])
        clarity = forms.CharField(widget=forms.Textarea)
        brevity_rating = forms.ChoiceField(
            choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)])
        brevity = forms.CharField(widget=forms.Textarea)
        not_good = forms.CharField(widget=forms.Textarea)
        general_comments = forms.CharField(widget=forms.Textarea)

    class Meta:
        model = Review
        fields = ['name', 'interest_rating', 'interest',
                  'clarity_rating', 'clarity', 'brevity_rating', 'brevity', 'not_good',     'general_comments']

My views.py

def readerpage(request, content_id):
    content = get_object_or_404(Content, pk=content_id)
    form = ReviewForm(request.POST)
    if form.is_valid():
        review = form.save(commit=False)
        review.content = content
        interest_rating = form.cleaned_data['interest_rating']
        interest = form.cleaned_data['interest']
        clarity_rating = form.cleaned_data['clarity_rating']
        clarity = form.cleaned_data['clarity']
        brevity_rating = form.cleaned_data['clarity_rating']
        brevity = form.cleaned_data['clarity']
        not_good = form.cleaned_data['not_good']
        general_comments = form.cleaned_data['general_comments']
        review.avg_rating = (float(interest_rating) +
                             float(clarity_rating) + float(brevity_rating)) / 3
        review.pub_date = timezone.datetime.now()
        review.save()
        return redirect('home')
    args = {'content': content, 'form': form}
    return render(request, 'content/readerpage.html', args)

Upvotes: 0

Views: 237

Answers (1)

bruno desthuilliers
bruno desthuilliers

Reputation: 77942

This is not a crispy-form issue, it's just that you are unconditionnaly trying to valide and save the form without first checking if it's a GET or POST request. You want:

def readerpage(request, content_id):
    content = get_object_or_404(Content, pk=content_id)
    if request.method == "POST":
        form = ReviewForm(request.POST)
        if form.is_valid():
            review = form.save(commit=False)
            # XXX snip lots of code that doesn't belong here
            # -- all this should be handled by the form itself, 
            # (or by the model for the avg_rating part)
            # the view should only have to call `form.save()`.
            # ... 
            review.save()
            return redirect('home')
    else:
        # GET request, present an unbound form
        form = ReviewForm()

    context = {'content': content, 'form': form}
    return render(request, 'content/readerpage.html', content)

Upvotes: 1

Related Questions