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?

Asked By: Majid Hojati

||

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.

Answered By: dahrens

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")
Answered By: Noam Nol
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.