32. Django validators

We’ve seen two ways of building Django forms:

  • by declaring the variables independently
  • by inheriting the variable types from our models

One important aspect of forms is the form validation. In views.py we used an is_valid() function – by default it checks the field types declared to ensure the data matches it.

If we want, we can write our own more sophisticated validations. For example, we know that entity can only be one of two values – either chromosome or plasmid. Likewise, sense can either be + or –

We can add some validation to our forms. We’re going to override the clean data function by adding this in our GeneForm class.

We need to do the basic check:

        cleaned_data = super(GeneForm, self).clean()

And then check entity and sense against our own validations:

        entity = cleaned_data.get("entity")
        sense = cleaned_data.get("sense")

We then put in some if statements to check they are OK, and if they aren’t we can raise a validation error:

        if not entity == "Chromosome" and not entity == "Plasmid":
            raise forms.ValidationError("Entity must be 'Chromosome' or 'Plasmid'")
        if not sense == "+" and not sense == "-":
            raise forms.ValidationError("Sense must be '+' or '-'")

The complete function, and the whole class will be:

class GeneForm(ModelForm):
    class Meta:
        model = Gene
        fields = ['gene_id', 'entity', 'start', 'stop', 'sense', 'start_codon', 'sequencing', 'ec']

    def clean(self):
        cleaned_data = super(GeneForm, self).clean()
        entity = cleaned_data.get("entity")
        sense = cleaned_data.get("sense")
        if not entity == "Chromosome" and not entity == "Plasmid":
            raise forms.ValidationError("Entity must be 'Chromosome' or 'Plasmid'")
        if not sense == "+" and not sense == "-":
            raise forms.ValidationError("Sense must be '+' or '-'")
        return(cleaned_data)

Finally in views.py we need to show this validation error if necessary. We need to add an else statement to the if form.is_valid() test like this:

def create_gene(request):
    master_genes = Gene.objects.all()
    if request.method == 'POST':
        form = GeneForm(request.POST)
        if form.is_valid():
            gene = form.save()
            return HttpResponseRedirect('/create_gene/')
        else:
            return render(request, 'genedata/create_gene.html', {'error': "failed", 'master_genes': master_genes, 'form': form})

    else:
        form = GeneForm()
    return render(request, 'genedata/create_gene.html', {'form': form, 'master_genes': master_genes})

To make this function work we needed to add master_genes to the top of the function, so the if else statements could find it.

Now if we try to put in false data, we will get an error accordingly based on our custom validation:

Wednesday 17 November 2021, 11 views


Leave a Reply

Your email address will not be published. Required fields are marked *