123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- from django.db import models
- from django.conf import settings # 用于引用 AUTH_USER_MODEL
- from django.utils.translation import gettext_lazy as _
- # 我们可以让小组也关联到兴趣标签
- # from accounts.models import InterestTag # 如果你想直接引用
- class Group(models.Model):
- name = models.CharField(_('小组名称'), max_length=100, unique=True)
- description = models.TextField(_('小组描述'), blank=True)
- cover_image = models.ImageField(_('小组封面'), upload_to='group_covers/', null=True, blank=True)
- creator = models.ForeignKey(
- settings.AUTH_USER_MODEL, # 关联到你的CustomUser模型
- verbose_name=_('创建者'),
- on_delete=models.SET_NULL, # 如果创建者被删除,小组可以保留,或者设为CASCADE则一起删除
- null=True, # 允许创建者为空 (虽然通常不希望这样,但SET_NULL要求)
- related_name='created_groups'
- )
- members = models.ManyToManyField(
- settings.AUTH_USER_MODEL,
- through='Membership', # 通过我们下面定义的Membership模型来管理成员关系
- through_fields=('group', 'user'), # 指定Membership模型中关联Group和User的字段名
- verbose_name=_('小组成员'),
- blank=True, # 小组刚创建时可以没有成员 (创建者会自动成为第一个成员)
- related_name='joined_groups'
- )
- # 关联到兴趣标签 (可选,但对推荐小组有帮助)
- tags = models.ManyToManyField(
- 'accounts.InterestTag', # 引用 accounts 应用的 InterestTag 模型
- verbose_name=_('相关兴趣标签'),
- blank=True,
- related_name='groups_with_tag'
- )
- created_at = models.DateTimeField(auto_now_add=True, verbose_name=_('创建时间'))
- updated_at = models.DateTimeField(auto_now=True, verbose_name=_('更新时间'))
- # (可选) 小组类型:公开、私密等
- # PUBLIC = 'public'
- # PRIVATE = 'private'
- # GROUP_TYPE_CHOICES = [
- # (PUBLIC, _('公开小组')),
- # (PRIVATE, _('私密小组')),
- # ]
- # group_type = models.CharField(
- # max_length=10,
- # choices=GROUP_TYPE_CHOICES,
- # default=PUBLIC,
- # verbose_name=_('小组类型')
- # )
- class Meta:
- verbose_name = _('小组')
- verbose_name_plural = _('小组们')
- ordering = ['-created_at'] # 按创建时间降序排列
- def __str__(self):
- return self.name
- class Membership(models.Model):
- """
- 用户和小组之间的中间模型,用于存储额外的成员关系信息。
- """
- user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_('用户'))
- group = models.ForeignKey(Group, on_delete=models.CASCADE, verbose_name=_('小组'))
- date_joined = models.DateTimeField(auto_now_add=True, verbose_name=_('加入日期'))
-
- # (可选) 成员角色
- # MEMBER = 'member'
- # ADMIN = 'admin'
- # MODERATOR = 'moderator'
- # ROLE_CHOICES = [
- # (MEMBER, _('成员')),
- # (ADMIN, _('管理员')),
- # (MODERATOR, _('版主')),
- # ]
- # role = models.CharField(
- # max_length=10,
- # choices=ROLE_CHOICES,
- # default=MEMBER,
- # verbose_name=_('角色')
- # )
- class Post(models.Model):
- group = models.ForeignKey(
- Group,
- on_delete=models.CASCADE, # 如果小组被删除,该小组下的所有帖子也一并删除
- related_name='posts', # 允许通过 group_instance.posts.all() 获取小组所有帖子
- verbose_name=_('所属小组')
- )
- author = models.ForeignKey(
- settings.AUTH_USER_MODEL, # 关联到 CustomUser 模型
- on_delete=models.CASCADE, # 如果发帖用户被删除,其帖子也一并删除 (你也可以考虑SET_NULL)
- related_name='posts', # 允许通过 user_instance.posts.all() 获取用户所有帖子
- verbose_name=_('作者')
- )
- title = models.CharField(_('帖子标题'), max_length=200, blank=True, null=True) # 帖子可以有标题,也可以没有(类似动态)
- content = models.TextField(_('帖子内容'))
- # (可选) 帖子图片或附件,可以用 ImageField 或 FileField,或者更复杂的方案如多图片关联
- # image = models.ImageField(_('帖子图片'), upload_to='post_images/', null=True, blank=True)
-
- created_at = models.DateTimeField(auto_now_add=True, verbose_name=_('发布时间'))
- updated_at = models.DateTimeField(auto_now=True, verbose_name=_('更新时间'))
- # (可选) 点赞数、评论数等统计字段,可以通过 annotate 动态获取,或在这里冗余存储以提高查询性能
- # likes_count = models.PositiveIntegerField(default=0, verbose_name=_('点赞数'))
- # comments_count = models.PositiveIntegerField(default=0, verbose_name=_('评论数'))
- class Meta:
- verbose_name = _('帖子/动态')
- verbose_name_plural = _('帖子/动态们')
- ordering = ['-created_at'] # 默认按发布时间降序排列 (最新的在前面)
- def __str__(self):
- return self.title if self.title else f"帖子来自 {self.author.display_name} 在 {self.group.name}"
- # 为了上面的 __str__ 方法,我们可能需要在 CustomUser 模型中添加一个辅助方法
- # 打开 accounts/models.py,在 CustomUser 类中添加:
- # def nickname_or_email(self):
- # return self.nickname if self.nickname else self.email
- # CustomUser.add_to_class("nickname_or_email", nickname_or_email) # 如果想动态添加
- # 或者直接在 __str__ 中写:
- # return f"{self.user.nickname if self.user.nickname else self.user.email} 加入了 {self.group.name}"
|