Files
ai_web/backend/apps/users/models.py
2026-01-28 16:00:56 +08:00

130 lines
4.4 KiB
Python

"""
User models for authentication and profile management.
"""
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
class UserManager(BaseUserManager):
"""Custom user manager."""
def create_user(self, open_id, password=None, **extra_fields):
"""Create and save a regular user."""
if not open_id:
raise ValueError('The open_id must be set')
user = self.model(open_id=open_id, **extra_fields)
if password:
user.set_password(password)
else:
user.set_unusable_password()
user.save(using=self._db)
return user
def create_superuser(self, open_id, password=None, **extra_fields):
"""Create and save a superuser."""
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('role', 'admin')
return self.create_user(open_id, password=password, **extra_fields)
class User(AbstractBaseUser, PermissionsMixin):
"""Custom user model matching the original schema."""
class Role(models.TextChoices):
USER = 'user', '普通用户'
ADMIN = 'admin', '管理员'
id = models.AutoField(primary_key=True)
open_id = models.CharField('OpenID', max_length=64, unique=True)
name = models.CharField('用户名', max_length=255, blank=True, null=True)
email = models.EmailField('邮箱', max_length=320, blank=True, null=True)
avatar = models.TextField('头像', blank=True, null=True)
login_method = models.CharField('登录方式', max_length=64, blank=True, null=True)
role = models.CharField(
'角色',
max_length=10,
choices=Role.choices,
default=Role.USER
)
stripe_customer_id = models.CharField('Stripe客户ID', max_length=255, blank=True, null=True)
stripe_account_id = models.CharField('Stripe账户ID', max_length=255, blank=True, null=True)
# Django auth fields
is_active = models.BooleanField('是否激活', default=True)
is_staff = models.BooleanField('是否员工', default=False)
created_at = models.DateTimeField('创建时间', auto_now_add=True)
updated_at = models.DateTimeField('更新时间', auto_now=True)
last_signed_in = models.DateTimeField('最后登录时间', auto_now=True)
objects = UserManager()
USERNAME_FIELD = 'open_id'
REQUIRED_FIELDS = []
class Meta:
db_table = 'users'
verbose_name = '用户'
verbose_name_plural = '用户'
indexes = [
models.Index(fields=["role", "is_active"]),
models.Index(fields=["created_at"]),
]
def __str__(self):
return self.name or self.open_id
@property
def is_admin(self):
return self.role == self.Role.ADMIN
class FriendRequest(models.Model):
"""Friend request and relationship status."""
class Status(models.TextChoices):
PENDING = "pending", "待处理"
ACCEPTED = "accepted", "已通过"
REJECTED = "rejected", "已拒绝"
CANCELED = "canceled", "已取消"
requester = models.ForeignKey(
User,
related_name="sent_friend_requests",
on_delete=models.CASCADE,
)
receiver = models.ForeignKey(
User,
related_name="received_friend_requests",
on_delete=models.CASCADE,
)
status = models.CharField(
"状态",
max_length=10,
choices=Status.choices,
default=Status.PENDING,
)
accepted_at = models.DateTimeField("通过时间", blank=True, null=True)
created_at = models.DateTimeField("创建时间", auto_now_add=True)
updated_at = models.DateTimeField("更新时间", auto_now=True)
class Meta:
db_table = "friend_requests"
verbose_name = "好友请求"
verbose_name_plural = "好友请求"
unique_together = ("requester", "receiver")
constraints = [
models.CheckConstraint(
check=~models.Q(requester=models.F("receiver")),
name="no_self_friend_request",
)
]
indexes = [
models.Index(fields=["receiver", "status"]),
models.Index(fields=["requester", "status"]),
]
def __str__(self):
return f"{self.requester_id}->{self.receiver_id} ({self.status})"