Form validation in django - python

I just started to use django. I came across forms and I need to know which one is the better way to validate a forms. Would it be using django forms or should we use javascript or some client side scripting language to do it?

You should ALWAYS validate your form on the server side, client side validation is but a convenience for the user only.
That being said, Django forms has a variable form.errors which shows if certain form fields were incorrect.
{{ form.name_of_field.errors }} can give you each individual error of each field that's incorrectly filled out. See more here:
http://docs.djangoproject.com/en/dev/topics/forms/

There's a pluggable Django app (django-ajax-forms) that helps validate forms on the client side through JavaScript. But as AlbertoPL says, use client side validation only as a usability measure (e.g. telling a user that his desired username is already taken without reloading the registration page). There are all kind of ways to sidestep client side validation, in most cases as simple as deactivating JavaScript.
Generally speaking: presume all data coming from the outside as faulty until validated.

Just came accross django-floppyforms, which seems to do clientside validation by default. They use HTML5 which supports clientside validation by default. Not sure if they also use javascript though if the browser doesn't support HTML5. Haven't tried it myself yet.
Link to django-floppyforms: Documentation and Github

If you are using bootstrap then you can simply add required attribute in forms field. For example if there is programe field then you can validate it like:
In forms.py:
programme = forms.ChoiceField(course_choices,required=True, widget=forms.Select(attrs={'required':'required'}))
Note: It requires to link to bootstrap files in your .html page of that form.

You will need to do this is JS. This app integrates forms with parsley.js to tag the forms with correct data-* attributes automatically.

Related

How to have single form on multiple pages

I am looking for ways to best handle a single form on multiple pages. Like how a newsletter signup might be on a home page, an about page, and several blog pages.
I've handled this exact scenario in these 2 ways.
Write an API (using DRF) that takes a POST request, and then point the normal HTML form at that API. This works, and is very flexible, but feels like overkill.
Pass the form object into the context of each view I want the form to be on, and then include that into the template with includes form_snippet with form=form
The first approach is more flexible with wagtail, wherein all that needs to happen on the admin side is an inclusion of the newsletter as a snippet, where the admin user is able to choose if they want the newsletter on the page or not.
While both approaches work just fine, neither of them "feels" right, as I would think there is a simple way to do this without creating a big API, or passing around the form object to every single view.
three years later on you probably found an answer.
For documentation purposes and Google searchers, Wagtail offers an explanation on how to make a multiple step form here:
https://docs.wagtail.org/en/v3.0.1/reference/contrib/forms/customisation.html#multi-step-form
I did this with a contact formular. I handled it with a new app for my contact formular.
In this contactApp is the templates/contactForm.html. To include this contactForm where I want I use {% include 'contact/contactForm.html' %} so it loads the contactForm.html from my app called contact.

Is it possible to have a form built by a user?

For example:
I have a user that wants to create a contact form for their personal website. They want three input type=text and one textarea and they specify a label and an name/id for them on my site. Then they can use this form on their site, but I will handle it on mine?
Is it possible for django to spit out custom forms specified by the user?
Edit: If django is too "locked down" what would you recommend I do? I would like to stay with python.
something like http://code.google.com/p/django-forms-builder or one of the million similar addins?
(made into answer at OP's request)
For this you would have some kind of editor that would create a html string. This string would be stored into your database and then upon request you would display it on the user's site.
The editor should be very strict into what it can add and what the user has control over, there are some javascript editors available that will be able to provide this functionality.
The only issue I can think of is that you may run into django escaping the form when displayed to the page.

Adding CSRF protection to simple comment forms in Django

I have blog comment forms in Django and I would like to know the following:
Should I add CSRF to the forms?
If I want to use the simple "render_comment_form" method, how do I add it?
If I can't add it like that, what is the best practice for doing it?
Each tutorial or discussion on the subject seems to have a different approach, and I am not certain I understand how it all works.
My answer assumes that you are using Django 1.2:
Yes! You should protect all your data that is sent by POST requests to the server against CSRF attacks.
You don't need to add the token yourself. This is already done by django. Have a look at the default template that is used by the render_comment_form tag and you will see, that the csrf_token is already included. You can overwrite this template in your project and including the CSRF token into it is as easy as writing {% csrf_token %} into the form.
There is a way to protect your forms even if you don't set the tokens in the templates. Have a look at django's documentation about that topic. But this method is marked as a legacy method so it's not recommended to use that - it's only provided for backwards compatibility with versions of Django earlier than 1.2.

Django-registration and ReCaptcha integration - how to pass the user's IP

New to django and trying to setup django-registration 0.8 with recaptcha-client. I followed the advice posted in the answer to this question.
I used the custom form and custom backend from that post and the widget and field from this tutorial. My form is displaying properly with the recaptcha widget but when I submit it throws the error about the missing IP. What's the best way to pass the IP using django-registration?
I also used the code from the tutorial you linked, in my case to add reCaptcha to the django comments app.
You need something like initial={'captcha': request.META['REMOTE_ADDR']} at the point where your RecaptchaRegistrationForm gets instantiated.
Unfortunately this is buried in the registration/views.py register method.
You need to do something like copy and paste their code into a view method of your own and edit it. Then you need a urls.py for your customised backend that looks like the one in registration/backends/default/ but points to your new register view in place of theirs.

Django FormPreview - What is it for?

While looking across the Django documentation, I came across the FormPreview.
The description says this:
Django comes with an optional “form preview” application that helps automate the following workflow:
“Display an HTML form, force a preview, then do something with the submission.”
What is meant by "force a preview"? What would you use this feature for an in application?
To force a preview means the users are forced to see the value they have inserted on the form input fields, before django actually saves it to the database.
One example is django comment system, which enforce the users to take a look at the comment they have written before django actually saves it to the database. You would see that the users are redirected to another page to take a look at their comment, and after that there is a submit button to actually save the comment.
I think they mean (I use django but I didn't know of this until now..) that you can let people write, for example in a textarea box like I'm doing right now. After the user submits it the system would preview it to the user and give him the chance to read and edit what he submitted, before it being submitted again all the way to the database.

Categories