0

I have a Django form with a check box for "Accept terms of service" but if I check it or not my app blocks the request with the message "you have to accept our Terms of service".


Here is my code:

forms.py

class ProfileModelForm(ModelForm):

    class Meta:
        model = UserProfile
        fields = ['u_fullname',
              'u_job',
              'u_country',
              'u_email',
              'u_terms',
              ]

    def clean(self):
        cleaned_data = super(ProfileModelForm, self).clean()
        u_fullname = cleaned_data.get('u_fullname')
        u_job = cleaned_data.get('u_job')
        u_country = cleaned_data.get('u_country')
        u_email = cleaned_data.get('u_email')
        u_terms = cleaned_data.get('u_terms')
        if not u_terms:
            raise forms.ValidationError("Please read and accept our Terms of Service")

        if not u_fullname and not u_job and not u_country and not u_terms:
            raise forms.ValidationError('You have to write something!')

        return cleaned_data

Field u_terms is a Booleanfield in my model.

the views.py:

    if request.method == 'POST':
    if 'user_reg' in request.POST:
        form = ProfileModelForm(request.POST)
        if form.is_valid():
            instance = form.save(commit=False)
            #Create user and get the id
            n_user = User.objects.create_user(username=request.POST['u_email'],
                                            email=request.POST['u_email'],
                                            password=request.POST['u_password'])
            instance.user = User.objects.get(id=n_user.id)
            instance.u_profile = 'U'
            print("TERMS-->",request.POST['u_terms'])
            instance.save()
            return  # Put return here
        else:
            messages.error(request, "Error")
            #form = ProfileModelForm()

        return render(request, 'login.html', {'form': form})

    elif 'register' in request.POST:
        pass
    elif 'company' in request.POST:
        pass

and the html template part related to my checkbox:

<div class="col-lg-12 no-pdd">
    <div class="checky-sec st2">
        <div class="fgt-sec">
            <input type="checkbox" name="cc" id="c2" value={{ form.u_terms }}>
            <label for="c2">
                <span></span>
            </label>
            <small>Yes, I understand and agree to the workwise Terms & Conditions.</small>
        </div><!--fgt-sec end-->
    </div>
</div>

I imagine the problem is in my html part but I don't know how can I manage boolean fields from checkbox.

Someone can help me?

2
  • 1
    Instead of <input name="cc" ...> use {{ form.u_terms }} that should render the checkbox. The problem is your input has the wrong "name" attribute so the value is submitted as request.POST['cc'] not request.POST['u_terms'] which your form expects. You can check that by printing request.POST or looking at the request in your browser debug tools. Commented Jan 9, 2020 at 13:37
  • 1
    Alternatively, if you really need to render the <input> tag yourself, use name="{{ form.u_terms.html_name }}" as the name attribute. And remove the value attribute, if you look at the source code in your browser you'll see it's not what you want. Here are all the attributes of a form's BoundField. Commented Jan 9, 2020 at 13:43

1 Answer 1

3

The "name" attribute of your <input> element does not match the POST attribute expected by your form: cc != u_terms.

You can solve this in two ways:

  • Use {{ form.u_terms }} to render the entire <input> tag. Note that you put that into the value attribute, which is wrong (look at the source code inside your browser, you'll see what I mean).

    {{ form.u_terms }}
    {{ form.u_terms.label_tag }}
    
  • If you must customise attributes of your <input> (which doesn't seem to be the case here), then make sure you still refer to your form's field so that the various attributes are correct:

    <input type="checkbox" name="{{ form.u_terms.html_name }}" id="{{ form.u_terms.id_for_label }}" class="some-custom-class">
    <label for="{{ form.u_terms.id_for_label }}"><span></span></label>
    
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.