【Django】TemplateResponseMixin requires either a definition of ‘template_name’ or an implementation of ‘get_template_names()
【Django】TemplateResponseMixin requires either a definition of ‘template_name’ or an implementation of ‘get_template_names()
こんなエラーが出てきたので翻訳機に掛けてみました。
TemplateResponseMixin は ‘template_name’ の定義か ‘get_template_names() の実装を必要とします。
(意訳)TemplateResponseMixinと言う所にデータが渡ってきたけど必要な情報揃ってないよ。
今回解決に至った方法
まぁね、まだまだな訳です。
Django初心者、参考図書のルート上にある事はやりたい様に動かせても、テキストのルートを少し外れると不明な事ばかりです。今回はそんな問題の一端でした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#views.py import logging from django.urls import reverse_lazy from django.contrib import messages from django.views import generic from django.shortcuts import render from .models import Company from .forms import InquiryForm, logger = logging.getLogger(__name__) class IndexView(generic.TemplateView): template_name = "websites/index.html" class InquiryView(generic.FormView): template_name = "websites/inquiry.html" form_class = InquiryForm success_url = reverse_lazy('company:inquiry') def form_valid(self, form): form.send_email() messages.success(self.request, 'メッセージを送信しました。') logger.info('Inquiry sent by {}'.format(form.cleaned_data['name'])) return super().form_valid(form) class ServiceView(generic.FormView): template_name = "websites/service.html" |
この中の28行目【class ServiceView(generic.FormView):】を【class ServiceView(generic.FormView):】と修正するとエラーの発生はなくなります。
1 2 |
class ServiceView(generic.TemplateView): template_name = "websites/service.html" |
この方法だと website/service.htmlに記載した値をurl.pyで関連付けたアドレスで表記してくれます。
1 2 3 4 5 6 7 8 9 |
#urls.py from django.urls import path from . import views app_name = 'web' urlpatterns = [ path('', views.IndexView.as_view(), name="index"), path('inquiry', views.InquiryView.as_view(), name="inquiry"), path('service', views.ServiceView.as_view(), name="service"), |
こんな感じでurls.pyを書いていれば、https://ドメイン/service にアクセスすれば websites/service.html を表示します。でもやりたのはそこじゃないんです。
FormView と書いてみたのはDBに格納した値を表示したかったからなんですよね。
WordPressのようにSQLにHTMLを格納しページに表示するための構成
今回はSQLに【 contents 】というテーブルを用意し次のようなフィールドを用意しました。
- types:記載ページを指示(informationかserviceかといったフラグ)
- name:記載内容(contents)のタイトル。WEBに表現する時はhタグをつけて飾る予定
- contents:記載するHTMLを格納する場所。bootstrapのルールに従っておけばテンプレート変更で色々変更出来るはず。
- sort_number:typesの中の並び替え。コンテンツを小分けにした方が融通を利かせられるので用意。
- switch:WEBへの表示対象とするかを表すマーカー。Falseにしておけば表示しないのでWEBサイトの変更に活用できる。
これをmodels.pyに表現するとこんな感じ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#models.py from django.db import models from django.core.validators import RegexValidator class Contents(models.Model): """CMS_WEB記載内容/要素""" CATEGORY_CHOICES = ( (1, 'インフォ'), (2, 'サービス'), (3, 'プロジェクト'), (4, 'プロフィール'), ) types = models.IntegerField(verbose_name='記載箇所', choices=CATEGORY_CHOICES) name = models.CharField(verbose_name="コンテンツ名", max_length=100, blank=False, null=True) contents = models.TextField(verbose_name="HTMLコード", blank=False, null=True) sort_number = models.IntegerField(verbose_name='並び順', blank=False, default=1) switch = models.BooleanField(verbose_name='ON/OFF', blank=False, default=True) created_at = models.DateTimeField(verbose_name='作成日時', auto_now_add=True) updated_at = models.DateTimeField(verbose_name='更新日時', auto_now=True) class Meta: verbose_name_plural = 'Contents' def __str__(self): return self.name |
この状態でマイグレーションを実行すれば設定したSQLサーバーにテーブルを作成してくれます。
Djangoではこうしてmodels.Model に紐づけたテーブル構成はQuerySetとして扱う事が出来る様です。
で、Views.pyではこのQuerySetを呼出して欲しい値の抽出を行います。
1 2 3 4 5 6 7 8 9 10 |
#views.py (前略) def ServiceView(request): data = Contents.objects.filter(switch=1).filter(types=2).order_by('sort_number') params = { 'title': '事業内容', 'data': data } return render(request, 'websites/service.html', params) |
この時のurls.pyは下のようにします。
1 2 3 4 5 6 |
#urls.py (前略) urlpatterns = [ (中略) path('service', views.ServiceView, name="service"), ] |
これで、https://ドメイン/service にアクセスしてきた場合 contentsテーブルの値にフィルターかけて抽出したものをservice.htmlに渡して表示する事が出来ます。
CMSの原型がこれで完成です。
まとめ
ここまででなかなか手こずったのは【class】と【def】の違いと記載方法でした。
Laravelを道具にしてた私からすると【def】の書き出しになじみがなく、全てClassで書いていたのですが[ class ServiceView(request): ] とするとエラーなんですよね。classではrequestを呼び込めないのか、動線が異なるのか、ここら辺はまだ「理解してる」と言い難いです。
まぁ作りながら理解してくしかないですね。
今日も頑張りましょう!
-
前の記事
【Django】Forms.pyって何!? バリデーション構築で混乱してきたので整理してみた 2020.11.27
-
次の記事
【Django】SQLに格納したHTMLをタグを含めそのまま出力する 2020.11.30
コメントを残す