基于python的web应用开发-添加关注者

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于python的web应用开发-添加关注者相关的知识,希望对你有一定的参考价值。

社交web允许用户之间相互联系。

例如:

关注者、好友、联系人、联络人或伙伴。

记录两个用户之间的定向联系,在数据库查询中也要使用这种联系。

 

一、论数据库关系

一对多关系

数据库使用关系建立记录之间的联系。其中,一对多关系是最常用的关系类型,它把一个记录和一组相关的记录联系在一起。实现这种关系,要在“多”这一层加一个外键,指向“一”这一侧,例如下列代码:

class Role(db.Model):
    __tablename__ = roles

  id = db.Column(db.Integer,primary_key = True) #... users = db.relationship(User, backref=role, lazy=dynamic) class User(UserMixin, db.Model): __tablename__ = users #... role_id = db.Column(db.Integer, db.ForeignKey(roles.id))

其中,users的数据库表中添加了一个外键role_id 指向了roles表的id

大部分的其他关系类型都可以从一对多类型中衍生。

多对一关系从“多”这一侧看,就是一对多关系。一对一关系类型是简化版的一对多关

多对多关系

解决方法是添加第三张表,这个表称为关联表。多对多关系可以分解成原表和关联表之间的两个一对多关系。

技术分享

用SQLAlchemy实现图中的关系。

registrations = db.Table(registrations,
      db.Column(student_id, db.Integer,        db.ForeignKey(students.id)),
db.Column(class_id, db.Integer, db.ForeignKey(classes.id))
)
class Student(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    classes = db.relationship(Class,
        secondary=registrations,
        backref=db.backref(students, lazy=dynamic),
        lazy=dynamic)
class Class(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String)            

多对多关系仍使用定义一对多关系的db.relationship() 方法进行定义,但在多对多关系中,必须把secondary 参数设为关联表。多对多关系可以在任何一个类中定义,backref 参数会处理好关系的另一侧。关联表就是一个简单的表,不是模型,SQLAlchemy 会自动接管这个表。

自引用关系

如果关系中的两侧都在同一个表中,这种关系称为自引用关系。

高级多对多关系

使用多对多关系时,往往需要存储所联两个实体之间的额外信息。对用户之间的关注来说,可以存储用户关注另一个用户的日期,这样就能按照时间顺序列出所有关注者。这种
信息只能存储在关联表中,但是在之前实现的学生和课程之间的关系中,关联表完全是由SQLAlchemy 掌控的内部表。

为了能在关系中处理自定义的数据,我们必须提升关联表的地位,使其变成程序可访问的模型。

app/models/user.py:关注关联表的模型实现

class Follow(db.Model):
    __tablename__ = follows
    follower_id = db.Column(db.Integer,db.ForeignKey(users.id),primary_key = True)
    followed_id = db.Column(db.Integer,db.ForegnKey(users.id),primary_key = True)
    timestamp = db.Column(db.DateTime,default = datetime.utcnow)

app/models/user.py:使用两个一对多关系实现的多对多关系

class User(UserMixin, db.Model):
# ...
    followed = db.relationship(Follow,
        foreign_keys=[Follow.follower_id],
        backref=db.backref(follower, lazy=joined),
        lazy=dynamic,
        cascade=all, delete-orphan)
    followers = db.relationship(Follow,
        foreign_keys=[Follow.followed_id],
       backref=db.backref(followed, lazy=joined),
       lazy=dynamic,
       cascade=all, delete-orphan)            

程序现在要处理两个一对多关系,以便实现多对多关系。由于这些操作经常需要重复执行,所以最好在User 模型中为所有可能的操作定义辅助方法

app/models.py:关注关系的辅助方法

 #关注关系的辅助方法
    def follow(self,user):
        if not self.is_following(user):
            f = Follow(follower=self,followed=user)
            db.session.add(f)

    def unfollow(self,user):
        f = self.followed.filter_by(followed_id = user.id).first()
        if f:
            db.session.delete(f)

    def is_following(self,user):
        return self.followed.filter_by(follow_id = user.id).first() is not None

    def is_followed(self,user):
        return self.followers.filter_by(follow_id = user.id).first() is not None

二、在资料页中显示关注者

app/templates/user.html:在用户资料页上部添加关注信息

{% extends "base.html" %}
{% import "_macros.html" as macros %}

{% block title %}微博 - {{ user.username }}{% endblock %}

{% block page_content %}
<div class="page-header">
    <img class="img-rounded profile-thumbnail" src="{{ user.gravatar(size=256) }}">
    <div class="profile-header">
        <h1>{{ user.username }}</h1>
        {% if user.name or user.location %}
        <p>
            {% if user.name %}{{ user.name }}<br>{% endif %}
            {% if user.location %}
                From <a href="http://maps.google.com/?q={{ user.location }}">{{ user.location }}</a><br>
            {% endif %}
        </p>
        {% endif %}
        {% if current_user.is_administrator() %}
        <p><a href="mailto:{{ user.email }}">{{ user.email }}</a></p>
        {% endif %}
        {% if user.about_me %}<p>{{ user.about_me }}</p>{% endif %}
        <p>创建时间 {{ moment(user.member_since).format(‘L‘) }}. 最后访问 {{ moment(user.last_seen).fromNow() }}.</p>
        <p>{{ user.posts.count() }} 博客文章.</p>
        <p>
               {% if current_user.can(Permission.FOLLOW) and user != current_user %}
                {% if not current_user.is_following(user) %}
                <a href="{{ url_for(‘.follow‘, username=user.username) }}" class="btn btn-primary">关注</a>
                {% else %}
                <a href="{{ url_for(‘.unfollow‘, username=user.username) }}" class="btn btn-success">取消关注</a>
                {% endif %}
            {% endif %}
            <a href="{{ url_for(‘.followers‘, username=user.username) }}">关注者: <span class="badge">{{ user.followers.count() }}</span></a>
            <a href="{{ url_for(‘.followed_by‘, username=user.username) }}">被关注: <span class="badge">{{ user.followed.count() }}</span></a>
            {% if current_user.is_authenticated and user != current_user and user.is_following(current_user) %}
            | <span class="label label-default">关注了你</span>
            {% endif %}
        </p>
        <p>
            {% if user == current_user %}
            <a class="btn btn-default" href="{{ url_for(‘.edit_profile‘) }}">编辑个人资料</a>
            {% endif %}
            {% if current_user.is_administrator() %}
            <a class="btn btn-danger" href="{{ url_for(‘.edit_profile_admin‘, id=user.id) }}">编辑个人资料 [管理员]</a>
            {% endif %}
        </p>
    </div>
</div>
<h3>Posts by {{ user.username }}</h3>
{% include ‘_posts.html‘ %}
{% if pagination %}
<div class="pagination">
    {{ macros.pagination_widget(pagination, ‘.user‘, username=user.username) }}
</div>
{% endif %}
{% endblock %}

 




以上是关于基于python的web应用开发-添加关注者的主要内容,如果未能解决你的问题,请参考以下文章

《Flask Web开发——基于Python的Web应用开发实践》一字一句上机实践(下)

Flask Web 开发 关注者

使用 python 脚本获取 Instagram 关注者列表

使用 Selenium 从 Twitter 抓取关注者

如何在新的 Spotify Web api 上获取用户的关注者和用户的关注用户?

如何使用 Python 删除我自己的 Instagram 关注者?