from django.contrib.auth.models import AbstractUser from django.db import models from apps.core.models import TimeStampedModel class User(AbstractUser): """Aurora Moments account. Email is the login identifier; username is the public @handle shown on profiles.""" email = models.EmailField(unique=True) display_name = models.CharField(max_length=150, blank=True) bio = models.TextField(max_length=500, blank=True) avatar = models.ImageField(upload_to="avatars/", blank=True, null=True) is_private = models.BooleanField( default=False, help_text="If true, new followers must be approved before they can see followers-only Moments.", ) USERNAME_FIELD = "email" REQUIRED_FIELDS = ["username"] def __str__(self): return self.username class Follow(TimeStampedModel): class Status(models.TextChoices): PENDING = "pending", "Pending" ACCEPTED = "accepted", "Accepted" follower = models.ForeignKey(User, related_name="following_edges", on_delete=models.CASCADE) following = models.ForeignKey(User, related_name="follower_edges", on_delete=models.CASCADE) status = models.CharField(max_length=10, choices=Status.choices, default=Status.ACCEPTED) class Meta: unique_together = ("follower", "following") constraints = [ models.CheckConstraint( check=~models.Q(follower=models.F("following")), name="follow_no_self_follow", ) ] def __str__(self): return f"{self.follower} -> {self.following} ({self.status})"