[Django]-Validate a single field in django without using Form or models

5πŸ‘

βœ…

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.

πŸ‘€dahrens

0πŸ‘

If you have a MyUser 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_starts_with_uppercase(value: str):
    if value and not value[0].isupper()
        raise ValidationError("Should start with uppercase")

validate_str_no_whitespace = RegexValidator(
    regex=r"^\S*$",
    message="Should not contain whitespace",
)

class MyUser(models.Model):
    name = models.CharField(
        validators=[validate_str_no_whitespace, validate_str_starts_with_uppercase],
    )

A function to call validators of one field (similar to model.clean_fields() but run on one field):

from django.db import models
from typing import Type, Union

def run_field_validators(model_type: Union[models.Model, Type[models.Model]], field_name: str, raw_value: Any) -> None:
    """
    Validate `raw_value` with the validators of one field of the model.

    Similar to `model.clean_fields()` but runs on only one field and validates the given `raw_value`.

    :param model_type: A model class or instance
    :param field_name: Name of the field to validate
    :param raw_value: Value to be validated
    :raises ValidationError: If value is not valid
    """
    if isinstance(model_type, models.Model):
        class_ = model_type.__class__
    else:
        class_ = model_type
    field = class_._meta.get_field(field_name)
    value = field.to_python(raw_value)

    # Raise error if field value is blank (and if field.blank==False).
    # This is needed here because field.run_validators ignores blank values.
    if not field.blank and value in field.empty_values:
        raise ValidationError(field.error_messages["blank"], code="blank")

    field.run_validators(value)

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"]
        run_field_validators(MyUser, "name", user_name)
πŸ‘€Noam Nol

Leave a comment