izaac-2/backend/users/models.py
2025-08-31 23:05:53 +02:00

113 lines
4.2 KiB
Python

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
import secrets
import string
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.conf import settings
# Create your models here.
# Ta klasa reprezentuje użytkownika w systemie. Dziedziczy po AbstractUser, co pozwala na rozszerzenie domyślnej funkcjonalności użytkownika Django.
class User(AbstractUser):
ROLES = (
('admin', 'Admin'),
('moderator', 'Moderator'),
('user', 'User'),
)
role = models.CharField(max_length=10, choices=ROLES, default='user')
avatar_image = models.ImageField(upload_to='avatars/', null=True, blank=True)
username = models.CharField(max_length=150, unique=True)
bio = models.TextField(blank=True, default='')
token_version = models.IntegerField(default=0)
# Add related_name to resolve clashes
groups = models.ManyToManyField(
'auth.Group',
related_name='custom_user_set',
blank=True,
help_text='The groups this user belongs to.',
verbose_name='groups',
)
user_permissions = models.ManyToManyField(
'auth.Permission',
related_name='custom_user_set',
blank=True,
help_text='Specific permissions for this user.',
verbose_name='user permissions',
)
def __str__(self):
return self.username
# Ta klasa obsługuje tokeny resetowania hasła, które są używane do weryfikacji użytkowników podczas procesu resetowania hasła.
class PasswordResetToken(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
token = models.CharField(max_length=100, unique=True)
created_at = models.DateTimeField(auto_now_add=True)
expires_at = models.DateTimeField()
used = models.BooleanField(default=False)
def save(self, *args, **kwargs):
if not self.token:
# Generate a random token
alphabet = string.ascii_letters + string.digits
self.token = ''.join(secrets.choice(alphabet) for _ in range(64))
super().save(*args, **kwargs)
#Ta funkcja sprawdza, czy token jest ważny. Token jest ważny, jeśli nie został użyty i nie wygasł.
def is_valid(self):
return (
not self.used and
self.expires_at > timezone.now()
)
class Meta:
verbose_name = 'Password Reset Token'
verbose_name_plural = 'Password Reset Tokens'
class EmailChangeToken(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
new_email = models.EmailField()
token = models.CharField(max_length=100, unique=True)
created_at = models.DateTimeField(auto_now_add=True)
expires_at = models.DateTimeField()
used = models.BooleanField(default=False)
def save(self, *args, **kwargs):
if not self.token:
import secrets, string
alphabet = string.ascii_letters + string.digits
self.token = ''.join(secrets.choice(alphabet) for _ in range(64))
super().save(*args, **kwargs)
def is_valid(self):
from django.utils import timezone
return (not self.used) and (self.expires_at > timezone.now())
class Favorite(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='favorites'
)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
constraints = [
models.UniqueConstraint(
fields=['user', 'content_type', 'object_id'],
name='uniq_favorite_per_user_object'
)
]
indexes = [
models.Index(fields=['user', 'content_type']),
models.Index(fields=['content_type', 'object_id']),
]
def __str__(self):
return f'{self.user}{self.content_type.app_label}.{self.content_type.model}:{self.object_id}'