【问题标题】:Add a friend system on django在django上添加好友系统
【发布时间】:2020-09-01 23:52:03
【问题描述】:

我一直在尝试添加朋友系统,用户可以在其中添加和删除朋友(其他用户),在完成代码后,我发现当登录用户尝试从其他用户的个人资料中添加朋友时出现错误,添加朋友按钮重定向到登录的用户配置文件,使其无法添加新朋友,它可以将自己添加为朋友。我个人认为错误出在 views.py 个人资料视图上。

views.py(profile 显示用户的个人资料,change_friend 是添加和删除朋友的那个)

    def profile(request, username=None):
        friend = Friend.objects.filter(current_user=request.user).first()
        friends = []
        if friend:   
          friends = friend.users.all()
        if username:
          post_owner = get_object_or_404(User, username=username)
          user_posts=Post.objects.filter(user_id=post_owner)
        else:
          post_owner = request.user
          user_posts=Post.objects.filter(user=request.user)
        args1 = {
            'post_owner': post_owner,
            'user_posts': user_posts,
            'friends': friends,
        }
        return render(request, 'profile.html', args1)

    def change_friends(request, operation, pk):
        friend = User.objects.get(pk=pk)
        if operation == 'add':
          Friend.make_friend(request.user, friend)
        elif operation == 'remove':
          Friend.lose_friend(request.user, friend)
        return redirect('profile')

模型.py

    class Friend(models.Model):
        users = models.ManyToManyField(User, default='users', blank=True, related_name='users')
        current_user = models.ForeignKey(User, related_name='owner', on_delete=models.CASCADE, null=True)

        @classmethod
        def make_friend(cls, current_user, new_friend):
            friend, created = cls.objects.get_or_create(
                current_user=current_user
            )
            friend.users.add(new_friend)

        @classmethod
        def lose_friend(cls, current_user, new_friend):
            friend, created = cls.objects.get_or_create(
                current_user=current_user
            )
            friend.users.remove(new_friend)

profile.html

    <div class="media">
      <div class="media-body">
        <h2 class="account-heading">{{ post_owner.username }}</h2>
        <p class="text-secondary">{{ post_owner.email }}</p>
        {% if not user in friends %}
          <a href="{% url 'change_friends' operation='add' pk=user.pk %}">
            <button type="button">add Friend</button>
          </a>
        {% endif %}
      </div>
    </div>
    <div>
      <h2>Friends</h2>
      {% for friend in friends %}
        <p>{{ friend.username }}</p>
        <a href="{% url 'change_friends' operation='remove' pk=friend.pk %}">
          <button type="button">Remove Friend</button>
        </a>
      {% endfor %}
    </div>

urls.py

    urlpatterns = [
        path('profile/<str:username>/', views.profile, name='profile_pk'),
        url(r'^connect/(?P<operation>.+)/(?P<pk>\d+)/$', views.change_friends, name='change_friends'),
    ]

【问题讨论】:

  • 我对 html 部分有点困惑。你想实现“post_owner(技术上与request.user相同)想将其他用户添加为好友”这个问题吗?如果是这样,您需要在模板中提供“其他用户”以循环并为每个用户生成“添加朋友”按钮。
  • @DenizKaplan 如何在模板中提供“其他用户”以循环生成“添加好友”?
  • 如果没有限制,只需将friends_to_add 传递给您的模板,这是User.objects.exclude(id=request.user.id) 的结果。如果您还想从查询集中删除用户的朋友,只需链接 .exclude(id__in=friend.users.values_list("id")) 如果这很复杂。我可以用详细视图和 html 代码在答案中解释。我在 cmets 中有字符限制。
  • @DenizKaplan 是的,这对我来说看起来有点复杂,请您添加一个答案以便我能更好地理解吗?

标签: python html django django-models django-views


【解决方案1】:

问题是您通过user 对象将request.user 对象传递给change_friends 视图。在模板中使用时默认为user == request.user

只需将您在 profile.html 中的那一行更改为:

<a href="{% url 'change_friends' operation='add' pk=post_owner.pk %}">
    <button type="button">add Friend</button>
</a>

现在,我注意到,一旦用户添加了新朋友,您就会将用户重定向到 profile 视图,这不是您想要的。这是因为当您在change_friends 视图中调用redirect() 函数时,您没有将任何参数传递给profile 视图。你定义的用户名应该是None,然后你说if not username然后post_owner应该是request.user

如何改变这个?好吧,只需在调用 redirect 作为关键字参数时传递所需的 username。如下:

return redirect('profile', username=friend.username)

【讨论】:

  • 嘿!您的代码使其工作,但是当用户添加朋友时,它会将其重定向到登录的用户个人资料,我可以添加一个朋友并将其保留在用户个人资料页面上而不将其重定向到登录的用户个人资料吗?
  • 我很高兴它成功了,我的朋友。如果您希望执行该操作但不更改当前页面,那么您应该考虑执行 AJAX 调用。另一方面,如果您不介意重新加载当前页面,那么您应该将user 对象作为参数传递给redirect() 函数。让我更新我的答案并告诉你如何做。
  • username=friend.username 返回无反向匹配错误,我也尝试了 user=friend.user 并返回相同的错误
  • 我还注意到,当任何用户添加朋友时,它会向所有用户添加朋友,删除朋友时也会发生同样的情况,抱歉这是我的第 4 个月编码
  • 关于 NoReverseMatch,很可能您在 urls.py 中没有为 profile 视图正确设置 path() 函数。请记住准备 URL 以接收参数。你应该有类似的东西:path('profile/&lt;username&gt;', view.profile, name='profile')
【解决方案2】:

在您看来,好友地址是已经添加的好友,您希望获得有资格添加为好友的用户到 request.user 对象。为此,

在您的个人资料视图中:

def profile(request, username=None):
    friend = Friend.objects.filter(current_user=request.user).first()
    friends = []
    # In case of friend is None, I send all users except request user, to be able to add on html template.
    friends_to_add = User.objects.exclude(id=request.user.id)
    if friend:   
        friends = friend.users.all()
        # here we have a valid friend (who is the user request has)
        # so I don't want to send users to template who are already friend of request user.
        friends_to_add = friends_to_add.exclude(id__in=friend.users.values_list("id"))
    if username:
        post_owner = get_object_or_404(User, username=username)
        user_posts=Post.objects.filter(user_id=post_owner)
    else:
        post_owner = request.user
        user_posts=Post.objects.filter(user=request.user)
    args1 = {
        'post_owner': post_owner,
        'user_posts': user_posts,
        'friends': friends,
        'friends_to_add': friends_to_add,
    }
    return render(request, 'profile.html', args1)

在您的模板文件中,您可以将它们用作:

<div class="media">
     <div class="media-body">
        <h2 class="account-heading">{{ post_owner.username }}</h2>
        <p class="text-secondary">{{ post_owner.email }}</p>
        {% for user in friends_to_add %}
            <a href="{% url 'change_friends' operation='add' pk=user.pk %}">
                <button type="button">add Friend</button>
            </a>
        {% endfor %}
    </div>
</div>

我希望这对你有意义。如果您需要,可以从 cmets 向我提出任何您无法理解的问题。

【讨论】:

  • 这是有道理的,但我想我并不清楚我想要什么,问题是代码在每个用户的个人资料页面中显示登录用户的朋友,目标是显示朋友就像在 facebook 中一样,来自他们个人资料页面中的选定用户。
  • 我的错,我现在明白了。您可以在 url 标签中传递user.pkpost_owner.pk
  • 你的意思是我可以使用{% url 'change_friends' operation='add' pk=user.pk %}{% url 'change_friends' operation='add' pk=post_owner.pk %}
  • 是的,您可以选择其中之一。如果您在添加_朋友时遇到另一个错误,请提供我可以更好地提供帮助的日志。
猜你喜欢
  • 2020-09-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-29
  • 2011-08-16
  • 2011-10-31
  • 2017-03-24
  • 1970-01-01
  • 2023-03-12
相关资源
最近更新 更多