2

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://')
user1026169
  • 5,345
  • 5
  • 21
  • 35

3 Answers3

8

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

Peter Souter
  • 5,110
  • 1
  • 33
  • 62
0

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

Ronnie Beltran
  • 614
  • 1
  • 8
  • 21
  • what I want it to do is either add or remover the http:// depending on whether or not it was part of the user's input. – user1026169 Mar 12 '14 at 13:08
  • @user1026169 so what you mean is that when the user inputted in the form with 'http://example.com' in the clean() method you will remove the 'http://' or when the user inputted in the form just 'example.com' in the clean() method you will add 'http://'? whats the point? what is it that your really want to do with the value in the url field? – Ronnie Beltran Mar 13 '14 at 03:29
  • 2
    if someone just puts `example.com` i'd like it to become `http://example.com`, if someone puts `http://example.com` i'd like it to remain as is. i don't want the urlfield to have http:// in it already. – user1026169 Mar 14 '14 at 01:19
0

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>
Anupam
  • 14,950
  • 19
  • 67
  • 94