Django how to validate POST Parameters

22,324

Solution 1

For checking if POST data is safe, have correct type etc you can use forms in django. For example if you're expecting 3 required parameters, one string and 2 integers, you can create form:

from django import forms

class MyValidationForm(forms.Form):
    first = forms.CharField()
    second = forms.IntegerField()
    third = forms.IntegerField()

And using it in view:

if request.method == 'POST':
    form = MyValidationForm(request.POST, request.FILES)
    if not form.is_valid():
        # print some error here
    else:
        # do whatever you like

For filtering if string doesn't contain something dangerous, there is no general solution. There are different threats for databases, XSS etc so there is no way to filter it all.

Solution 2

If you are using Django REST Framework then you can do something like following inside your view.

from rest_framework import status
from rest_framework.views import APIView

class MyView(APIView):
  def post(self , request):
    serializer = MySerializer(data = request.data)
    if serializer.is_valid():
      serializer.save()
      return Response({"status" : "Success"} , status = status.HTTP_201_CREATED)

If you are not using DRF the do have a look at serializers.py to see how is_valid() is implemented. Basically, it calls run_validators() function of django.db.models.fields. Hope this helps!

Solution 3

You can consider using cleaned_ before your field to put validations on it. For instance if you want to check the username, and u have a model defined for it like,

class MyModel(models.Model):
    username = model.CharField(max_length = 255)

then for the same you have a form like under

class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = ['username']

    def clean_username(self):
        username = self.cleaned_data.get('username')
        """ this will give you the actual username from the field
            Now you may get that validated
        """
        if username == "blah blah":
            return forms.ValidationError("This isnt any name!")
        else:
            return username

This is per the django documentation which says:

"The clean() method on a Field subclass is responsible for running to_python(), validate(), and run_validators() in the correct order and propagating their errors. If, at any time, any of the methods raise ValidationError, the validation stops and that error is raised. This method returns the clean data, which is then inserted into the cleaned_data dictionary of the form.

The clean_() method is called on a form subclass – where is replaced with the name of the form field attribute. This method does any cleaning that is specific to that particular attribute, unrelated to the type of field that it is. This method is not passed any parameters. You will need to look up the value of the field in self.cleaned_data and remember that it will be a Python object at this point, not the original string submitted in the form (it will be in cleaned_data because the general field clean() method, above, has already cleaned the data once)."

Solution 4

the easiest way is to create a form:

from django import forms

class SingleForm(forms.Form):
    user_comment = forms.CharField(max_length=100)

then

comment = SingleForm(request.POST or None)
if comment.is_valid():
    # here everything is cleaned and safe

or you want to do it without a form?

Share:
22,324
John Smithv1
Author by

John Smithv1

Updated on February 13, 2020

Comments

  • John Smithv1
    John Smithv1 over 4 years

    I pass some parameters to django by a POST request. How can I validate if a parameter is an integer, a String and also that there is no unsecure stuff like code injection inside? Is there a django function I can use?

    For example:

    if request.method == 'POST':
        print request.POST.get('user_comment')
    

    How can I check if the POST parameter contains a non dangerous String for my system? Something like

    request.POST.get('user_comment').is_valid()
    

    Thanks.

  • John Smithv1
    John Smithv1 over 8 years
    So is the is_valid() function only checking if the parameters fit into a CharField or IntegerField etc. Nothing with xss, etc?
  • GwynBleidD
    GwynBleidD over 8 years
    There are different methods for protecting from XSS or SQL Injection in django. Proper ways for XSS are built into templates. For SQL Injection, ORM will do the job if you're not using raw queries or extra
  • Adarsh Trivedi
    Adarsh Trivedi almost 5 years
    This method expects to have a model behind every API request. I mean having a serializer means having a model. What if I just want to valid API request without having a model?
  • Muhammad Fahad Manzoor
    Muhammad Fahad Manzoor almost 5 years
    It is totally possible to have a Serializer without Django Model if you know about parameters/fields request.data contains.
  • Adarsh Trivedi
    Adarsh Trivedi almost 5 years
    Yes, I could figure that out after reading the documentation and trying myself.