首页 > 解决方案 > 为什么我的页面上没有出现 follow_by(followers) 条目

问题描述

我正在制作一个类似克隆的 twitter(只是为了了解 django 中的工作原理)所以我基本上是在尝试建立一个 many_to_many 关系。我想将显示“FOLLOWED_BY”和“FOLLOWING”的功能添加到用户个人资料,但“FOLLOWED_BY”列表未显示在页面上,请有人帮助我!

在models.py中我定义了两个关系

user = models.OneToOneField(settings.AUTH_USER_MODEL, 
    on_delete=models.SET_NULL, related_name='profile', null=True, 
    blank=True)



following = models.ManyToManyField(settings.AUTH_USER_MODEL, 
     related_name='followed_by', blank=True)

在 user_detail.html 我有关于配置文件应该是什么样子的代码

这是 models.py 模块:

from django.conf import settings
from django.db import models

# Create your models here.

class UserProfile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, 
               on_delete=models.SET_NULL, related_name='profile', 
               null=True, 
                blank=True)
    following = models.ManyToManyField(settings.AUTH_USER_MODEL, 
                          related_name='followed_by', blank=True)

    def __str__(self):
        return str(self.following.all().count())

下面是 user_detail.html 文件的代码:

{% extends "base.html" %}

{% block content %}
<div  class="row">
    <div class="col-sm-3 col-xs-12" style="background-color: yellow">
        <h1>{{ object.username }}</h1>
        <p>Followers: {{ object.followed_by.count }}</p>
    </div>
<div class="col-sm-9 col-xs-12">
    <h1>Tweets</h1>
    {% for tweet in object.tweet_set.all %}
    {{ tweet }}<br/>
    {% endfor %}
   <hr/>    
    <h1>Following</h1>
    {% for user in object.profile.following.all %}
    <a href='/{{ user.username }}'>{{ user.username }}</a><br/>
    {% empty %}
    <h4>Not following any users</h4>
    {% endfor %}

   <hr/>    
    <h1>Followed By</h1>
    {% for profile in object.profile.followed_by.all %}
    <a href='/{{ profile.user.username }}'>{{ profile.user.username }}</a><br/>
    {% empty %}
    <h4>Not followed by any user</h4>
    {% endfor %}

</div>

{% endblock content %}

对于用户配置文件,我得到了我想要的 FOLLOWING 字段,但 FOLLOWED_BY 字段没有显示我该怎么做(我应该在我的代码中做哪些更改)?

标签: djangomanytomanyfield

解决方案


您定义了一个following指向用户模型的字段,而不是一个Profile. 结果 aProfile没有followed_by关系,而User对象有。

我认为最好让following指向Profile,例如:

class UserProfile(models.Model):
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL, 
        on_delete=models.SET_NULL,
        related_name='profile', 
        null=True, 
        blank=True
    )
    following = models.ManyToManyField(
        'self',
        related_name='followed_by',
        symmetrical=False,
        blank=True
    )

    def __str__(self):
        return str(self.following.all().count())

然后你可以这样渲染:

<div class="col-sm-3 col-xs-12" style="background-color: yellow">
    <h1>{{ object.username }}</h1>
    <p>Followers: {{ object.followed_by.count }}</p>
</div>
<div class="col-sm-9 col-xs-12">
    <h1>Tweets</h1>
    {% for tweet in object.tweet_set.all %}
        {{ tweet }}<br/>
    {% endfor %}
    <hr/>    
    <h1>Following</h1>
    {% for profile in object.profile.following.all %}
        <a href='/{{ profile.user.username }}'>{{ profile.user.username }}</a><br/>
    {% empty %}
        <h4>Not following any users</h4>
    {% endfor %}

    <hr/>    
    <h1>Followed By</h1>
    {% for profile in object.profile.followed_by.all %}
    <a href='/{{ profile.user.username }}'>{{ profile.user.username }}</a><br/>
    {% empty %}
       <h4>Not followed by any user</h4>
    {% endfor %}
</div>

但是,您的代码有一些(严重的)反模式。最重要的一点是不要在模板中编写业务逻辑。您应该为此使用视图。例如,您可以在视图中指定如下上下文:

context = {
    'tweets': object.tweet_set.all()
    'followers': object.profile.following.select_related('user').all()
    'followed_by': object.profile.followed_by.select_related('user').all()
}

我们在这里还可以使用.select_related()[Django-doc]来显着提高性能,因为现在所有用户都在同一个查询中获取。

您还最好使用{% url ... %}模板标签 [Django-doc]来构造查询。所以不要写:

<a href="/{{ profile.user.username }}">

最好使用反向查找来构造查询,例如:

<a href="/{% url 'profile_view' username=profile.user.username %}">

推荐阅读