Search code examples
pythondjangoforms

Django Form Field validation


I have a form that requires a URL as input. I would like to check if the URL begins with http:// or https://.

If it doesn't have one of these two 'stings' in the beginning, the form submission should give an error.

I don't have any clue on how to get started with this and could not find any info based on my limited knowledge of django and I have no clue what search terms to look up.

A basic hint would be a great help.

Thanks!

My current forms.py has a form based on a model:

class AddUrlForm(forms.ModelForm):

    class Meta:
        model = forwards
        # fields = '__all__'
        exclude = ["user", "counterA", "counterB", "shortcodeurl", "uniqueid"]

models.py:

class forwards(models.Model):
    uniqueid = models.AutoField(primary_key=True)
    user = models.CharField(max_length = 150)
    urlA = models.CharField(verbose_name="URL Version A", max_length = 254)
    counterA = models.DecimalField( max_digits=19, decimal_places=0,default=Decimal('0'))
    urlB = models.CharField(verbose_name="URL Version B",max_length = 254)
    counterB = models.DecimalField( max_digits=19, decimal_places=0,default=Decimal('0'))
    timestamp = models.DateTimeField('date created', auto_now_add=True)
    shortcodeurl = models.CharField(max_length = 254)

html segment where that shows how the form is integrated:

        <form method="post">
            {% csrf_token %}
            {% for field in forwardform %}
                <span>{{ field.label_tag }} </span>
                <p style="color: black">{{ field }} </p>
                {% for error in field.errors %}
                        <p style="color: red">{{ error }}</p>
                {% endfor %}
            {% endfor %}
        <button class="btn btn-outline btn-xl type="submit">Generate URL</button>
        </form>

views.py:

def forwardthis(request):
    forwardform = AddUrlForm(request.POST or None)
    if forwardform.is_valid():
        forward = forwardform.save(commit=False)
        forward.user = request.user.username
        forward = forwardform.save()
        uniqueid_local = forward.uniqueid
        uniqueid_local_bytes = uniqueid_local.to_bytes((uniqueid_local.bit_length() + 7) // 8, byteorder='little')
        shortcodeurl_local  = urlsafe_base64_encode(uniqueid_local_bytes)
        forward.shortcodeurl = shortcodeurl_local
        forward.save()
        return HttpResponseRedirect('/forwardthis')
    query_results = forwards.objects.filter(user=request.user.username)
    query_results_qty = query_results.count()
    click_results = clickstats.objects.filter(user=request.user.username)
    template = loader.get_template('forwardthis.html')
    context = {
        'forwardform': forwardform ,
        'query_results':query_results,
        'query_results_qty': query_results_qty
    }
    return HttpResponse(template.render(context,request))

Solution

  • You can create a validation method for each form field. def clean_FIELDNAME(). I supose the url field is shortcodeurl:

    class AddUrlForm(forms.ModelForm):
    
        def clean_shortcodeurl(self):
            cleaned_data = self.clean()
            url = cleaned_data.get('shortcodeurl')
            if not is_valid_url(url):  # You create this function
                self.add_error('shortcodeurl', "The url is not valid")
            return url
    
        class Meta:
            model = forwards
            # fields = '__all__'
            exclude = ["user", "counterA", "counterB", "shortcodeurl", "uniqueid"]