From 9ffdcc3ba3f373018bbe540b6fe026ed5ae104cb Mon Sep 17 00:00:00 2001 From: blankhex Date: Sat, 23 May 2026 18:14:56 +0300 Subject: [PATCH] Add django-simpler.md --- django-simpler.md | 209 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 django-simpler.md diff --git a/django-simpler.md b/django-simpler.md new file mode 100644 index 0000000..ce02f03 --- /dev/null +++ b/django-simpler.md @@ -0,0 +1,209 @@ +```python +# models.py +from django.contrib.auth.models import User +from django.db import models + +class Profile(models.Model): + class Role(models.TextChoices): + USER = 'user' + MODERATOR = 'moderator' + ADMIN = 'admin' + + user = models.OneToOneField(User, on_delete=models.CASCADE) + bio = models.CharField(max_length=500, blank=True) + role = models.CharField(max_length=20, choices=Role.choices, default=Role.USER) + verification_code = models.CharField(max_length=6, blank=True, null=True) + + def __str__(self): + return self.user.username +``` + + +```python +# serializers.py +from rest_framework import serializers +from django.contrib.auth.models import User +from .models import Profile + +class UserSerializer(serializers.ModelSerializer): + bio = serializers.CharField(source='profile.bio', allow_blank=True) + role = serializers.CharField(source='profile.role', read_only=True) + + class Meta: + model = User + fields = ['id', 'username', 'bio', 'role', 'email'] + read_only_fields = ['id', 'role'] + +class RegisterSerializer(serializers.Serializer): + username = serializers.CharField(max_length=150) + email = serializers.EmailField() + + def validate_username(self, value): + if User.objects.filter(username=value).exists(): + raise serializers.ValidationError("Username already taken.") + return value + + def validate_email(self, value): + if User.objects.filter(email=value).exists(): + raise serializers.ValidationError("Email already registered.") + return value +``` + + +```python +# permissions.py +from rest_framework import permissions + +class IsUser(permissions.BasePermission): + def has_permission(self, request, view): + return ( + request.user and + request.user.is_authenticated and + hasattr(request.user, 'profile') and + request.user.profile.role == 'user' + ) + +class IsModerator(permissions.BasePermission): + def has_permission(self, request, view): + return ( + request.user and + request.user.is_authenticated and + hasattr(request.user, 'profile') and + request.user.profile.role in ['moderator', 'admin'] + ) + +class IsAdmin(permissions.BasePermission): + def has_permission(self, request, view): + return ( + request.user and + request.user.is_authenticated and + hasattr(request.user, 'profile') and + request.user.profile.role == 'admin' + ) +``` + + +```python +# views.py +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework.permissions import AllowAny, IsAuthenticated +from rest_framework_simplejwt.tokens import RefreshToken +from django.contrib.auth.models import User +from django.core.mail import send_mail +from django.conf import settings +from random import randint +from .serializers import UserSerializer, RegisterSerializer + +class RegisterView(APIView): + permission_classes = [AllowAny] + + def post(self, request): + serializer = RegisterSerializer(data=request.data) + if not serializer.is_valid(): + return Response(serializer.errors, status=400) + + data = serializer.validated_data + user = User.objects.create_user( + username=data['username'], + email=data['email'] + ) + profile = Profile.objects.create(user=user, bio='') + + code = str(randint(100000, 999999)) + profile.verification_code = code + profile.save() + + send_mail( + subject="Your verification code", + message=f"Your code is: {code}", + recipient_list=[user.email], + from_email=settings.DEFAULT_FROM_EMAIL + ) + + return Response({ + 'username': user.username, + 'email': user.email + }, status=201) + +class AuthView(APIView): + permission_classes = [AllowAny] + + def post(self, request): + username = request.data.get('username') + code = request.data.get('code') + + if not username or not code: + return Response({'error': 'Username and code required'}, status=400) + + try: + user = User.objects.get(username=username) + profile = user.profile + except User.DoesNotExist: + return Response({'error': 'Invalid credentials'}, status=401) + + if profile.verification_code != code: + return Response({'error': 'Invalid code'}, status=401) + + refresh = RefreshToken.for_user(user) + return Response({ + 'refresh': str(refresh), + 'access': str(refresh.access_token), + }) + +class UserProfileView(APIView): + permission_classes = [IsAuthenticated] + + def get(self, request): + serializer = UserSerializer(request.user) + return Response(serializer.data) +``` + + +```python +# urls.py +from django.urls import path +from . import views + +urlpatterns = [ + path('register/', views.RegisterView.as_view(), name='register'), + path('auth/', views.AuthView.as_view(), name='auth'), + path('profile/', views.UserProfileView.as_view(), name='profile'), +] +``` + + +```python +# settings.py (additions) +""" +INSTALLED_APPS = [ + ... + 'rest_framework', + 'rest_framework_simplejwt', + 'your_app_name', +] + +REST_FRAMEWORK = { + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework_simplejwt.authentication.JWTAuthentication', + ), + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.IsAuthenticated', + ], +} + +from datetime import timedelta +SIMPLE_JWT = { + 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60), + 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), +} + +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_HOST = 'smtp.gmail.com' +EMAIL_PORT = 587 +EMAIL_USE_TLS = True +EMAIL_HOST_USER = 'your@email.com' +EMAIL_HOST_PASSWORD = 'yourpassword' +DEFAULT_FROM_EMAIL = EMAIL_HOST_USER +""" +``` \ No newline at end of file