Курс → Урок 35 → Справочник
⚡ Кратко
📚 Подробно
⚡ Шпаргалка
# Django-команды
python manage.py startapp users
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
# settings.py
AUTH_USER_MODEL = 'users.User'
# AbstractBaseUser минимум
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username"]
objects = UserManager()
# FileResponse
from django.http import FileResponse
response = FileResponse(file_handle, content_type='application/octet-stream')
response['Content-Disposition'] = f'attachment; filename="{name}"'
# SlugRelatedField
assignee = serializers.SlugRelatedField(slug_field='email', queryset=User.objects.all(), required=False)
Django-команды проекта
Команда
Что делает
python manage.py startapp usersСоздать новое приложение users
python manage.py makemigrationsСгенерировать файлы миграций
python manage.py migrateПрименить миграции
python manage.py createsuperuserСоздать суперпользователя
python manage.py runserverЗапустить dev-сервер
Git-команды (Agile workflow)
# Стандартный цикл задачи
git checkout -b feature/task-35-N
git add apps/...
git commit -m "feat: описание задачи 35-N"
git push origin feature/task-35-N
# Создать Pull Request в GitHub/GitLab
AbstractBaseUser — шаблон
from django.contrib.auth.base_user import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin, UserManager
from django.db import models
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
username = models.CharField(max_length=50, unique=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username", "first_name", "last_name"]
objects = UserManager()
class Meta:
verbose_name = "User"
FileResponse — скачивание
from django.http import FileResponse
from rest_framework.generics import get_object_or_404
from rest_framework.views import APIView
from rest_framework.request import Request
class DownloadProjectFileView(APIView):
def get_object(self):
return get_object_or_404(ProjectFile, pk=self.kwargs['pk'])
def get(self, request: Request, *args, **kwargs) -> FileResponse:
project_file = self.get_object()
file_handle = project_file.file_path.open()
response = FileResponse(
file_handle,
content_type='application/octet-stream'
)
response['Content-Disposition'] = (
f'attachment; filename="{project_file.file_name}"'
)
return response
RegisterUserSerializer — шаблон
from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ValidationError
import re
class RegisterUserSerializer(serializers.ModelSerializer):
re_password = serializers.CharField(max_length=128, write_only=True)
class Meta:
model = User
fields = ('username', 'first_name', 'last_name',
'email', 'position', 'password', 're_password')
extra_kwargs = {'password': {'write_only': True}}
def validate(self, data):
username = data.get('username')
first_name = data.get('first_name')
last_name = data.get('last_name')
if not re.match('^[a-zA-Z0-9_]*$', username):
raise serializers.ValidationError("Invalid username")
if not re.match('^[a-zA-Z]*$', first_name):
raise serializers.ValidationError("Invalid first_name")
if not re.match('^[a-zA-Z]*$', last_name):
raise serializers.ValidationError("Invalid last_name")
password = data.get("password")
re_password = data.get("re_password")
if password != re_password:
raise serializers.ValidationError({"password": "Passwords don't match"})
try:
validate_password(password)
except ValidationError as err:
raise serializers.ValidationError({"password": err.messages})
return data
def create(self, validated_data):
password = validated_data.pop('password')
validated_data.pop('re_password')
user = User(**validated_data)
user.set_password(password)
user.save()
return user
SlugRelatedField
# Связь по полю email вместо pk
assignee = serializers.SlugRelatedField(
slug_field='email',
queryset=User.objects.all(),
required=False
)
Физическое удаление файла
import os
def delete_file(file_path):
os.remove(os.path.realpath(file_path))
settings.py — кастомный пользователь
# Добавить ДО первой миграции!
INSTALLED_APPS = [
...
'apps.users',
]
AUTH_USER_MODEL = 'users.User'