Question

I am going through the Tango With Django tutorials, I have come across a function in the forms chapter ( http://www.tangowithdjango.com/book/chapters/forms.html ) that I cannot get to work.

Admittedly I am going through the tutorial using Python 3.3 and Django 1.6, however so far I've been able to move through the tutorials.

The clean function forms.py is supposed to clean the URLField:

class PageForm(forms.ModelForm):
    title = forms.CharField(max_length=128, help_text="input page title")
    url = forms.URLField(max_length=200, help_text="input page URL")
    views = forms.IntegerField(widget=forms.HiddenInput(), initial=0)

    def clean(self, cleaned_data):
        cleaned_data = super(PageForm, self).clean()
        url = cleaned_data.get('url')

        if url and not url.startswith('http://'):
            url = 'http://' + url
            cleaned_data['url'] = url

        return cleaned_data

    class Meta:
        model = Page
        fields = ('title', 'url', 'views')

Here is an excerpt from the add_page.html template:

<form id="page_form" method="POST" action="/rango/category/{{category_name_url}}/add_page/">

        {% csrf_token %}
        {% for hidden in form.hidden_fields %}
            {{ hidden }}
        {% endfor %}

        {% for field in form.visible_fields %}
        <p></p>
            {{ field.errors }}
            {{ field.help_text }}
            {{ field }}
        {% endfor %}

        <p></p>
        <input type="submit" name="submit" value="create page" />
        <br>
</form>

As a workaround I have adjusted the forms.py url function to work this way per the official Django docs, although it is not my preferred method:

url = forms.URLField(
    max_length=200, help_text="input page URL", initial='http://')
Was it helpful?

Solution

I had this issue too. My problem was that a pop up constantly showed when entering a url string missing http://, saying "Please enter a URL". So the clean() call never had a chance to happen.

I think this is because the default widget for a URLfield in a form performs a check. By doing the following, the clean() code got a chance to happen and add an eventual missing "http://"

from django.forms.widgets import TextInput
...
url = forms.URLField(max_length=200, 
                     help_text="Please enter the URL of the page.", 
                     initial="http://",
                     widget=TextInput)

The default is widget=UrlInput

OTHER TIPS

If you want to make sure that input value in the url field in the form should have a prefix of "http://" when saved whether the user has inputted it or not this line is already correct:

url = forms.URLField(max_length=200, help_text="input page URL", initial='http://')

try this:

>>> from django import forms
>>> url = forms.URLField(initial='http://')
>>> print url.clean('google.com')
http://google.com/

No need to implement clean() method in the form.

Update 1:

In PageForm class you have to make a clean_url() method that do what you want with the input and in save() method assign the cleaned data to an object you want tot save. Hint: Take a look at my django form forms.py

I would like to add another answer here that I learnt from Daniel's answer here

The validation message "Please enter a URL" is not coming from Django. Its coming from the browser which is trying to validate it on the client side (because the type is set to "url" in the input field I think). To not let the browser validate it, just put novalidate attribute in the form:

<form id="page_form" method="POST" ... novalidate>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top