130 lines
4.4 KiB
Python
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})"
|