saas-market-analysis-dubai/apps/users/serializers.py
2025-09-17 03:04:22 +05:30

157 lines
5.3 KiB
Python

"""
Serializers for user-related models.
"""
from rest_framework import serializers
from django.contrib.auth import authenticate
from django.contrib.auth.password_validation import validate_password
from .models import User, UserProfile, APIKey
import secrets
class UserRegistrationSerializer(serializers.ModelSerializer):
"""Serializer for user registration."""
password = serializers.CharField(write_only=True, validators=[validate_password])
password_confirm = serializers.CharField(write_only=True)
class Meta:
model = User
fields = ('username', 'email', 'password', 'password_confirm', 'first_name', 'last_name', 'company_name', 'phone_number')
def validate(self, attrs):
if attrs['password'] != attrs['password_confirm']:
raise serializers.ValidationError("Passwords don't match.")
return attrs
def create(self, validated_data):
validated_data.pop('password_confirm')
user = User.objects.create_user(**validated_data)
return user
class UserLoginSerializer(serializers.Serializer):
"""Serializer for user login."""
email = serializers.EmailField()
password = serializers.CharField()
def validate(self, attrs):
email = attrs.get('email')
password = attrs.get('password')
if email and password:
user = authenticate(username=email, password=password)
if not user:
raise serializers.ValidationError('Invalid credentials.')
if not user.is_active:
raise serializers.ValidationError('User account is disabled.')
attrs['user'] = user
return attrs
else:
raise serializers.ValidationError('Must include email and password.')
class UserSerializer(serializers.ModelSerializer):
"""Serializer for user details."""
profile = serializers.SerializerMethodField()
usage_limits = serializers.SerializerMethodField()
class Meta:
model = User
fields = (
'id', 'username', 'email', 'first_name', 'last_name', 'subscription_type',
'is_api_enabled', 'company_name', 'phone_number', 'is_verified',
'date_joined', 'last_login', 'profile', 'usage_limits'
)
read_only_fields = ('id', 'date_joined', 'last_login')
def get_profile(self, obj):
try:
profile = obj.profile
return UserProfileSerializer(profile).data
except UserProfile.DoesNotExist:
return None
def get_usage_limits(self, obj):
return obj.get_usage_limits()
class UserProfileSerializer(serializers.ModelSerializer):
"""Serializer for user profile."""
class Meta:
model = UserProfile
fields = (
'avatar', 'bio', 'website', 'location', 'timezone', 'language',
'notification_preferences', 'created_at', 'updated_at'
)
read_only_fields = ('created_at', 'updated_at')
class UserUpdateSerializer(serializers.ModelSerializer):
"""Serializer for updating user information."""
class Meta:
model = User
fields = ('first_name', 'last_name', 'company_name', 'phone_number')
def update(self, instance, validated_data):
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
return instance
class PasswordChangeSerializer(serializers.Serializer):
"""Serializer for password change."""
old_password = serializers.CharField()
new_password = serializers.CharField(validators=[validate_password])
new_password_confirm = serializers.CharField()
def validate(self, attrs):
if attrs['new_password'] != attrs['new_password_confirm']:
raise serializers.ValidationError("New passwords don't match.")
return attrs
def validate_old_password(self, value):
user = self.context['request'].user
if not user.check_password(value):
raise serializers.ValidationError('Old password is incorrect.')
return value
class APIKeySerializer(serializers.ModelSerializer):
"""Serializer for API keys."""
class Meta:
model = APIKey
fields = ('id', 'name', 'key', 'is_active', 'last_used', 'created_at', 'expires_at')
read_only_fields = ('id', 'key', 'last_used', 'created_at')
def create(self, validated_data):
validated_data['key'] = secrets.token_urlsafe(32)
return super().create(validated_data)
class APIKeyCreateSerializer(serializers.ModelSerializer):
"""Serializer for creating API keys."""
class Meta:
model = APIKey
fields = ('name', 'expires_at')
def create(self, validated_data):
validated_data['user'] = self.context['request'].user
validated_data['key'] = secrets.token_urlsafe(32)
return super().create(validated_data)
class SubscriptionUpdateSerializer(serializers.Serializer):
"""Serializer for updating user subscription."""
subscription_type = serializers.ChoiceField(choices=[
('free', 'Free'),
('paid', 'Paid'),
('premium', 'Premium'),
])
def validate_subscription_type(self, value):
user = self.context['request'].user
if user.subscription_type == value:
raise serializers.ValidationError('User already has this subscription type.')
return value