[Django]フォロー機能と課題、そして解決へ!
フォロー・フォロワー機能を実装しようとしたのだが、うまくいかなかった。しかし、このブログをみてくださった心優しい方がDMで解決策を教えてくれました。
参考:GitHub - benigls/instagram: Instagram clone made with Django framework.
前回
jyouj.hatenablog.com
フォロー・アンフォロー
まず、models.pyについて。
@python_2_unicode_compatible class Connection(models.Model): follower = models.ForeignKey(User, related_name='follower', on_delete=models.CASCADE) following = models.ForeignKey(User, related_name='following', on_delete=models.CASCADE) date_created = models.DateTimeField(auto_now_add=True) def __str__(self): return "{} : {}".format(self.follower.username, self.following.username)
次に、views.py。
from __future__ import absolute_import from django.contrib.auth.decorators import login_required from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login, logout, update_session_auth_hash from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic import CreateView, TemplateView, DetailView, UpdateView, ListView from django.urls import reverse_lazy from django.contrib import messages from django.http import HttpResponseRedirect, Http404 from .models import User, Connection from .forms import SignUpForm, LoginForm, ProfileEditForm from .helpers import get_current_user class ProfileDetailView(LoginRequiredMixin, DetailView): model = User template_name = 'users/profile.html' slug_field = 'username' slug_url_kwarg = 'username' def get_context_data(self, **kwargs): context = super(ProfileDetailView, self).get_context_data(**kwargs) username = self.kwargs['username'] context['username'] = username context['user'] = get_current_user(self.request) context['following'] = Connection.objects.filter(follower__username=username).count() context['followers'] = Connection.objects.filter(following__username=username).count() if username is not context['user'].username: result = Connection.objects.filter(follower__username=context['user'].username).filter(following__username=username) context['connected'] = True if result else False return context @login_required def follow_view(request, *args, **kwargs): try: follower = User.objects.get(username=request.user) following = User.objects.get(username=kwargs['username']) except User.DoesNotExist: messages.warning(request, '{}は存在しません'.format(kwargs['username'])) return HttpResponseRedirect(reverse_lazy('users:index')) if follower == following: messages.warning(request, '自分自身はフォローできませんよ') else: _, created = Connection.objects.get_or_create(follower=follower, following=following) if (created): messages.success(request, '{}をフォローしました'.format(following.username)) else: messages.warning(request, 'あなたはすでに{}をフォローしています'.format(following.username)) return HttpResponseRedirect(reverse_lazy('users:profile', kwargs={'username': following.username})) @login_required def unfollow_view(request, *args, **kwargs): try: follower = User.objects.get(username=request.user) following = User.objects.get(username=kwargs['username']) if follower == following: messages.warning(request, '自分自身のフォローを外せません') else: unfollow = Connection.objects.get(follower=follower, following=following) unfollow.delete() messages.success(request, 'あなたは{}のフォローを外しました'.format(following.username)) except User.DoesNotExist: messages.warning(request, '{}は存在しません'.format(kwargs['username'])) return HttpResponseRedirect(reverse_lazy('users:index')) except Connection.DoesNotExist: messages.warning(request, 'あなたは{0}をフォローしませんでした'.format(following.username)) return HttpResponseRedirect(reverse_lazy('users:profile', kwargs={'username': following.username}))
そして、urls.py。
urlpatterns = [ path('signup', views.SignUpView.as_view(), name='signup'), path('login', views.LoginView.as_view(), name='login'), path('', views.IndexView.as_view(), name='index'), path('logout', views.LogoutView.as_view(), name='logout'), path('<slug:username>', views.ProfileDetailView.as_view(), name='profile'), path('<slug:username>/edit', views.ProfileUpdateView.as_view(), name='edit'), path('<slug:username>/follow', views.follow_view, name='follow'), path('<slug:username>/unfollow', views.unfollow_view, name='unfollow'), ]
templates/users/profile.htmlも編集。
{% extends 'base.html' %} {% block body %} <h1>@{{ username }}</h1> <h3>{{ object.name }}</h3> <h6>{{ object.about_me }}</h6> {% if user.username == username %} <a href="{% url 'users:edit' username %}" class="btn btn-info">プロフィール編集</a> {% elif connected %} <a href="{% url 'users:unfollow' username %}" class="btn btn-dark">フォロー解除</a> {% else %} <a href="{% url 'users:follow' username %}" class="btn btn-light">フォロー</a> {% endif %} {% endblock %}
課題
実際にいくつかユーザーを作成して、フォローしようとすると、「<ユーザー名>は存在しません」というUser.DoesNotExistが出てしまう。
解決策
提示してもらった解決策を試してみました。まず、shellを起動してUserが存在するか確かめてみました。
>>>from users.models import User >>>User.objects.all()
すると、作成したtestユーザーが出てきました。コードのどこかにミスがあるな、と考えられます。
またまた、提示してもらった方法を試してみることにしました。views.pyを編集します。
def follow_view(request, *args, **kwargs): try: follower = User.objects.get(username=request.user.username) # 変更 # 省略 def unfollow_view(request, *args, **kwargs): try: follower = User.objects.get(username=request.user.username) # 変更 # 省略
すると、思ったように動くことができました。気づかなかったとは、、、。解決策を提示していただきありがとうございました。
何かありましたら以下に。
Twitterアカウント:じぇい👨💻 (@jyouj__) | Twitter
投げ銭も待ってまーす!-> jyouj__さんの投げ銭ビスケット募集中!