Odpowiedź:
- 1. Walidacje wynikające z definicji pól modeli:
class A(models.Model):
first_name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
# W modelu A samą definicją pól narzucamy domyślne walidacje:
# first_name - max długość 100 znaków
# age - wymuszamy wartość dodatnią
2. Customowe walidatory:
def more_than18(value: int) -> bool:
if value > 18:
return True
return False
class B(models.Model):
first_name = models.CharField(max_length=100)
age = models.PositiveIntegerField(validators=[more_than_18])
# W modelu B użyliśmy customowego walidatora 'more_than_18' na polu 'age'.
3. Domyślny mechanizm walidacyjny na poziomie całego obiektu:
# Istnieje domyślny mechanizm sprawdzania danych na poziomie całego obiektu modelu, żeby go użyć należy zaimplementować metodę clean w modelu.
# Poniżej przykład dla modelu C:
class C(models.Model):
first_name = models.CharField(max_length=100)
age = models.PositiveIntegerField(validators=[more_than_18])
def clean(data:) -> bool:
IMPLEMENT logic
4. Walidacja przy użyciu clean_FIELDNAME:
# Django pozwala na definiowanie metod walidacji dla poszczególnych pól modelu za pomocą metody clean_FIELDNAME.
# Jest to bardziej granularne podejście niż implementowanie metody clean.
class D(models.Model):
first_name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
def clean_age(self):
if self.age < 18:
raise ValidationError("Age must be at least 18.")
# Tutaj clean_age zostanie wywołane podczas walidacji tego pola, np. w momencie wywołania metody full_clean na instancji modelu.
5. Użycie Meta.constraints dla walidacji na poziomie bazy danych.
# Od Django 2.2 można definiować walidacje przy pomocy atrybutu constraints w klasie Meta.
# Pozwala to na deklaratywne narzucanie ograniczeń, które są wymuszane także na poziomie bazy danych.
from django.db.models import Q, CheckConstraint
class E(models.Model):
first_name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
class Meta:
constraints = [
CheckConstraint(check=Q(age__gte=18), name='age_gte_18'),
]
# Ten mechanizm jest użyteczny w przypadku prostych reguł, takich jak wymaganie, aby wartość była większa lub równa pewnej liczbie.
6. Walidacja w metodzie save
7. Walidacja na poziomie menedżera (Managera)
8. Walidacja w metodach full_clean:
# Możesz ręcznie wywołać metodę 'full_clean' przed zapisaniem obiektu.
# Ta metoda uruchamia wszystkie poziomy walidacji (pola, metody clean_FIELDNAME oraz clean).
obj = G(first_name="John", age=15)
obj.full_clean() # Podniesie ValidationError, jeśli warunki nie są spełnione
obj.save()
# Metoda 'full_clean' nie jest automatycznie wywoływana przy zapisie w bazie.
# Można, natomiast wprowadzić konwencję, aby ją ręcznie wywoływać w określonych miejscach kodu.
9. Używanie walidatorów wbudowanych w Django:
# Przykład walidatora korzystającego z wyrażeń regularnych:
from django.core.validators import RegexValidator
class H(models.Model):
phone_number = models.CharField(
max_length=15,
validators=[
RegexValidator(
regex=r'^\+?1?\d{9,15}$',
message="Phone number must be entered in the format: '+999999999'."
)
]
)
class PhoneNumber(models.Model):
phone_number = models.CharField(
max_length=15,
validators=[RegexValidator(regex=r'^\+?1?\d{9,15}$')])
Podsumowując, metody walidacji w Django można stosować na wielu poziomach: od indywidualnych pól, przez walidację całych obiektów, aż po bardziej zaawansowane podejście z użyciem constraintów bazy danych lub menedżerów. Wybór odpowiedniej metody zależy od przypadku użycia i potrzeb projektu.