Search code examples
django-formsdjango-viewsdjango-1.6

django 1.6 automatically remove or add http:// from URLField from form data


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://')

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