почему я не получаю запись follow_by (последователей), отображающуюся на моей странице - PullRequest
0 голосов
/ 27 мая 2019

я делаю твиттер как клон (просто чтобы узнать, как все работает в 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 не показывает, как я могу это сделать (какие изменения я должен сделать в своем коде) ??

1 Ответ

0 голосов
/ 27 мая 2019

Вы определили поле following, которое указывает на модель пользователь , а не на Profile. В результате Profile не имеет отношения 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(
        <b>'self'</b>,
        related_name='followed_by',
        <b>symmetrical=False,</b>
        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 <b>profile</b> in object.profile.following.all %}
        <a href='/{{ <b>profile.user.username</b> }}'>{{ <b>profile.user.username</b> }}</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='/{{ <b>profile.user.username</b> }}'>{{ <b>profile.user.username</b> }}</a><br/>
    {% empty %}
       <h4>Not followed by any user</h4>
    {% endfor %}
</div>

Однако в вашем коде есть (серьезные) анти-паттерны. Наиболее важным является то, что вы должны не писать бизнес-логику в шаблоне. Вы должны использовать вид для этого. Например, вы можете указать в представлении контекст как:

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

Здесь мы также можем использовать .select_related() [Django-doc] , который значительно повысит производительность, поскольку теперь все пользователи выбираются в одном запросе.

Вам также лучше использовать шаблонный тег {% url ... %} [Django-doc] для построения запросов. Поэтому вместо того, чтобы писать:

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

лучше построить запрос, используя обратный поиск, например:

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