Validate a single field in django without using Form or models
Question:
I am using django to fill some forms, I know how to use Forms and use validation but my forms are complicated and it is hard to create Forms object from those forms. I wanted to know is there any way to use validators on a parameter which I get from POST in a view?
For example I have a feild which is named user
then
def login_view(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
user=request.POST["user"]
# check whether it's valid without using forms
I know about validators https://docs.djangoproject.com/en/dev/ref/validators/ and it seems they only works on models
and forms
. Is it even possible to validate a single field? If not what other options do I have for complex forms?
Answers:
A Validator is just a function that receives the form value and does nothing if the value is valid or raises an ValidationError in case it is not valid.
You can just import a Validator into your view and call it there.
With a Validator called custom_validate_user
this might look like that:
def login_view(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
user=request.POST["user"]
try:
custom_validate_user(user)
except ValidationError as e:
# handle the validation error
Nevertheless – if you have complex forms your views may become messy if you handle whole the validation directly in place. Therefore you usually encapsulate this logic in a form, or ensure validation on model level.
If you have a User
model you can define your validators inside it and reuse it whenever you need.
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
def validate_str_not_empty(value: str):
if not value:
raise ValidationError("Should not be empty")
validate_str_no_whitespace = RegexValidator(
regex=r"^S*$",
message="Should not contain whitespace",
)
class MyUser(models.Model):
name = models.CharField(
validators=[validate_str_not_empty, validate_str_no_whitespace],
)
A function to call validators of one field (similar to model.clean_fields()
but run on one field):
def clear_one_field(instance: models.Model, field_name: str) -> Any:
"""
Run validators on one field of the model.
Similar to `model.clean_fields()` but run on one field instead of all fields.
:param instance: A model instance
:param field_name: Name of the field to "clean"
:raises ValidationError: If field value is not valid
:return: The "cleaned" value of the field
"""
raw_value = getattr(instance, field_name)
return instance._meta.get_field(field_name).clean(raw_value, instance)
Use it:
def login_view(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
user_name=request.POST["user"]
clear_one_field(MyUser(name=user_name), "name")
I am using django to fill some forms, I know how to use Forms and use validation but my forms are complicated and it is hard to create Forms object from those forms. I wanted to know is there any way to use validators on a parameter which I get from POST in a view?
For example I have a feild which is named user
then
def login_view(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
user=request.POST["user"]
# check whether it's valid without using forms
I know about validators https://docs.djangoproject.com/en/dev/ref/validators/ and it seems they only works on models
and forms
. Is it even possible to validate a single field? If not what other options do I have for complex forms?
A Validator is just a function that receives the form value and does nothing if the value is valid or raises an ValidationError in case it is not valid.
You can just import a Validator into your view and call it there.
With a Validator called custom_validate_user
this might look like that:
def login_view(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
user=request.POST["user"]
try:
custom_validate_user(user)
except ValidationError as e:
# handle the validation error
Nevertheless – if you have complex forms your views may become messy if you handle whole the validation directly in place. Therefore you usually encapsulate this logic in a form, or ensure validation on model level.
If you have a User
model you can define your validators inside it and reuse it whenever you need.
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
def validate_str_not_empty(value: str):
if not value:
raise ValidationError("Should not be empty")
validate_str_no_whitespace = RegexValidator(
regex=r"^S*$",
message="Should not contain whitespace",
)
class MyUser(models.Model):
name = models.CharField(
validators=[validate_str_not_empty, validate_str_no_whitespace],
)
A function to call validators of one field (similar to model.clean_fields()
but run on one field):
def clear_one_field(instance: models.Model, field_name: str) -> Any:
"""
Run validators on one field of the model.
Similar to `model.clean_fields()` but run on one field instead of all fields.
:param instance: A model instance
:param field_name: Name of the field to "clean"
:raises ValidationError: If field value is not valid
:return: The "cleaned" value of the field
"""
raw_value = getattr(instance, field_name)
return instance._meta.get_field(field_name).clean(raw_value, instance)
Use it:
def login_view(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
user_name=request.POST["user"]
clear_one_field(MyUser(name=user_name), "name")