⚖️ Старый vs Новый: паттерны из лекции
Этот раздел показывает устаревшие или упрощённые паттерны из лекции и их современные аналоги. Используй актуальный код в своих проектах.
⚡ Основные различия
- Валидаторы в Meta (лекция) → валидаторы на уровне класса (современно)
- create_file_path с split('.') → безопаснее
rsplit('.', 1) - Опечатка CreateTasSerializer →
CreateTaskSerializer - deleted по умолчанию True → логичнее False (удалён=False по умолчанию)
- validate_deadline без is_naive → в DRF 3.15+ datetime уже aware
1. Методы validate_ внутри class Meta (из лекции — неработающий код)
Из лекции (не работает)
class CreateTaskSerializer(serializers.ModelSerializer):
class Meta:
model = Task
fields = (...)
# ❌ Внутри Meta — DRF игнорирует!
def validate_name(self, value):
if len(value) < 10:
raise serializers.ValidationError(...)
return value
Современный (DRF 3.15+)
class CreateTaskSerializer(serializers.ModelSerializer):
class Meta:
model = Task
fields = (...)
# ✅ На уровне класса сериализатора
def validate_name(self, value: str) -> str:
if len(value) < 10:
raise serializers.ValidationError(
"Too short — min 10 characters"
)
return value
2. Функция create_file_path с split('.') (из лекции — потенциальная ошибка)
Из лекции
def create_file_path(project_name, file_name):
# ❌ split('.') сломается если в имени
# несколько точек: "my.report.pdf"
new_file_name, file_ext = file_name.split('.')
file_path = "documents/{}/{}.{}".format(
project_name.replace(' ', '_'),
new_file_name.replace(' ', '_'),
file_ext
)
return file_path
Современный
def create_file_path(project_name: str, file_name: str) -> str:
# ✅ rsplit с maxsplit=1 — безопасно
stem, ext = file_name.rsplit('.', 1)
file_path = "documents/{}/{}.{}".format(
project_name.replace(' ', '_'),
stem.replace(' ', '_'),
ext
)
return file_path
3. Опечатка в имени класса (из лекции — баг)
Из лекции (опечатка)
def post(self, request, *args, **kwargs):
# ❌ Опечатка: CreateTasSerializer
serializer = CreateTasSerializer(data=request.data)
...
Правильно
def post(self, request, *args, **kwargs):
# ✅ CreateTaskSerializer (с k)
serializer = CreateTaskSerializer(data=request.data)
...
4. Поле deleted по умолчанию True (из лекции — логическая ошибка)
Из лекции
class User(AbstractBaseUser, PermissionsMixin):
# ❌ default=True означает "удалён по умолчанию"
deleted = models.BooleanField(default=True)
Логически правильно
class User(AbstractBaseUser, PermissionsMixin):
# ✅ default=False — пользователь не удалён
deleted = models.BooleanField(default=False)
5. validate_deadline без проверки aware/naive
Из лекции
def validate_deadline(self, value: str) -> int:
# Применяет make_aware всегда —
# в DRF 3.15+ значение уже aware
value = timezone.make_aware(
value, timezone.get_current_timezone()
)
if value < timezone.now():
raise serializers.ValidationError(...)
return value
DRF 3.15+
def validate_deadline(self, value) -> ...:
# Проверяем is_naive перед make_aware
if timezone.is_naive(value):
value = timezone.make_aware(
value, timezone.get_current_timezone()
)
if value < timezone.now():
raise serializers.ValidationError(
"The deadline cannot be in the past"
)
return value
6. ProjectFileListAPIView vs ProjectFileListGenericView (расхождение имён)
В лекции есть расхождение: в одном месте класс называется ProjectFileListAPIView, в другом — ProjectFileListGenericView. В urls.py регистрируется ProjectFileListGenericView (GenericView). Придерживайся единого имени в своём коде.
Вывод: При написании кода по этой лекции — всегда переносить методы
validate_* на уровень класса, исправлять опечатки и проверять is_naive() перед make_aware().