Parcourir la source

feat: 显示关注和粉丝

SongZihuan il y a 2 ans
Parent
commit
81321c8166

+ 26 - 0
app/auth.py

@@ -267,3 +267,29 @@ def user_page():
     if not user:
         return abort(404)
     return render_template("auth/user.html", user=user)
+
+
+@auth.route("/follower/list")
+def follower_page():
+    if current_user.follower_count == 0:
+        return render_template("auth/no_follow.html", title="粉丝", msg="你暂时一个粉丝都没有哦。")
+
+    page = request.args.get("page", 1, type=int)
+    pagination = current_user.follower.paginate(page=page, per_page=8, error_out=False)
+    return render_template("auth/follow.html",
+                           items=[i.follower for i in pagination.items],
+                           pagination=pagination,
+                           title="粉丝")
+
+
+@auth.route("/followed/list")
+def followed_page():
+    if current_user.followed_count == 0:
+        return render_template("auth/no_follow.html", title="关注", msg="你暂时未关注任何人。")
+
+    page = request.args.get("page", 1, type=int)
+    pagination = current_user.followed.paginate(page=page, per_page=8, error_out=False)
+    return render_template("auth/follow.html",
+                           items=[i.followed for i in pagination.items],
+                           pagination=pagination,
+                           title="关注")

+ 43 - 9
app/db.py

@@ -13,10 +13,10 @@ db = SQLAlchemy()
 
 class Follow(db.Model):
     time = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
-    follower_id = db.Column(db.Integer, db.ForeignKey("user.id"), primary_key=True, nullable=True)
-    followed_id = db.Column(db.Integer, db.ForeignKey("user.id"), primary_key=True, nullable=True)
-    follower = db.relationship("User", primaryjoin="Follow.follower_id==User.id", back_populates="follower")
-    followed = db.relationship("User", primaryjoin="Follow.followed_id==User.id", back_populates="followed")
+    follower_id = db.Column(db.Integer, db.ForeignKey("user.id"), primary_key=True, nullable=True)  # 关注者
+    followed_id = db.Column(db.Integer, db.ForeignKey("user.id"), primary_key=True, nullable=True)  # 被关注者
+    follower = db.relationship("User", primaryjoin="Follow.follower_id==User.id", back_populates="followed")
+    followed = db.relationship("User", primaryjoin="Follow.followed_id==User.id", back_populates="follower")
 
 
 
@@ -36,10 +36,18 @@ class User(db.Model, UserMixin):
     role = db.relationship("Role", back_populates="user")
     comment = db.relationship("Comment", back_populates="auth")
 
-    follower = db.relationship("Follow", primaryjoin="Follow.follower_id==User.id", back_populates="follower",
-                               lazy="dynamic")
-    followed = db.relationship("Follow", primaryjoin="Follow.followed_id==User.id", back_populates="followed",
-                               lazy="dynamic")
+    followed = db.relationship("Follow", primaryjoin="Follow.follower_id==User.id", back_populates="follower",
+                               lazy="dynamic")  # User 关注的人
+    follower = db.relationship("Follow", primaryjoin="Follow.followed_id==User.id", back_populates="followed",
+                               lazy="dynamic")  # 关注 User 的人
+
+    @property
+    def follower_count(self):
+        return self.follower.count()
+
+    @property
+    def followed_count(self):
+        return self.followed.count()
 
     @staticmethod
     def register_creat_token(email: str, passwd_hash: str):
@@ -259,4 +267,30 @@ def create_fake_archive_comment():
         except IntegrityError:
             db.session.rollback()
         else:
-            count_archive_comment += 1
+            count_archive_comment += 1
+
+
+def create_fake_follow():
+    from random import randint
+    from sqlalchemy.exc import IntegrityError
+
+    user_count = User.query.count()
+
+    count_archive_comment = 0
+    while count_archive_comment < 20:
+        follower_id = randint(0, user_count)
+        followed_id = randint(0, user_count)
+        if follower_id == followed_id:
+            continue
+
+        follower = User.query.offset(follower_id).limit(1).first()
+        followed = User.query.offset(followed_id).limit(1).first()
+        follow = Follow(followed=followed, follower=follower)
+        db.session.add(follow)
+
+        try:
+            db.session.commit()
+        except IntegrityError:
+            db.session.rollback()
+        else:
+            count_archive_comment += 1

+ 3 - 1
main.py

@@ -23,7 +23,8 @@ def make_shell_context():
                         create_faker_user,
                         create_faker_comment,
                         create_faker_archive,
-                        create_fake_archive_comment)
+                        create_fake_archive_comment,
+                        create_fake_follow)
     return {
         "app": app,
         "db": db,
@@ -32,4 +33,5 @@ def make_shell_context():
         "create_faker_comment": create_faker_comment,
         "create_faker_archive": create_faker_archive,
         "create_fake_archive_comment": create_fake_archive_comment,
+        "create_fake_follow": create_fake_follow,
     }

+ 53 - 0
templates/auth/follow.html

@@ -0,0 +1,53 @@
+{% extends "base.html" %}
+
+{% block title %} {{ title }} {% endblock %}
+
+{% block content %}
+    <div class="container text-center">
+        <div class="mt-2 text-start">
+            {% for i in items %}
+                <div class="card mt-2">
+                    <div class="card-body">
+                        <h4 class="card-title"> 用户: {{ i.email }} </h4>
+                        <p class="card-text">  ID: {{ i.id }} </p>
+                        <p class="text-end">
+                            <a class="btn btn-link" href="{{ url_for("auth.user_page", user=i.id) }}"> 前往查看 </a>
+                        </p>
+                    </div>
+                </div>
+            {% endfor %}
+        </div>
+
+        <ul class="pagination justify-content-center mt-2">
+            {% if pagination.has_prev %}
+                <li class="page-item">
+                    <a class="page-link" href="{{ url_for("auth.follower_page", page=pagination.prev_num) }}"> 上一页 </a>
+                </li>
+            {% endif %}
+
+            {% for p in pagination.iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) %}
+                {% if p %}
+                    {% if p == pagination.page %}
+                        <li class="page-item active">
+                            <a class="page-link" href="{{ url_for("auth.follower_page", page=p) }}"> {{ p }} </a>
+                        </li>
+                    {% else %}
+                        <li class="page-item">
+                            <a class="page-link" href="{{ url_for("auth.follower_page", page=p) }}"> {{ p }} </a>
+                        </li>
+                    {% endif %}
+                {% else %}
+                    <li class="page-item disabled">
+                        <a class="page-link" href="#">&hellip;</a>
+                    </li>
+                {% endif %}
+            {% endfor %}
+
+            {% if pagination.has_next %}
+                <li class="page-item">
+                    <a class="page-link" href="{{ url_for("auth.follower_page", page=pagination.next_num) }}"> 下一页 </a>
+                </li>
+            {% endif %}
+        </ul>
+    </div>
+{% endblock %}

+ 9 - 0
templates/auth/no_follow.html

@@ -0,0 +1,9 @@
+{% extends "base.html" %}
+
+{% block title %} {{ title }} {% endblock %}
+
+{% block content %}
+    <div class="container">
+        <div class="alert alert-warning"> <strong>抱歉!</strong> {{ msg }} </div>
+    </div>
+{% endblock %}

+ 8 - 6
templates/auth/user.html

@@ -5,15 +5,17 @@
 {% block content %}
     <div class="container">
         <h5> 用户信息 </h5>
-        <ul class="list-group list-group-flush">
-            <li class="list-group-item">用户ID:{{ user.id }}</li>
-            <li class="list-group-item">用户邮箱:{{ user.email }}</li>
-            <li class="list-group-item">是否封禁:{{ "否" if user.role.has_permission(Role.USABLE) else "是" }}</li>
-        </ul>
+        <div class="list-group list-group-flush">
+            <a class="list-group-item">用户ID:{{ user.id }}</a>
+            <a class="list-group-item">用户邮箱:{{ user.email }}</a>
+            <a class="list-group-item">是否封禁:{{ "否" if user.role.has_permission(Role.USABLE) else "是" }} </a>
+            <a class="list-group-item">关注:{{ user.followed_count }}</a>
+            <a class="list-group-item">粉丝:{{ user.follower_count }}</a>
+        </div>
 
         <div class="text-end">
             <div class="btn-group">
-                <a class="btn btn-outline-danger" href="{{ url_for("auth.logout_page") }}"> 关注 </a>
+                <a class="btn btn-outline-danger" href="#"> 关注 </a>
             </div>
         </div>
 

+ 9 - 7
templates/auth/yours.html

@@ -5,13 +5,15 @@
 {% block content %}
     <div class="container">
         <h5> 用户信息 </h5>
-        <ul class="list-group list-group-flush">
-            <li class="list-group-item">用户ID:{{ current_user.id }}</li>
-            <li class="list-group-item">用户邮箱:{{ current_user.email }}</li>
-            <li class="list-group-item">是否封禁:{{ "否" if current_user.role.has_permission(Role.USABLE) else "是" }}</li>
-            <li class="list-group-item">角色组:{{ current_user.role.name }}</li>
-            <li class="list-group-item">用户权限:{{ current_user.role.permission }}</li>
-        </ul>
+        <div class="list-group list-group-flush">
+            <a class="list-group-item">用户ID:{{ current_user.id }}</a>
+            <a class="list-group-item">用户邮箱:{{ current_user.email }}</a>
+            <a class="list-group-item">是否封禁:{{ "否" if current_user.role.has_permission(Role.USABLE) else "是" }}</a>
+            <a class="list-group-item">角色组:{{ current_user.role.name }}</a>
+            <a class="list-group-item">用户权限:{{ current_user.role.permission }}</a>
+            <a class="list-group-item" href="{{ url_for("auth.followed_page") }}">关注:{{ current_user.followed_count }}</a>
+            <a class="list-group-item" href="{{ url_for("auth.follower_page") }}">粉丝:{{ current_user.follower_count }}</a>
+        </div>
 
         <div class="text-end">
             <div class="btn-group">

+ 0 - 1
templates/comment/list.html

@@ -67,6 +67,5 @@
                 </li>
             {% endif %}
         </ul>
-
     </div>
 {% endblock %}