校园集市小程序开发-系统架构与Django后端
E-R模型

接口设计

数据模型设计
基本模型放在models.py中
class School(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100, verbose_name='学校名称')
# 学校校区
class SchoolRegion(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100, verbose_name='校区名称')
school = models.ForeignKey(School, on_delete=models.CASCADE, related_name='regions', verbose_name='所属学校')
def __str__(self):
return f"{self.school.name} {self.name}"
# 用户
class CustomUser(models.Model):
wechat_openid = models.CharField(max_length=255, unique=True, verbose_name='微信OpenID', null=True, blank=True)
id = models.BigAutoField(primary_key=True, editable=False)
phone = models.CharField(max_length=11, unique=True, verbose_name='手机号')
gender = models.CharField(max_length=10, choices=(('male', '男'), ('female', '女'),('unknow','未知')), verbose_name='性别')
avatar = models.URLField(verbose_name='头像URL')
nickname = models.CharField(max_length=50, verbose_name='昵称')
signature = models.CharField(null=True, blank=True, max_length=200, verbose_name='个性签名')
email = models.EmailField(null=True, blank=True, unique=True, verbose_name='邮箱')
birthday = models.DateField(null=True, blank=True, verbose_name='生日')
height = models.IntegerField(null=True, blank=True, verbose_name='身高')
background_image = models.URLField(null=True, blank=True, verbose_name='背景图URL')
hometown = models.CharField(null=True, blank=True, max_length=50, verbose_name='家乡')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
is_verified = models.BooleanField(default=False, verbose_name='是否通过认证')
is_frozen = models.BooleanField(default=False, verbose_name='是否冻结')
school = models.ForeignKey('School', on_delete=models.CASCADE, related_name='students', verbose_name='所在学校', null=True, blank=True)
region = models.ForeignKey('SchoolRegion', on_delete=models.CASCADE, related_name='students', verbose_name='所在校区', null=True, blank=True)
like_number = models.IntegerField(default=0, verbose_name='点赞数')
fan_number = models.IntegerField(default=0, verbose_name='粉丝数') # 用户被关注
follow_number = models.IntegerField(default=0, verbose_name='关注数') # 用户关注数
def __str__(self):
return self.nickname
# 圈子
class Circle(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100, verbose_name='圈子名称')
description = models.TextField(verbose_name='圈子描述')
avatar = models.URLField(verbose_name='圈子头像URL')
notice = models.TextField(null=True, blank=True, verbose_name='圈子公告')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
is_verified = models.BooleanField(default=False, verbose_name='是否通过认证')
is_frozen = models.BooleanField(default=False, verbose_name='是否冻结')
creator = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='circles', verbose_name='创建者')
school = models.ForeignKey(School, on_delete=models.CASCADE, related_name='circles', verbose_name='所属学校')
like_number = models.IntegerField(default=0, verbose_name='点赞数')
collect_number = models.IntegerField(default=0, verbose_name='收藏数')
fan_number = models.IntegerField(default=0, verbose_name='粉丝数')
def __str__(self):
return f"{self.name} (创建者:{self.creator.nickname})"
# 帖子
class Post(models.Model):
id = models.BigAutoField(primary_key=True)
title = models.CharField(max_length=200, verbose_name='标题')
content = models.TextField(verbose_name='内容')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
is_frozen = models.BooleanField(default=False, verbose_name='是否冻结')
circle = models.ForeignKey(Circle, on_delete=models.CASCADE, related_name='posts', verbose_name='所属圈子')
author = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='posts', verbose_name='作者')
like_number = models.IntegerField(default=0, verbose_name='点赞数')
collect_number = models.IntegerField(default=0, verbose_name='收藏数')
comment_number = models.IntegerField(default=0, verbose_name='评论数')
def __str__(self):
return f"{self.author.nickname}发布的{self.title}"
# 评论
class Comment(models.Model):
id = models.BigAutoField(primary_key=True)
content = models.TextField(verbose_name='评论内容')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments', verbose_name='所属帖子')
reply_to = models.ForeignKey('self', on_delete=models.SET_NULL, related_name='replies', verbose_name='回复目标', null=True, blank=True)
author = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='comments', verbose_name='作者')
like_number = models.IntegerField(default=0, verbose_name='点赞数')
reply_number = models.IntegerField(default=0, verbose_name='回复数')
def __str__(self):
return f"{self.author.nickname}的{self.content}"
def delete(self, *args, **kwargs):
# 当删除一个评论时,将指向它的所有回复评论的reply_to字段设置为NULL
if self.reply_to:
self.reply_to.replies.update(reply_to=None)
super().delete(*args, **kwargs)
# 通知
class Notification(models.Model):
id = models.BigAutoField(primary_key=True)
sender = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='sent_notifications', verbose_name='事件发送者')
receiver = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='notifications', verbose_name='接收用户')
content = models.TextField(verbose_name='通知内容', null=True, blank=True)
status = models.BooleanField(default=False, verbose_name='状态') # True 表示已读,False 表示未读
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
# 上传的图片
class Image(models.Model):
id = models.BigAutoField(primary_key=True)
image = models.CharField(max_length=255, verbose_name='图片url')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
uploader = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='images', verbose_name='上传者')
关系模型另外放在relations.py
"""帖子图片"""
class PostImage(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='post_images')
image = models.ForeignKey(Image, on_delete=models.CASCADE, related_name='post_images')
# 额外排序字段
order = models.PositiveIntegerField(default=0)
class Meta:
# 确保图片的顺序是按照升序排列的
ordering = ['order']
# 确保不会有重复的帖子-图片对
unique_together = ('post', 'image')
"""用户举报(帖子、圈子、评论、用户)"""
class Report(models.Model):
id = models.BigAutoField(primary_key=True)
report_type = models.CharField(max_length=50, choices=[('post', '帖子'), ('circle', '圈子'), ('comment', '评论'), ('user', '用户')], verbose_name='举报类型')
reason = models.TextField(verbose_name='举报理由', null=True, blank=True)
status = models.CharField(max_length=50, choices=[('pending', '待处理'), ('approved', '已批准'), ('rejected', '已拒绝')], default='pending', verbose_name='举报状态')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
reporter = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='reports', verbose_name='举报者')
reported_object = models.ForeignKey(Post if report_type == 'post' else Circle if report_type == 'circle' else Comment if report_type == 'comment' else CustomUser, on_delete=models.CASCADE, related_name='reporters', verbose_name='被举报对象')
def __str__(self):
if self.report_type == 'post':
return f"{self.reporter.nickname}:id({self.reporter.id})举报了帖子{self.reported_object.title}:id({self.reported_object.id})"
elif self.report_type == 'circle':
return f"{self.reporter.nickname}:id({self.reporter.id})举报了{self.reported_object.name}:id({self.reported_object.id})"
elif self.report_type == 'comment':
return f"{self.reporter.nickname}:id({self.reporter.id})举报了{self.reported_object.content}:id({self.reported_object.id})"
elif self.report_type == 'user':
return f"{self.reporter.nickname}:id({self.reporter.id})举报了用户{self.reported_object.nickname}:id({self.reported_object.id})"
"""用户点赞(帖子、评论、圈子、用户)"""
class UserLikePost(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='liked_posts')
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='likers')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='点赞时间')
class Meta:
unique_together = ('user', 'post')
def __str__(self):
return f"{self.user.nickname} 点赞了 {self.post.title}"
class UserLikeComment(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='liked_comments')
comment = models.ForeignKey(Comment, on_delete=models.CASCADE, related_name='likers')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='点赞时间')
class Meta:
unique_together = ('user', 'comment')
def __str__(self):
return f"{self.user.nickname} 点赞了 {self.comment.content}"
class UserLikeCircle(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='liked_circles')
circle = models.ForeignKey(Circle, on_delete=models.CASCADE, related_name='likers')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='点赞时间')
class Meta:
unique_together = ('user', 'circle')
def __str__(self):
return f"{self.user.nickname} 点赞了 {self.circle.name}"
class UserLikeUser(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='liked_users')
liked_user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='likers')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='点赞时间')
class Meta:
unique_together = ('user', 'liked_user')
def __str__(self):
return f"{self.user.nickname} 点赞了 {self.liked_user.nickname}"
"""用户收藏(帖子、圈子、评论)"""
class UserCollectPost(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='collected_posts')
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='collecters')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='收藏时间')
class Meta:
unique_together = ('user', 'post')
def __str__(self):
return f"{self.user.nickname} 收藏了 {self.post.title}"
class UserCollectCircle(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='collected_circles')
circle = models.ForeignKey(Circle, on_delete=models.CASCADE, related_name='collecters')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='收藏时间')
class Meta:
unique_together = ('user', 'circle')
def __str__(self):
return f"{self.user.nickname} 收藏了 {self.circle.name}"
class UserCollectComment(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='collected_comments')
comment = models.ForeignKey(Comment, on_delete=models.CASCADE, related_name='collecters')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='收藏时间')
class Meta:
unique_together = ('user', 'comment')
def __str__(self):
return f"{self.user.nickname} 收藏了 {self.comment.content}"
"""用户关注(用户、圈子)"""
class UserFollowUser(models.Model):
follower = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='following_users')
following = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='followers')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='关注时间')
class Meta:
unique_together = ('follower', 'following') # 确保关注关系是唯一的,防止重复关注
def __str__(self):
return f"{self.follower.nickname} 关注 {self.following.nickname}"
class UserFollowCircle(models.Model):
follower = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='following_circles')
following = models.ForeignKey(Circle, on_delete=models.CASCADE, related_name='followers')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='关注时间')
class Meta:
unique_together = ('follower', 'following')
def __str__(self):
return f"{self.follower.nickname} 关注 {self.following.name}"
前端响应模型设计
对前端响应模型进行封装,resfront.py

异常处理配置中间件
CMarket/app/middleware.py

CMarket/cmarket/settings.py


浙公网安备 33010602011771号