Bootcamp2是我学Django造的轮子,这篇文章写一下其中的关注系统。

关注属于数据库自引用的多对多关系,在Django中多对多可以用ManyToManyField,但多对多关系不能传递额外的信息,比如关注时间。所以,我们要创建一个联系两个User的关联表,表中可以加额外信息。

class Follow(models.Model):
    follower = models.ForeignKey(User, related_name='follower', on_delete=models.CASCADE)
    #on_delete是Django2必须要的
    followed = models.ForeignKey(User, related_name='followed', on_delete=models.CASCADE)
    date = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ('-date',)

    def __str__(self):
        return f'{self.follower} follow {self.followed}'

这样,关注模型就建好了,下面添加几个静态方法。

    @staticmethod
    def follow(from_user, to_user):
        Follow(follower=from_user,
               followed=to_user).save() #关注方法

    @staticmethod
    def unfollow(from_user, to_user):
        f = Follow.objects.filter(follower=from_user, followed=to_user).all()
        if f:
            f.delete() #取关

    @staticmethod
    def user_followed(from_user):
        followeders = Follow.objects.filter(follower=from_user).all()
        user_followed = []
        for followeder in followeders:
            user_followed.append(followeder.followed)
        return user_followed #得到from_user关注的人,返回列表

在views.py中调用,比如首页中获取当前用户关注的人的动态,这涉及联级查询,Django的联级查询,我不好实现,还好有__in查询

def followed(request):
    user = request.user
    all_feeds = Feed.get_feeds().filter(user__in=Follow.user_followed(user))
    #user__in 表示查询在给定的列表中
    paginator = Paginator(all_feeds, FEEDS_NUM_PATES)
    feeds = paginator.page(1)
    from_feed = -1
    if feeds:
        from_feed = feeds[0].id
    return render(request, 'feeds/followed_feeds.html', {
        'feeds': feeds,
        'from_feed': from_feed,
        'page': 1,
    })