返回顶部

09 | 帖子相关功能开发

表结构设计

apps/community/models.py

class Post(BaseModel):
    user = ForeignKeyField(User, verbose_name="用户")
    title = CharField(max_length=200, verbose_name="标题", null=True)
    group = ForeignKeyField(CommunityGroup, verbose_name="小组")
    comment_nums = IntegerField(default=0, verbose_name="评论数")

    is_excellent = BooleanField(default=0, verbose_name="是否精华")
    is_hot = BooleanField(default=0, verbose_name="是否热门")

    content = TextField(verbose_name="内容")

    @classmethod
    def extend(cls):
        return cls.select(cls, User.id, User.nick_name).join(User)

class PostComment(BaseModel):
    # 评论和回复
    user = ForeignKeyField(User, verbose_name="用户", related_name="author")
    post = ForeignKeyField(Post, verbose_name="帖子")
    parent_comment = ForeignKeyField('self', null=True, verbose_name="评论", related_name="comments_parent")
    reply_user = ForeignKeyField(User, verbose_name="用户", related_name="replyed_author", null=True)
    content = CharField(max_length=1000, verbose_name="内容")
    reply_nums = IntegerField(default=0, verbose_name="回复数")
    like_nums = IntegerField(default=0, verbose_name="点赞数")

    @classmethod
    def extend(cls):
        #1. 多表join
        #2. 多字段映射同一个model
        author = User.alias()
        relyed_user = User.alias()
        return cls.select(cls, Post, relyed_user.id, relyed_user.nick_name, author.id, author.nick_name).join(
            Post, join_type=JOIN.LEFT_OUTER, on=cls.post).switch(cls).join(author, join_type=JOIN.LEFT_OUTER, on=cls.user).switch(cls).join(
            relyed_user, join_type=JOIN.LEFT_OUTER, on=cls.reply_user
        )


class CommentLike(BaseModel):
    # 评论点赞
    user = ForeignKeyField(User, verbose_name="用户")
    post_comment = ForeignKeyField(PostComment, verbose_name="帖子")

发布新帖

apps/community/forms.py 参数校验

class PostForm(Form):
    title = StringField("标题", validators=[DataRequired("请输入标题")])
    content = StringField("内容", validators=[DataRequired("请输入内容")])

 

apps/community/handler.py  发布帖子hander

class PostHandler(RedisHandler):
    @authenticated_async
    async def get(self,group_id, *args, **kwargs):
        #获取小组内的帖子
         pass
    
    @authenticated_async
    async def post(self,group_id, *args, **kwargs):
        #小组内发帖
        re_data = {}

        try:
            group = await self.application.objects.get(CommunityGroup, id=int(group_id))

            group_member = await self.application.objects.get(CommunityGroupMember, user=self.current_user,
                                                              community=group, status="agree")
            param = self.request.body.decode("utf8")
            param = json.loads(param)
            form = PostForm.from_json(param)
            if form.validate():
                post = await self.application.objects.create(Post, user=self.current_user,title=form.title.data,
                                                             content=form.content.data, group=group)
                re_data["id"] = post.id
            else:
                self.set_status(400)
                for field in form.errors:
                    re_data[field] = form.errors[field][0]

        except CommunityGroup.DoesNotExist as e:
            self.set_status(404)
        except CommunityGroupMember.DoesNotExist as e:
            self.set_status(403)

        self.finish(re_data)
    

 

 apps/community/urls.py路由

urlpattern = (

    url("/posts/([0-9]+)/", PostDetailHandler),
)

 

联调

获取帖子

 apps/community/handler.py  获取帖子hander 重写get方法

class PostHandler(RedisHandler):
    @authenticated_async
    async def get(self,group_id, *args, **kwargs):
        #获取小组内的帖子
        post_list = []
        try:

            group = await self.application.objects.get(CommunityGroup, id=int(group_id))

            group_member = await self.application.objects.get(CommunityGroupMember, user=self.current_user,
                                                              community=group, status="agree")
            posts_query = Post.extend()
            c = self.get_argument("c", None)
            if c == "hot":
                posts_query = posts_query.filter(Post.is_hot == True)
            if c == "excellent":
                posts_query = posts_query.filter(Post.is_excellent == True)
            posts = await self.application.objects.execute(posts_query)

            for post in posts:
                item_dict = {
                    "user":{
                        "id":post.user.id,
                        "nick_name": post.user.nick_name
                    },
                    "id":post.id,
                    "title":post.title,
                    "content":post.content,
                    "comment_nums":post.comment_nums
                }
                post_list.append(item_dict)
        except CommunityGroupMember.DoesNotExist as e:
            self.set_status(403)
        except CommunityGroup.DoesNotExist as e:
            self.set_status(404)

        self.finish(json.dumps(post_list))


    @authenticated_async
    async def post(self,group_id, *args, **kwargs):
        #小组内发帖
        re_data = {}

        try:
            group = await self.application.objects.get(CommunityGroup, id=int(group_id))

            group_member = await self.application.objects.get(CommunityGroupMember, user=self.current_user,
                                                              community=group, status="agree")
            param = self.request.body.decode("utf8")
            param = json.loads(param)
            form = PostForm.from_json(param)
            if form.validate():
                post = await self.application.objects.create(Post, user=self.current_user,title=form.title.data,
                                                             content=form.content.data, group=group)
                re_data["id"] = post.id
            else:
                self.set_status(400)
                for field in form.errors:
                    re_data[field] = form.errors[field][0]

        except CommunityGroup.DoesNotExist as e:
            self.set_status(404)
        except CommunityGroupMember.DoesNotExist as e:
            self.set_status(403)

        self.finish(re_data)

 

联调

帖子详情

  apps/community/handler.py  帖子详情

# 获取帖子详情
class PostDetailHandler(RedisHandler):
    @authenticated_async
    async def get(self, post_id, *args, **kwargs):
        #获取某一个帖子的详情
        re_data = {}
        post_details = await self.application.objects.execute(Post.extend().where(Post.id==int(post_id)))
        re_count = 0
        for data in post_details:
            item_dict = {}
            item_dict["user"] = model_to_dict(data.user)
            item_dict["title"] = data.title
            item_dict["content"] = data.content
            item_dict["comment_nums"] = data.comment_nums
            item_dict["add_time"] = data.add_time.strftime("%Y-%m-%d")
            re_data = item_dict

            re_count += 1

        if re_count == 0:
            self.set_status(404)

        self.finish(re_data)

  apps/community/urls.py路由

urlpattern = (

    url("/posts/([0-9]+)/", PostDetailHandler),
)

联调 

 

帖子评论相关功能开发

 添加评论

 apps/community/forms.py 参数校验 

class PostComentForm(Form):
    content = StringField("内容", validators=[DataRequired("请输入评论内容"),
                                            Length(min=3, message="内容不能少于3个字符")])

 

 apps/community/handler.py  帖子评论handler

# 帖子评论
class PostCommentHanlder(RedisHandler):
    @authenticated_async
    async def get(self, post_id, *args, **kwargs):
        #获取帖子的所有评论
        pass

    @authenticated_async
    async def post(self, post_id, *args, **kwargs):
        #新增评论
        re_data = {}
        param = self.request.body.decode("utf8")
        param = json.loads(param)
        form = PostComentForm.from_json(param)
        if form.validate():
            try:
                post = await self.application.objects.get(Post, id=int(post_id))
                post_comment = await self.application.objects.create(PostComment, user=self.current_user, post=post,
                                                                     content=form.content.data)
                post.comment_nums += 1
                await self.application.objects.update(post)
                re_data["id"] = post_comment.id
                re_data["user"] = {}
                re_data["user"]["nick_name"] = self.current_user.nick_name
                re_data["user"]["id"] = self.current_user.id
            except Post.DoesNotExist as e:
                self.set_status(404)
        else:
            self.set_status(400)
            for field in form.errors:
                re_data[field] = form.errors[field][0]

        self.finish(re_data)

 

  apps/community/urls.py路由

urlpattern = (
    url("/posts/([0-9]+)/comments/", PostCommentHanlder),
)

 获取帖子评论列变

 apps/community/handler.py  帖子评论列表handler 重写get方法

class PostCommentHanlder(RedisHandler):
    @authenticated_async
    async def get(self, post_id, *args, **kwargs):
        #获取帖子的所有评论
        re_data = []

        try:
            post = await self.application.objects.get(Post, id=int(post_id))
            post_coments = await self.application.objects.execute(
                PostComment.extend().where(PostComment.post==post, PostComment.parent_comment.is_null(True)).order_by(PostComment.add_time.desc())
            )

            for item in post_coments:
                has_liked = False
                try:
                    comments_like = await self.application.objects.get(CommentLike, post_comment_id=item.id, user_id=self.current_user.id)
                    has_liked = True
                except CommentLike.DoesNotExist:
                    pass

                item_dict = {
                    "user":model_to_dict(item.user),
                    "content":item.content,
                    "reply_nums":item.reply_nums,
                    "like_nums": item.like_nums,
                    "has_liked": has_liked,
                    "id": item.id,
                }

                re_data.append(item_dict)
        except Post.DoesNotExist as e:
            self.set_status(404)
        self.finish(self.finish(json.dumps(re_data, default=json_serial)))

    @authenticated_async
    async def post(self, post_id, *args, **kwargs):
        #新增评论
        re_data = {}
        param = self.request.body.decode("utf8")
        param = json.loads(param)
        form = PostComentForm.from_json(param)
        if form.validate():
            try:
                post = await self.application.objects.get(Post, id=int(post_id))
                post_comment = await self.application.objects.create(PostComment, user=self.current_user, post=post,
                                                                     content=form.content.data)
                post.comment_nums += 1
                await self.application.objects.update(post)
                re_data["id"] = post_comment.id
                re_data["user"] = {}
                re_data["user"]["nick_name"] = self.current_user.nick_name
                re_data["user"]["id"] = self.current_user.id
            except Post.DoesNotExist as e:
                self.set_status(404)
        else:
            self.set_status(400)
            for field in form.errors:
                re_data[field] = form.errors[field][0]

        self.finish(re_data)

 

 联调

帖子回复

 添加回复功能

  apps/community/forms.py 参数校验 

class CommentReplyForm(Form):
    replyed_user = IntegerField("回复用户", validators=[DataRequired("请输入回复用户")])
    content = StringField("内容", validators=[DataRequired("请输入评论内容"),
                                            Length(min=3, message="内容不能少于3个字符")])

 

  apps/community/handler.py  帖子回复handler 

# 帖子回复
class CommentReplyHandler(RedisHandler):
    @authenticated_async
    async def get(self, comment_id, *args, **kwargs):
        pass

    @authenticated_async
    async def post(self, comment_id, *args, **kwargs):
        # 添加回复
        re_data = {}
        param = self.request.body.decode("utf8")
        param = json.loads(param)
        form = CommentReplyForm.from_json(param)
        if form.validate():
            try:
                comment = await self.application.objects.get(PostComment, id=int(comment_id))
                reply_user = await self.application.objects.get(User, id=form.replyed_user.data)
                post = await self.application.objects.get(Post, id=int(comment.post_id))
                reply = await self.application.objects.create(PostComment, post=post, user=self.current_user,
                                                              parent_comment=comment, reply_user=reply_user,
                                                              content=form.content.data)

                # 修改comment的回复数
                comment.reply_nums += 1
                await self.application.objects.update(comment)

                re_data["id"] = reply.id
                re_data["user"] = {
                    "id": self.current_user.id,
                    "nick_name": self.current_user.nick_name
                }

                # 写入消息
                await self.application.objects.create(Message, sender=self.current_user, receiver=reply_user,
                                                      message_type=2, parent_content=comment.content,
                                                      message=form.content.data)

            except PostComment.DoesNotExist as e:
                self.set_status(404)
            except User.DoesNotExist as e:
                self.set_status(400)
                re_data["replyed_user"] = "用户不存在"
        else:
            self.set_status(400)
            for field in form.errors:
                re_data[field] = form.errors[field][0]

        self.finish(re_data)

 

   apps/community/urls.py路由

urlpattern = (
    url("/comments/([0-9]+)/likes/", CommentsLikeHanlder),
)  

获取回复列表

  apps/community/handler.py  获取帖子回复列表 handler 重写get方法 

# 帖子回复
class CommentReplyHandler(RedisHandler):
    @authenticated_async
    async def get(self, comment_id, *args, **kwargs):
        re_data = []
        comment_replys = await self.application.objects.execute(PostComment.extend().where(PostComment.parent_comment_id==int(comment_id)))

        for item in comment_replys:
            item_dict = {
                "user":model_to_dict(item.user),
                "content":item.content,
                "reply_nums":item.reply_nums,
                "add_time":item.add_time.strftime("%Y-%m-%d"),
                "id":item.id
            }

            re_data.append(item_dict)

        self.finish(self.finish(json.dumps(re_data, default=json_serial)))

    @authenticated_async
    async def post(self, comment_id, *args, **kwargs):
        # 添加回复
        re_data = {}
        param = self.request.body.decode("utf8")
        param = json.loads(param)
        form = CommentReplyForm.from_json(param)
        if form.validate():
            try:
                comment = await self.application.objects.get(PostComment, id=int(comment_id))
                reply_user = await self.application.objects.get(User, id=form.replyed_user.data)
                post = await self.application.objects.get(Post, id=int(comment.post_id))
                reply = await self.application.objects.create(PostComment, post=post, user=self.current_user,
                                                              parent_comment=comment, reply_user=reply_user,
                                                              content=form.content.data)

                # 修改comment的回复数
                comment.reply_nums += 1
                await self.application.objects.update(comment)

                re_data["id"] = reply.id
                re_data["user"] = {
                    "id": self.current_user.id,
                    "nick_name": self.current_user.nick_name
                }

                # 写入消息
                await self.application.objects.create(Message, sender=self.current_user, receiver=reply_user,
                                                      message_type=2, parent_content=comment.content,
                                                      message=form.content.data)

            except PostComment.DoesNotExist as e:
                self.set_status(404)
            except User.DoesNotExist as e:
                self.set_status(400)
                re_data["replyed_user"] = "用户不存在"
        else:
            self.set_status(400)
            for field in form.errors:
                re_data[field] = form.errors[field][0]

        self.finish(re_data)

 

在这里使用了连接多个表进行查询和对字段起别名

    @classmethod
    def extend(cls):
        #1. 多表join
        #2. 多字段映射同一个model
        author = User.alias()
        relyed_user = User.alias()
        return cls.select(cls, Post, relyed_user.id, relyed_user.nick_name, author.id, author.nick_name).join(
            Post, join_type=JOIN.LEFT_OUTER, on=cls.post).switch(cls).join(author, join_type=JOIN.LEFT_OUTER, on=cls.user).switch(cls).join(
            relyed_user, join_type=JOIN.LEFT_OUTER, on=cls.reply_user
        )

联调

评论点赞

  apps/community/handler.py  评论点赞handler

# 帖子点赞
class CommentsLikeHanlder(RedisHandler):
    @authenticated_async
    async def post(self, comment_id, *args, **kwargs):
        re_data = {}
        try:
            comment = await self.application.objects.get(PostComment, id=int(comment_id))
            comment_like = await self.application.objects.create(CommentLike, user=self.current_user,
                                                          post_comment=comment)
            comment.like_nums += 1
            await self.application.objects.update(comment)

            re_data["id"] = comment_like.id

        except PostComment.DoesNotExist as e:
            self.set_status(404)

        self.finish(re_data)

    apps/community/urls.py路由

urlpattern = (
    # 小组功能开发
    url("/comments/([0-9]+)/likes/", CommentsLikeHanlder),
)

 联调

 

posted @ 2019-01-01 14:27  Crazymagic  阅读(236)  评论(0编辑  收藏  举报