質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

1回答

660閲覧

【Django】いいね機能にログインユーザー制限をかけたいのにうまくいきません。

nre

総合スコア35

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2020/10/23 07:15

編集2020/10/24 11:35

前提・実現したいこと

現在django2を使用してwebアプリケーションを開発しております。
そのアプリには会員登録機能とログイン機能が備わっております。
そしてログインしたユーザーのみが詳細ページ内の「いいね」を押せる様に制限をかけたいです。

仕様としては
誰でも閲覧可能な詳細ページにアクセスし、
そこで現在ログインしているユーザーであれば通常通り「いいね」を押せる。
ログインしていないユーザーはログインページにリダイレクトされる。

発生している問題・エラーメッセージ

ログインしていないユーザーが「いいね」を押すと、無反応です。
「いいね」数もカウントされないし(これは問題無し)、リダイレクトもされない状態です。

該当のソースコード

django

1#views.py 2"""ライブラリ読み込み""" 3from django.shortcuts import render 4 5 6class DetailView(generic.DetailView): 7 """詳細ページはクラスビューで表示""" 8 model = User 9 template_name = 'register/detail.html' 10 11 12def like(request, pk): 13 """いいね機能""" 14 try: 15 user = User.objects.get(pk=pk) 16 except User.DoesNotExist: 17 raise Http404 18 user.like += 1 19 user.save() 20 return redirect('register:detail', pk=pk) 21 22 23def api_like(request, pk): 24 """いいね後ページをロードさせない""" 25 if not request.user.is_authenticated: 26 return render(request, 'register/login.html') #ログインページにリダイレクトさせる 27 try: 28 user = User.objects.get(pk=pk) 29 except User.DoesNotExist: 30 raise Http404 31 user.like += 1 32 33 return JsonResponse({"like":user.like})

django

1#urls.py 2 3urlpatterns = [ 4 path('', views.TopView.as_view(), name='top'), 5 path('<int:pk>/', views.DetailView.as_view(), name='detail'), #詳細ページのパス 6 path("<int:pk>/like/", views.like, name="like"), 7 path("api/like/<int:pk>/", views.api_like, name="api_like"), 8]

django

1#models.py 2 3class User(AbstractBaseUser, PermissionsMixin): 4 """カスタムユーザーモデル.""" 5 6 email = models.EmailField(_('email address'), unique=True) 7 first_name = models.CharField(_('first name'), max_length=30, blank=True) 8 last_name = models.CharField(_('last name'), max_length=150, blank=True) 9 like = models.IntegerField(default=0) 10 """省略."""

django

1#settings.py 2LOGIN_URL = 'register:login' 3LOGIN_REDIRECT_URL = 'register:top'

django

1#detail.html 2"""詳細ページ内のいいねボタン部分""" 3<div class="Likes"> 4<a onclick="api_like()" class="Likes-Icon"></a> 5</div> 6<script> 7 function api_like() { 8 var api_url = "{% url 'register:api_like' user.pk %}"; 9 var btn_txt = document.getElementById("like"); 10 var request = new XMLHttpRequest(); 11 request.onreadystatechange = function () { 12 if (request.readyState === 4 && request.status === 200) { 13 var received_data = JSON.parse(request.responseText); 14 btn_txt.innerText = received_data.like; 15 } 16 } 17 request.open("GET",api_url); 18 request.send(); 19 } 20</script>

試したこと

djangoのドキュメントを参考に試してみましたが同じ結果となりました。

django

1from django.contrib.auth.decorators import login_required 2 3@login_required 4def api_like(request, pk): 5 ... 67 8from django.contrib.auth.decorators import login_required 9 10@login_required(login_url='/accounts/login/') 11def api_like(request, pk): 12 ...

補足情報(FW/ツールのバージョンなど)

処理のログをよく観てみるとこちらが表示されております。このリンクのせいで正しいリダイレクト先が呼び出せないのでしょうか?

django

1[23/Oct/2020 19:21:19] "GET /login/?next=/api/like/12/ HTTP/1.1" 200 6225 2

下記が参考にしたものです。
django公式ドキュメント
いいね機能はこちらのサイトにあるコードカスタマイズしました。
会員登録機能はこちらを参考にしました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

urls.pyにapi_like()へのURL定義がないので、javascriptから呼び出せてないのではないでしょうか?

javascriptのエラーも確認してみてください。

追記, 2020.10.27

jsのXMLHttpRequest.responseURLを参照がわからなかったため、

具体例をあげたほうがよかったですね。
XMLHttpRequestインスタンスから参照できます。

提示のソースですと、以下のようにresponseURLが参照できます。(locationへ代入)
locationのURLがログイン画面のURLであれば、リダイレクトが発生したと判断してもいいかと思います。

javascript

1<script> 2 function api_like() { 3 var api_url = "{% url 'register:api_like' user.pk %}"; 4 var btn_txt = document.getElementById("like"); 5 var request = new XMLHttpRequest(); 6 request.onreadystatechange = function () { 7 if (request.readyState === 4 && request.status === 200) { 8 9 // ----- add start ----- 10 let location = request.responseURL; 11 console.log(location); 12 // ----- add end ----- 13 14 var received_data = JSON.parse(request.responseText); 15 btn_txt.innerText = received_data.like; 16 } 17 } 18 request.open("GET",api_url); 19 request.send(); 20 } 21</script>

投稿2020/10/23 09:53

編集2020/10/27 06:06
takyafumin

総合スコア2335

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nre

2020/10/23 10:10

大変お忙しい中、ご返信してくださり誠にありがとうございます。 一応api_like()へのURU定義となるのはこちらだと考えているのですが、 path("api/like/<int:pk>/", views.api_like, name="api_like"), 記述もれでした。大変申し訳ございません。
takyafumin

2020/10/26 00:39

XmlHttpRequestは、リダイレクトが発生したときに自動的にリダイレクト先のレスポンスを返すようです。 ですのでjavascriptのapi_like()内で、XMLHttpRequest.responseURLを参照しログインURLであれば画面遷移するよう実装するのはいかがでしょうか?
nre

2020/10/26 09:13

大変お忙しい中、ご回答して頂き誠にありがとうございます。 早速、挑戦してみたのですが、 jsのXMLHttpRequest.responseURLを参照がわからなかったため、 仕様を変更することにいたしました。 ご回答して頂いたのにも関わらず大変申し訳ございません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問