```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 """ ```