kazuhira123
@kazuhira123

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Django TypeError: 'str' object is not a mappingに関して

解決したいこと

Djangoでのsnsっぽいデモアプリを開発中です。
ホームのページへアクセスする際に下記のエラーが発生してしまったので解決方法をお聞きしたいです。
(エラー表示を見るにレイアウト用テンプレートの記述が間違っているのかな?と思っています)

###開発環境

python 3.10.5
Django 3.0.4

発生している問題・エラー

下記の3つが確認できています。

TypeError at /sns/
Error during template rendering
'str' object is not a mapping

画面は下記のような状態です
スクリーンショット 2022-08-28 0.07.11.png

スクリーンショット 2022-08-28 0.07.53.png

該当するソースコード

urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('<int:page>', views.index, name='index'),
    path('groups', views.groups, name='groups'),
    path('add', views.add, name='add'),
    path('creategroup', views.creategroup, 'creategroup'),
    path('post', views.post, name='post'),
    path('share/<int:share_id>', views.share, name='share'),
    path('good/<int:good_id>', views.good, name='good'),
]
layout.html
{% load static %}
<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>{% block title %}{% endblock %}</title> <!--タイトル表示用のブロック生成-->
  <link rel="stylesheet"
  href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
    crossorigin="anonymous">
</head>
<body class="container">
  <nav class="navbar navbar-expand navbar-light bg-light"> <!--navタグでナビゲーションを表示-->
  <ul class="navbar-nav mr-auto">
    <li class="nav-item">
      <a class="nav-link" href="{% url 'index' %}">top</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="{% url 'post' %}">post</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="{% url 'groups' %}">group</a>
    </li>
  </ul>
  <span>logined: <span class="h6">"{{login_user}}".</span></span> <!--spanタグでインライン要素をグループ化-->
  </nav>

  <div>{% block header %} <!--ヘッダー情報表示用のブロック生成-->
    {% endblock %}</div>
  <div class="content">{% block content %} <!--ページのコンテンツ表示用のブロック生成-->
    {% endblock %}</div>

  <hr>
  <div class="my-3">
    <span class="font-weight-bold">
      <a href="/admin/logout?next=/sns/">
        [ logout ]</a></span>
    <span class="float-right">copyright 2022
      Izumi Kohei.</span>
  </div>
</body>
</html>
index.html
{% extends 'sns/layout.html' %} <!--sns/layout.htmlを継承する-->

{% block title %}Index{% endblock %} <!--継承元のtitleブロックの処理のままIndexが表示される-->

{% block header %}
<script>
function sendGroupForm(page) {
  document.group_form.action += page;
  document.group_form.submit();
}
</script> <!--scriptタグでjavascriptの記述を埋めこみ-->
<h1 class="display-4 text-primary">SNS</h1>
<p>※グループのチェックをONにしてupdateすると、
  そのグループに登録されている利用者のメッセージだけが表示されます</p>
{% if messages %} <!--システムメッセージがある場合の表示-->
<ul class="messages">
  {% for message in messages %}
  <li {% if message.tags %}
    class="{{message.tags}}"
    {% endif %}>{{message}}
  {% endfor %}
</ul>
{% endif %}
{% endblock %}

{% block content %}
<hr>
<div>
  <form action="{% url 'index' %}" method="post" name="group-form">
    {% csrf_token %}
    {{check_form}}
    <div>
      <button class="btn btn-primary">update</button>
    </div>
  </form>
</div>
<table class="table mt-3">
  <tr><th>Messages</th></tr>
{% for item in contents %}
  <tr><td>
  <p class="my-0">
    {% if item.group.title == 'public' %}
    <span class="bg-info text-light px-1">Public</span>
    {% endif %}
    {{item.content}}</p>
  <p class=""> ({{item.pub_date}})</p>
  {% if item.share_id > 0 %}
  <ul><li class="text-black-50">"{{item.get_share}}"</li></ul>
  {% endif %}
  <span class="float-left text-info">
    share={{item.share_count}} good={{item.good_count}}
  </span>
  <span class="float-right">
    "{{item.owner}}"(<a href="{% url 'add' %}?name={{item.owner}}">
      add friend</a>)
    <a href="{% url 'share' item.id %}">
      <button class="py-0">share</button></a>
      <a href="{% url 'good' item.id %}">
        <button class="py-0">good!</button></a>
      </span>
  </td></tr>
{% endfor %}
</table>

<ul class="pagination justify-content-center">
  {% if contents.has_previous %}
  <li class="page-item">
    <a class="page-link" href="javascript:sendGroupForm(1);">
      &laquo; first</a>
  </li>
  <li class="page-item">
    <a class="page-link"
    href="javascript:sendGroupForm({{contents.
      previous_page_number}});">
      &laquo; prev</a>
  </li>
  {% else %}
  <li class="page-item">
    <a class="page-link">&laquo; first</a>
  </li>
  <li class="page-item">
    <a class="page-link">&laquo; prev</a>
  </li>
  {% endif %}
  <li class="page-item">
    <a class="page-link">
      {{contents.number}}/{{contents.paginator.num_pages}}</a>
  </li>
  {% if contents.has_next %}
  <li class="page-item">
    <a class="page-link"
    href="javascript:sendGroupForm({{contents.next_page_number}});">
      next &raquo;</a>
  </li>
  <li class="page-item">
    <a class="page-link"
    href="javascript:sendGroupForm({{contents.paginator.
      num_pages}});">
      last &raquo;</a>
  </li>
  {% else %}
  <li class="page-item">
    <a class="page-link">next &raquo;</a>
  </li>
  {% endif %}
</ul>
{% endblock %}
views.py
#外部のメソッドとクラスのimport
import re
from sqlite3 import paramstyle
from sre_constants import GROUPREF
from tkinter.messagebox import NO
from tokenize import group
from turtle import fd, pu, title
from django import shortcuts
from django.shortcuts import render
from django.shortcuts import redirect
from django.contrib.auth.models import User #ユーザー認証機能をimport
from django.contrib import messages
from django.core.paginator import Paginator
from django.db.models import Q
from django.contrib.auth.decorators import login_required #ログイン用の機能をimport

#snsアプリケーション内のクラスのimport
from .models import Message,Friend,Group,Good
from .forms import GroupCheckForm,GroupSelectForm,FriendsForm,CreateGroupForm,PostForm

#indexのビュー関数
@login_required(login_url='admin/login/') #/admin/login/へのログインが必須となるアノテーションを設定
def index(request, page=1):
  #publicのuserを取得
  (public_user, public_group) = get_public()

  #POST送信時の処理
  if request.method == 'POST':
    #Groupsのチェックを更新した時の処理
    #フォームの用意
    checkform = GroupCheckForm(request.user, request.POST) #アクセス時のユーザーとチェックボックスの選択状態を引数にしてGroupCheckFormのインスタンスを生成
    #チェックされたGroup名をリストにまとめる
    glist = []
    for item in request.POST.getlist('groups'): #チェックされたgroupsモデルのデータを代入する繰り返し処理
      glist.append(item) #代入されたgroupsのデータをリストへ追加
    #Messageの取得
    messages = get_your_group_message(request.user, glist, page) #アクセス時のユーザー、チェックされたgroupsのデータ、ページ数を引数にget_your_group_messageメソッドをmessagesに代入

  #GETアクセス時の処理
  else:
    #フォームの用意
    checkform = GroupCheckForm(request.user)  #アクセス時のユーザー情報を元にGroupCheckFormのインスタンスを生成
    #Groupのリストを取得
    gps = Group.objects.filter(owner=request.user) #Groupモデルの中から、利用者がアクセス時のユーザーのデータを検索する
    glist = [public_group.title] #publicのGroupが設定されたデータをglistに代入
    for item in gps:
      glist.append(item.title) #Groupの中で検索されたデータのタイトルを繰り返しglistに追加
    #メッセージの取得
    messages = get_your_group_message(request.user, glist, page)
  
  #共通処理
  params = {
    'login_user':request.user, #現在アクセスしているユーザーがログイン時のユーザーとして保管
    'contents':messages,
    'check_form':checkform,
  }
  return render(request, 'sns/index.html', params)

@login_required(login_url='/admin/login/')
def groups(request):
  #自分が登録したFriendを取得
  friends = Friend.objects.filter(owner=request.user) #Friendモデルの中からアクセス時のユーザーと利用者が一致するレコードを検索してfriendsに代入

  #POST送信時の処理
  if request.method == 'POST':

    #Groupメニュー選択肢の処理
    if request.POST['mode'] == '__groups_form__':
      #選択したGroup名を取得
      sel_group = request.POST['groups'] #選択されたgroupsの情報をsel_groupに代入
      #Groupを取得
      gp = Group.objects.filter(owner=request.user).filter(title=sel_group).first() #利用者がアクセス時のユーザーかつメニューで選択されたgroupを検索し最初のものをgpに代入
      #Groupに含まれるFriendを取得
      fds = Friend.objects.filter(owener=request.user).filter(group=gp) #利用者がアクセス時のユーザーかつ、選択されたgroupと一致するFriendモデルのレコードを検索しfdsに代入
      print(Friend.objects.filter(owner=request.user)) #利用者がアクセス時のユーザーのFriendモデルのレコードを出力
      #FriendのUserをリストにまとめる
      vlist = []
      for item in fds:
        vlist.append(item.user.username) #上記で検索したFriendモデルのレコードのユーザー名をリストに追加
      #フォームの用意
      groupsform = GroupSelectForm(request.user, request.POST) #indexと同じ処理
      friendsform = FriendsForm(request.user, friends=friends, vals=vlist) #アクセス時のユーザーとFriendモデルのリスト、選択されたFriendを表示するリストの中身を引数にしてFriendsFormインスタンス生成
    
    #Frinedsのチェック更新時の処理
    if request.POST['mode'] == '__friends_form__':
      #選択したGroupの取得
      sel_group = request.POST['group'] #選択されたgroupの値をsel_groupに代入
      group_obj = Group.objects.filter(title=sel_group).first() #Groupモデルの中から選択されたグループと一致する一番最初のレコードを検索
      print(group_obj) #検索したレコードを表示
      #チェックしたFriendsを取得
      sel_fds = request.POST.getlist('friends') #送信されたfirendsの値をリスト化して取得
      #FriendsのUserを取得
      sel_users = User.objects.filter(username__in=sel_fds) #User内のユーザー名が上記で取得したfriendsのリストに含まれているかを検索
      #Userのリストに含まれるユーザーが登録したFriendを取得
      fds = Friend.objects.filter(owner=request.user).filter(user__in=sel_users) #上記で検索したUserを元にFriendモデルを検索
      #全てのFriendにGroupを設定し保存する
      vlist = []
      for item in fds: #取得したFriendsモデルを元に繰り返し処理を実行
        item.group = group_obj #Friendのgroupに選択されたgroupを代入
        item.save() #上記のレコードの保存
        vlist.append(item.user.username) #リスト選択したFriendsモデルのユーザー名を追加
      #メッセージを設定
      messages.success(request, 'チェックされたFriendを' + sel_group + 'に登録しました') #メッセージフレームワークでシステムメッセージを表示
      #フォームの用意
      groupsform = GroupSelectForm(request.user, {'groups':sel_group})
      friendsform = FriendsForm(request.user, friends=friends, vals=vlist)
    
    #GETアクセス時の処理
    else:
      #フォームの用意
      groupsform = GroupSelectForm(request.user) #アクセス時のユーザーを元にグループ選択用のインスタンスを生成
      friendsform = FriendsForm(request.user, friends=friends, vals=[]) #アクセス時のユーザーとFriendモデルのリスト、選択されたFriendを表示するリストの中身を空にしてfriendsformに代入
      sel_group = '-' #GETアクセス時なのでgroupの選択がないことを表示
    
    #共通処理
    createform = CreateGroupForm() #グループ作成用のインスタンスを生成
    params = {
      'login_user':request.user,
      'gourps_form':groupsform,
      'friends_form':friendsform,
      'create_form':createform,
      'group':sel_group,
    }
    return render(request, 'sns/groups.html', params)

#Friendの追加処理
@login_required(login_url='/admin/login/')
def add(request):
  #追加するUserを取得
  add_name = request.GET['name'] #Friend登録するユーザーの名前をadd_nameに代入
  add_user = User.objects.filter(username=add_name).first() #上記で代入した値とUserのユーザー名が最初に一致するものを取得
  #Userが本人だった場合の処理
  if add_user == request.user:
    messages.info(request, "自分自身をFriendに追加することはできません")
    return redirect(to='/sns')
  #publicの取得
  (public_user, public_group) = get_public()
  #add_userのFriendの数を調べる
  frd_num = Friend.objects.filter(owner=request.user).filter(user=add_user).count()
  #0より大きければ既に登録済み
  if frd_num > 0:
    messages.info(request, add_user.username + 'は既に追加されています')
    return redirect(to='/sns')
  
  #ここからFriendの登録処理
  frd = Friend() #Friendモデルのインスタンスを生成してfrdに代入
  frd.owner = request.user #登録者をアクセス時のユーザーに設定
  frd.user = add_user #登録するユーザーをadd_userに設定
  frd.group = public_group #Friendモデルのgroup情報をpublicグループに設定
  frd.save() #上記内容を保存
  #メッセージを設定
  messages.success(request, add_user.username + 'を追加しました! groupページに移動して、追加したFriendをメンバーに設定してください')
  return redirect(to='/sns') #snsアプリケーションのホームへリダイレクト

#グループの作成処理
@login_required(login_url='/admin/login/')
def creategroup(request):
  #Groupを作り、Userとtitleを設定して保存する
  gp = Group()
  gp.owner = request.user
  gp.title = request.user.username + 'の' + request.POST['group_name'] #グループのタイトルを「[グループ作成者]の[グループ名]」の形で表示
  gp.save()
  messages.info(request, '新しいグループを作成しました')
  return redirect(to='/sns/groups')

#メッセージのポスト処理
@login_required(login_url='/admin/login/')
def post(request):
  #POST送信時の処理
  if request.method == 'POST':
    #送信内容の取得
    gr_name = request.POST['groups'] #投稿されたgroupsの値をgr_nameに代入
    content = request.POST['content'] #投稿されたcontentの値をcontentに代入
    #Groupの取得
    group = Group.objects.filter(owner=request.user).filter(title=gr_name).first() #Groupモデル内の投稿グループと位置する情報を取得
    if group == None: #投稿されたgroupが存在しない時の処理
      (pub_user, group) = get_public() #publicのgroupを取り出す
    #Messageを作成し設定して保存
    msg = Message() #Messageインスタンスを生成してmsgに代入
    msg.owner = request.user #投稿者はアクセス時のユーザー
    msg.group = group #groupは投稿時のgroup
    msg.content = content #投稿した内容は投稿時のcontent
    msg.save() #上記を保存
    #メッセージを設定
    messages.success(request, '新しいメッセージを投稿しました!')
    return redirect(to='/sns')
  
  #GETアクセス時の処理
  else:
    form = PostForm(request.user)

  #共通処理
  params = {
    'login_user':request.user,
    'form':form,
  }
  return render(request, 'sns/post.html', params)

#投稿をシェアする
@login_required(login_url='/admin/login/')
def share(request, share_id):
  #シェアするMessageの取得
  share = Message.objects.get(id=share_id)
  print(share)
  #POST送信時の処理
  if request.method == 'POST':
    #送信内容を取得
    gr_name = request.POST['groups']
    content = request.POST['content']
    #Groupの取得
    group = Group.objects.filter(owner=request.user).filter(title=gr_name).first()
    if group == None:
      (pub_user, group) = get_public()
    #メッセージを作成し、設定し保存
    msg = Message()
    msg.owner = request.user
    msg.group = group
    msg.content = content
    msg.share_id = share_id
    msg.save()
    share_msg = msg.get_share()
    share_msg.share_count += 1
    share_msg.save()
    #メッセージを設定
    messages.success(request, 'メッセージをシェアしました!')
    return redirect(to='/sns')
  
  #共通処理
  form = PostForm(request.user)
  params = {
    'login_user':request.user,
    'form':form,
    'share':share,
  }
  return render(request, 'sns/share.html', params)

#goodボタンの処理
@login_required(login_url='/admin/login/')
def good (request, good_id):
  #goodするMessageを取得
  good_msg = Message.objects.get(id=good_id) #goodした時のidとMessageモデルのidが一致するものを取得
  #自分がメッセージにgoodした数を調べる
  is_good = Good.objects.filter(owner=request.user).filter(message=good_msg).count()
  #0より大きければ既にgood済み
  if is_good > 0:
    messages.success(request, '既にメッセージにはgoodしています')
    return redirect(to='/sns')
  
  #Messageのgood_countを1増やす
  good_msg.good_count += 1
  good_msg.save()
  #Goodを作成し、設定し保存する
  good = Good()
  good.owner = request.user
  good.message = good_msg
  good.save()
  #メッセージを設定
  messages.success(request, 'メッセージにgoodしました!')
  return redirect(to='/sns')

#これ以降は普通の関数===========================

#指定されたグループおよび検索文字によるMessageの取得
def get_your_group_message(owner, glist, page):
  page_num = 10 #ページあたりの表示数
  #publicの取得
  (public_user, public_group) = get_public()
  #チェックされたGroupの取得
  groups = Group.objects.filter(Q(owner=owner)|Q(owner=public_user)).filter(title__in=glist)
  #Groupに含まれるFriendの取得
  me_friends = Friend.objects.filter(group__in=groups)
  #FriendのUserをリストにまとめる
  me_users = []
  for f in me_friends:
    me_users.append(f.user)
  #UserリストのUserが作ったGroupの取得
  his_groups = Group.objects.filter(owner__in=me_users)
  his_friends = Friend.objects.filter(user=owner).filter(group__in=his_groups)
  me_groups = []
  for hf in his_friends:
    me_groups.append(hf.group)
  #groupがgroupsに含まれるか、me_groupsに含まれるMessageの取得
  messages = Message.objects.filter(Q(group__in=groups)|Q(group__in=me_groups))
  #ページネーションで指定ページを取得
  page_item = Paginator(messages, page_num)
  return page_item.get_page(page)

#publicなUserとGroupを取得する
def get_public():
  public_user = User.objects.filter(username='public').first() #User内のユーザー名がpublicのものを取得
  public_group = Group.objects.filter(owner=public_user).first() #Groupモデル内の作成者がpublicとなっているものを取得
  return (public_user, public_group)

自分で試したこと

特にありません。
ネット上で同様のエラーが発生したケースを複数確認できましたが、urls.pyのpath内のキーワードにname引数を追加する旨のアドバイスしかなく、解決の目処が立たなかったため質問させていただきました。
長文になり申し訳ありません。
内容に不備や不足あればご指摘いただけると幸いです。
よろしくお願いします。

0

4Answer

このような使い方をしたことが無いので分からないのですが、urls.pyに name='index'が2つあるのは問題ないのでしょうか?

2Like

Comments

  1. @kazuhira123

    Questioner

    回答いただきありがとうございます!
    仰る通りindexが2つあるのは違和感ありますね・・・
    ただ、学習に使っている書籍のコードを写経しただけなので正しいか分からず、申し訳ございません。

    なお、name='index'を片方削除した上でアクセスしても再度エラーとなってしましました。
    よろしくお願いいたします。

コードをしっかり見れてないので、作ってらっしゃるアプリについて上手くつかめてないのですが、

例えばですが、よくあるSNSだと

urls.py
# ログインなしでも見れるトップページ
path('', views.index, name='index'),
# 自分専用のページ
path('dashboard', views.dashboard, name='dashboard'),
# 他のユーザーのページ
path('<slug>', views.userprofile, name='userprofile'),

のように、urlが分けられていて

views.py
# ログインなしでも見れるページ
def index(request):
    〜〜
    return render(request, 'sns/index.html', params)

# 自分だけのダッシュボード
@login_required
def dashboardrequest):
    user = request.user
    〜〜
    return render(request, 'sns/dashboard.html', params)

# 他のユーザーのプロフィールページ
@login_required任意
def userprofilerequest, slug):
    user = User.object.get(slug=slug)
    〜〜
    return render(request, 'sns/userprofile.html', params)
userprofile.html
(userprofileのviewから)

ユーザーのslugを取得できる(modelsで設定が必要)
{{ user.slug }} 

example.com/slugのURLが取得できる
{% url 'sns:userprofile' user.slug %}

となり、user.slugの部分でviewに値を渡してあげます。

今回の場合、多分ですが、pageの値(slug)がviewに渡せていないのが原因じゃないかなと感じました。(indexも2つあったのも原因の一つ?)

既にindexは1つになったようなので、あとは

<form action="{% url '????' %}" method="post" name="group-form">

{% url 'sns:????' %}で値を渡してあげれば良いのかなと。

{% url 'sns:????' gps.page %}みたいな感じですかね?

回答してて違和感があるので、動かないかもしれませんが、何か気づくきっかけになれば幸いです。

1Like

Comments

  1. @kazuhira123

    Questioner

    改めて回答ありがとうございます!
    ご指摘いただいた通り、`urls.py`と`index.html`を修正しましたが、エラー解消されませんでした。
    (修正した内容は下記に投稿させていただきますので、もしお時間ありましたら不備がないか確認いただけると幸いです)

    ちなみに1点確認したいのですが、`{% url 'sns:????' gps.page %}`とありますが、テンプレートタグにurlを記述際は
    `{% url 'アプリケーション名:name引数の値' %}`
    という形になるという理解でよろしいでしょうか。

    せっかく何度もご回答いただいているにも関わらず、私の理解が及ばず申し訳ないです。。。
    今後ともよろしくおねがいします。
  2. 何かを保存する場合は、どこに保存するかIdやpkなどで指定してあげる必要があります。

    {% url 'アプリケーション名:name引数の値' %}
    はちょっと違って
    {% url 'アプリケーション名:name' 引数の値 %}
    で、「''」の外に書きます。

    そして思ったのですが、viewの「page=1」というのは静的なものなのでしょうか?
    1が変わらないのであれば、関数内で処理しても良い気も?

    あと、urls.py
    app_name = "sns"
    が無いのも気になるところです。

    app_name = "sns" # 追加
    urlpatterns = [
    path('', views.index, name='index'),

    https://docs.djangoproject.com/ja/4.1/intro/tutorial03/#namespacing-url-names
  3. 【追記】
    >urlを記述の際は〜

    {% url 'アプリケーション名:name' 引数の値 %}

    の方法と、modelに、get_absolute_url()のメソッドを書いてあげる方法があります。

    get_absolute_url()を使った場合は、テンプレート側に{{ hoge.get_absolute_url }}と書けば出力できます。
  4. @kazuhira123

    Questioner

    再度回答いただきありがとうございます!

    テンプレートタグのurlの記述方法、ご教授いただきありがとうございます。
    get_absolute_url()メソッドを使用した記述方法は、別の機会に試してみたいと思います。

    >viewsの「page=1」に関して
    恥ずかしながら書籍のサンプルを写経しただけなので、静的なものかは私自身分かっておりません。。。。。。

    また、"静的なもの"というのは「あらかじめ定義されていて、実行時に変化しないもの」という認識なのですが、合っているでしょうか。(間違っていたら申し訳ございません)

    >urls.pyのapp_nameに関して
    こちら知りませんでした。教えてくださりありがとうございます。
    公式ドキュメントのリンクも送付してくださり助かります。

    なお、テンプレートタグのurlの記述の修正とapp_nameの追記しましたが、依然エラーのままでした。
    今後ともよろしくお願いいたします。

ソースがネット上にないか探してみたらあったので私も作ってみました。

結果、別のエラーは出ましたが、投稿されているコードは多分問題ないような感じがしました。

(kazuhira123さんのコードにはスペルミスなどがいくつかありましたが)

なので、ここに投稿されていない部分のコードに問題があるかもしれません。
url関係だとは思うのですがわかりません。。。

色々メモされていて、メカニズム等は既に理解していると思うので、こちらのページのコードをコピペして、完成品をみた上で次に進むのが良いかと思います。

ちなみに何の書籍を見て学習されているのか教えて頂けますでしょうか?

1Like

Comments

  1. @kazuhira123

    Questioner

    ありがとうございます!
    私以上に色々と調べていただき申し訳ないです。。。

    学習に使用している書籍は「Python Django3超入門」です。
    リンクは別途送付致します。

    また、Qiita記事もありがとうございます!
    今日は時間取れそうにないので、明日以降確認させていただきたいと思います。
    (スペルミスもあるそうなので、改めて自分自身で書いたコードのチェックしたいと思います)

    改めてご対応いただきありがとうございます!
    今後ともよろしくお願いします。
  2. @kazuhira123

    Questioner

    何度も連投申し訳ないです。
    なんだかんだ気になってしまったのでコード確認してみまして、、、
    上記Qiita記事をもとにコード修正したところエラー解消しました!!!!!!!

    正直色々なところを修正しすぎてどこが原因かいまいち理解できていないのですが、おそらくindex関数のアノテーションのアドレスのスペルミスが原因だったのではないかと思われます。
    元々は'admin/index/'でしたが、正しくは'/admin/index/'でした
    (その他の修正も改行位置やフォームやモデルのスペルミス程度だったのでこれが原因かな〜と思っています)

    細かい原因究明は後ほど時間を取りたいとおもいます。
    改めて色々とご教授いただきありがとうございます!

    今後ともよろしくお願いします!
  3. 解決できてよかったです!

    そして書籍の情報ありがとう御座います。
    以前読んだことのある本でしたが、SNS作成は飛ばして読んでいたようですw

    書籍の内容を書き写すのも勉強になるのですが、自身で1からコーディングすると更に学習効率が上がると思います。(ミスなどもコーディングしてる時にすぐわかるので)

    例えばTwitterのコピーを作ってみるとか、自身の仕事・趣味・生活に関わるものを作ってみるとか。

    あと私の主観ですが、Djangoの公式チュートリアル(投票アプリ)は非常に良くできているなと思ったので、こちらもオススメです。

    Djangoは深くまでいくと難しく感じるのですが、一般的なアプリケーションであればポンポン作れるのでこれからも楽しんでアプリ作っていきましょう(^o^)
  4. @kazuhira123

    Questioner

    やはり書籍の学習だけではだめですね・・・
    個人的に作りたい!と思っているものが沢山あるので、学習中の書籍をやり切ったらアプリの作成に移りたいと思います。

    また、チュートリアルの情報ありがとうございます!
    学習に詰まったら挑戦してみたいと思います。

    改めて数日にわたり色々とご教授くださりありがとうざいました。
    アプリ作り楽しみたいとおもいます!
    今後ともよろしくお願いします!!!!

@NOIZE さんのアドバイスを受け、下記のように修正いたしました。

urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('groups', views.groups, name='groups'),
    path('add', views.add, name='add'),
    path('creategroup', views.creategroup, 'creategroup'),
    path('post', views.post, name='post'),
    path('share/<int:share_id>', views.share, name='share'),
    path('good/<int:good_id>', views.good, name='good'),
]
index.html
{% extends 'sns/layout.html' %} <!--sns/layout.htmlを継承する-->

{% block title %}Index{% endblock %} <!--継承元のtitleブロックの処理のままIndexが表示される-->

{% block header %}
<script>
function sendGroupForm(page) {
  document.group_form.action += page;
  document.group_form.submit();
}
</script> <!--scriptタグでjavascriptの記述を埋めこみ-->
<h1 class="display-4 text-primary">SNS</h1>
<p>※グループのチェックをONにしてupdateすると、
  そのグループに登録されている利用者のメッセージだけが表示されます</p>
{% if messages %} <!--システムメッセージがある場合の表示-->
<ul class="messages">
  {% for message in messages %}
  <li {% if message.tags %}
    class="{{message.tags}}"
    {% endif %}>{{message}}
  {% endfor %}
</ul>
{% endif %}
{% endblock %}

{% block content %}
<hr>
<div>
  <form action="{% url 'sns:index' %}" method="post" name="group-form">
    {% csrf_token %}
    {{check_form}}
    <div>
      <button class="btn btn-primary">update</button>
    </div>
  </form>
</div>
<table class="table mt-3">
  <tr><th>Messages</th></tr>
{% for item in contents %}
  <tr><td>
  <p class="my-0">
    {% if item.group.title == 'public' %}
    <span class="bg-info text-light px-1">Public</span>
    {% endif %}
    {{item.content}}</p>
  <p class=""> ({{item.pub_date}})</p>
  {% if item.share_id > 0 %}
  <ul><li class="text-black-50">"{{item.get_share}}"</li></ul>
  {% endif %}
  <span class="float-left text-info">
    share={{item.share_count}} good={{item.good_count}}
  </span>
  <span class="float-right">
    "{{item.owner}}"(<a href="{% url 'add' %}?name={{item.owner}}">
      add friend</a>)
    <a href="{% url 'share' item.id %}">
      <button class="py-0">share</button></a>
      <a href="{% url 'good' item.id %}">
        <button class="py-0">good!</button></a>
      </span>
  </td></tr>
{% endfor %}
</table>

<ul class="pagination justify-content-center">
  {% if contents.has_previous %}
  <li class="page-item">
    <a class="page-link" href="javascript:sendGroupForm(1);">
      &laquo; first</a>
  </li>
  <li class="page-item">
    <a class="page-link"
    href="javascript:sendGroupForm({{contents.
      previous_page_number}});">
      &laquo; prev</a>
  </li>
  {% else %}
  <li class="page-item">
    <a class="page-link">&laquo; first</a>
  </li>
  <li class="page-item">
    <a class="page-link">&laquo; prev</a>
  </li>
  {% endif %}
  <li class="page-item">
    <a class="page-link">
      {{contents.number}}/{{contents.paginator.num_pages}}</a>
  </li>
  {% if contents.has_next %}
  <li class="page-item">
    <a class="page-link"
    href="javascript:sendGroupForm({{contents.next_page_number}});">
      next &raquo;</a>
  </li>
  <li class="page-item">
    <a class="page-link"
    href="javascript:sendGroupForm({{contents.paginator.
      num_pages}});">
      last &raquo;</a>
  </li>
  {% else %}
  <li class="page-item">
    <a class="page-link">next &raquo;</a>
  </li>
  {% endif %}
</ul>
{% endblock %}
layout.html
{% load static %}
<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>{% block title %}{% endblock %}</title> <!--タイトル表示用のブロック生成-->
  <link rel="stylesheet"
  href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
    crossorigin="anonymous">
</head>
<body class="container">
  <nav class="navbar navbar-expand navbar-light bg-light"> <!--navタグでナビゲーションを表示-->
  <ul class="navbar-nav mr-auto">
    <li class="nav-item">
      <a class="nav-link" href="{% url 'sns:index' %}">top</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="{% url 'sns:post' %}">post</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="{% url 'sns:groups' %}">group</a>
    </li>
  </ul>
  <span>logined: <span class="h6">"{{login_user}}".</span></span> <!--spanタグでインライン要素をグループ化-->
  </nav>

  <div>{% block header %} <!--ヘッダー情報表示用のブロック生成-->
    {% endblock %}</div>
  <div class="content">{% block content %} <!--ページのコンテンツ表示用のブロック生成-->
    {% endblock %}</div>

  <hr>
  <div class="my-3">
    <span class="font-weight-bold">
      <a href="/admin/logout?next=/sns/">
        [ logout ]</a></span>
    <span class="float-right">copyright 2022
      Izumi Kohei.</span>
  </div>
</body>
</html>

以上です。
よろしくお願いします。

0Like

Your answer might help someone💌