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

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

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

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

Python 3.x

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

Q&A

解決済

1回答

2322閲覧

[python][Django] Djangoでテンプレートファイル内にリンクを貼りたいのですが...

hiroshimaeasyry

総合スコア15

Django

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

Python 3.x

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

0グッド

0クリップ

投稿2018/11/09 11:28

まず当人のレベル感からお話しますと、
私は独学でpythonからプログラミング入門して4-5ヶ月程度です。
この度webアプリケーション制作を一からやってみようと思いdjangoを勉強し始めました。

まずは教材を一通りやってみたあと、今度は変数名やサイトのデザインなどを改変して
オリジナルを作っている最中ですが、テンプレートファイル内にリンクを貼ろうとしたところ
どうも動かないので、どこがおかしいのかご教示いただけると光栄です。

実現したいこと

テンプレート内のhtmlファイルに、modelのclassのidを引き渡して
jobs/3/ とか jobs/10/ とかのurlで個別ページに遷移するリンクを作りたい。

サイトイメージ

イメージ説明
このオシゴト名をクリックするとオシゴト詳細画面(job_detail.html)に遷移するようなイメージです

ディレクトリ構造

![
project2 というプロジェクトがあり、その中にjobs というアプリケーションを作っています。
今回はjobs アプリケーション内のtemplates ディレクトリ内のjobs ディレクトリ内の、
job_index.html の中にテンプレートエンジンを埋め込み、リンクから同列に配置している
job_detail.html を参照できるようにしていきたいと思っています。

job_index.htmlの中身

html

1{% extends 'jobs/base.html' %} 2 3<head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> 6 <!-- Bootstrap CSS --> 7 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> 8<title>オシゴトサーチ</title> 9</head> 10{% block content %} 11<h2>オシゴトを検索しよう。</h2> 12<div class="table-responsible"> 13<table class="table table-hover"> 14<thead> 15<tr class="success"> 16 <th></th> 17 <th>オシゴト名</th> 18 <th>エリア</th> 19 <th>公開日</th> 20 <th>オシゴト内容</th> 21 <th>報酬</th> 22</tr> 23</thead> 24 <tbody> 25 {% for recruit in recruits.all %} 26 <tr> 27 <td><img src="{{ recruit.icon.url }}" class="img-fluid rounded" alt="Responsive image" style="max-height: 50px;"></td> 28 <td><a href="#">{{ recruit.job_name }}</a></td> 29 <td>{{ recruit.area }}</td> 30 <td>{{ recruit.published }}</td> 31 <td>{{ recruit.summary }}...</td> 32 <td>{{ recruit.reward }}</td> 33 </tr> 34 {% endfor %} 35 </tbody> 36</table> 37</div> 38<br> 39<a href="#">ホームへ戻る</a> 40{% endblock %}

※ブロックコンテンツを適用し、共通レイアウト部分に関してはjobs/base.html 内に格納しています。

この2つある<a href="#"> にリンクを埋め込むのを目標としています

modelsファイルの中身

python

1from django.db import models 2 3 4class Recruit(models.Model): 5 job_name = models.CharField(max_length=30) 6 job_genre = models.CharField(max_length=30, blank=True) 7 area = models.CharField(max_length=30, blank=True) 8 company_name = models.CharField(max_length=30) 9 reward = models.IntegerField() 10 from_dates = models.DateField() 11 comments = models.TextField() 12 icon = models.ImageField(upload_to='media/', blank=True) 13 published = models.DateField() 14 points = models.IntegerField() 15 16 def __str__(self): 17 return self.job_name 18 19 def summary(self): 20 return self.comments[:20]

このRecruitクラスが暗にもつidをprimary keyとし、jobs/<id>/のようなurl構成で詳細ページへ飛ばします。

viewsファイルの中身

python

1from django.shortcuts import render, get_object_or_404 2from django.http import HttpResponse 3from .models import Recruit 4 5 6def job_index(request): 7 recruits = Recruit.objects.order_by('-published') 8 return render(request, 'jobs/job_index.html', {'recruits': recruits}) 9 10 11def job_detail(request, job_id): 12 job = get_object_or_404(Recruit, pk=job_id) 13 return render(request, 'jobs/job_detail.html', {'job': job})

project2/urls.py(プロジェクト全体のurl設定)の中身

python

1from django.contrib import admin 2from django.conf.urls import include, url # 他のアプリケーションを読み込むためのinclude 3from django.conf.urls.static import static # 静的ファイルを扱うための設定 4from django.conf import settings # settings.pyを読み込む。*staticを先にimportしないといけない 5from jobs import views 6 7 8urlpatterns = [ 9 url(r'^jobs/', include('jobs.urls')), # jobsの中にあるurls.pyを参照する 10 url(r'^admin/', admin.site.urls), 11 url(r'^jobs/(?P<job_id>[0-9]+)/$', views.job_detail, name="job_detail"), 12 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

django2.1.2で開発していますが、正規表現によるurlパターンを作っています。
django2以降からpathを使ってurlを記述しやすくなったとの話がありますが、よくわかっていません...

jobs/urls.py(個別アプリケーションのurl設定)の中身

python

1from django.conf.urls import url 2from . import views 3 4urlpatterns = [ 5 url(r'^$', views.job_index, name='job_index'), 6]

さて、ではいよいよテンプレートエンジンを使ってリンクを作成します

job_index.html の#のところに、{% url 'job_detail' job.id %} を挿入すれば、リンクが通るはずなんですが。。

イメージ説明

リロードしたらエラーしました。
ちなみに、アドレスバーに/jobs/3/を打ち込むと、詳細ページは表示されるのでurl設定が間違っていると思われます。
イメージ説明

考えられるエラー要因

Reverse for 'job_detail' with arguments '('',)' not found. 1 pattern(s) tried: ['jobs/(?P<job_id>[0-9]+)/$']
とのことですから、viewsファイルで設定したjob_detailがパターンマッチせずうまく読めていないということだと思いますが...なぜなのか?わかりません。

url設定についてまだよくわかっておらず、これを機に理解を深めたいと思いますので、
教えていただけると幸いです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

もしかして見当違いかもしれませんが、テンプレートの for ループで各要素のあてられている名前が recruit であるのに対し、「リンクが通るはずなんですが」とおっしゃっている {% url 'job_detail' job.id %} の名前が job となっています。これが原因ではありませんか?

patch

1- <td><a href="#">{{ recruit.job_name }}</a></td> 2+ <td><a href="{% url 'job_detail' recruit.id %}">{{ recruit.job_name }}</a></td>

投稿2018/11/09 13:44

gh640

総合スコア1407

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

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

hiroshimaeasyry

2018/11/09 15:38

それでした...見当違いどころか、そこがエラーの根源でした。 `{% url 'job_detail' job.id %}` の `job.id` の `job` がどこから来たものか、何を指しているつもりなのかわかっていなかったおかげでエラーを起こしたのですね... それが分かっていないままに適当な`recruit` という変数を設けてしまったことと、先人の知恵をお借りしようとせず3日も悩んだことを悔やみます。 本当に、理解を助けていただいてありがとうございます!!
gh640

2018/11/10 01:30

そうでしたか。。このあたりはハマってしまいますよね。。私も同様の問題を繰り返し経験していますし、ここは Django 利用者の多くが共通ではまるポイントなのではないかと思います。 ご解決に至られたとのことでよかったです! 少し蛇足というか余談ですが、この `url` がうまく動かない問題については一般に次の 2 つのポイントに切り分けて解決するのがよいと思っています。 1. 対象の URL パターンが動作するか確認する 2. 渡された変数が適切か確認する 1 は、 `manage.py shell` でコンソールに入って `django.urls.reverse()` を呼び出すことでチェックすることができます。今回の場合でいえば、 `from django.urls import reverse; reverse('job_detail', 5)` ( `5` は実際に存在する `Recruit` の ID を指定します)と打ち込んで、 `django.urls.exceptions.NoReverseMatch` 等の例外があがれば、 URL パターンが正しく動作していないということがわかります。ポイントは、変数ではなく確実に存在するとわかっている値を引数に渡して試すことです。 2 は、 `url` に渡すべき変数を `url` に渡すのではなく `{{ job }} {{ job.id }}` とページに出力してみるとでチェックすることができます。 今回の場合ですと、 1 は詳細ページがブラウザで閲覧できるということで問題が無いと判断できるので、あとは 2 をチェックすれば糸口がつかめる、という感じになったかなと思います。 ともあれ。前進されたとのことでよかったです! 独学でやられているとのことで困難なこともあるかと思いますが、がんばってください :)
hiroshimaeasyry

2018/11/17 08:38

ご親切に追加情報ありがとうございます! >`{{ job }} {{ job.id }}` とページに出力してみる っていうのはテンプレートのHTMLファイルの貼り付けてブラウザで確認してみるということで合ってますかね?
gh640

2018/11/17 09:19

> っていうのはテンプレートのHTMLファイルの貼り付けてブラウザで確認してみるということで合ってますかね? はい、ご認識のとおりです。例えば今回の場合ですと、 `<a>` タグの直前に `{{ job }}` とでも書いて一度ブラウザで確認してみたら何も表示されないと思いますので、「 `job` に何も入っていない、ここが問題だなぁ」と気づきやすいのではないかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問