Djangoにおいて、外部キーで紐づけられた先のテーブルのカラムの値もまとめて取得するにはどのようにすればよいでしょうか?
ブログのように投稿でき、投稿にファイル(画像またはPDF)を添付できるWEBサイトを構築しようとしています。あらかじめ添付ファイルをアップロードしたうえで、投稿データに対して添付するファイルの名前(ファイルのパスではなく、アップロード時にAttachmentクラスのnameで指定した値)を指定して添付する仕組みとしております。投稿データと添付ファイルデータの関係は、投稿1件に対して添付ファイル0件もしくは1件を想定しています。
投稿一覧とその添付ファイルを画面に表示するために、投稿内容だけでなく、各投稿に添付したファイルのURLも取得したいです。
私が調べた範囲では、投稿データのカラムとして、添付ファイルの名前を外部キーとして設定することで、添付ファイルデータもまとめて取得できそうだったのですが、実際に以下のようなHTMLを書いて取得しようとしてもURLが取得できません。エラーは特に発生していないのですが、LINKが機能しておらず、画面上でクリックしても遷移できない状況です。
HTML
1{# attachment_nameは取得できるが、attachment.urlは取得できない #} 2{% for object in object_list %} 3<a href="{{ object.attachment.url }}">{{ object.attachment_name }}</a> 4{% endfor %}
原因や対処法について教えていただけますと大変助かります。
以下、ディレクトリ構造と、全体のスクリプトです。
ディレクトリ構造 myproject |-myproject(配下は省略) |-templates | |-base.html | |-post_list.html | |-app | |-forms.py | |-models.py | |-urls.py | |-views.py | |-.....(その他のファイルは省略) | |-media | |-attachment(添付ファイルの保存場所) | |-manage.py |-db.sqlite3
HTML
1{# templates/post_list.html #} 2 3{% extends "base.html" %} 4{% block content %} 5<h4>投稿一覧と各投稿の添付ファイル</h4> 6<div class="container-fluid"> 7 {% for object in object_list %} 8 <div class="card mb-5"> 9 <div class="card-body"> 10 <h5 class="card-title">{{ object.title }}</h5> 11 <p class="card-text">{{ object.text }}</p> 12 <p class="card-text"><small class="text-muted">{{ object.updated_at|date:"Y.m.d H:i" }}</small></p> 13 </div> 14 <div class="mb-3 mr-3"> 15 <p class="card-text text-right"><a href="{{ object.attachment.url }}">{{ object.attachment_name }}</a></p> 16 </div> 17 </div> 18 {% endfor %} 19</div> 20{% endblock %}
python
1# app/models.py 2from django.db import models 3from django.utils.timezone import now 4from django.core.validators import FileExtensionValidator 5 6# 添付ファイル 7class Attachment(models.Model): 8 name = models.CharField(max_length=100, unique=True) 9 attachment = models.FileField( 10 upload_to='attachment/%Y/%m/%d/', 11 verbose_name='添付ファイル', 12 validators=[FileExtensionValidator(['pdf', 'png', 'jpeg', 'jpg'])], 13 ) 14 is_valid = models.BooleanField(default=True) 15 created_at = models.DateTimeField(auto_now_add=True) 16 updated_at = models.DateTimeField(auto_now=True) 17 18 def __str__(self): 19 return self.name 20 21# 投稿 22class Post(models.Model): 23 title = models.CharField(max_length=100) 24 text = models.TextField() 25 attachment_name = models.ForeignKey(Attachment, to_field='name', on_delete=models.CASCADE, null=True, blank=True, default=None) 26 is_valid = models.BooleanField(default=True) 27 created_at = models.DateTimeField(auto_now_add=True) 28 updated_at = models.DateTimeField(auto_now=True) 29 30 def __str__(self): 31 return self.title 32
python
1# app/forms.py 2from django import forms 3from .models import Attachment, Post 4 5# 添付ファイルをアップロードするためのform 6class AttachmentForm(forms.ModelForm): 7 class Meta: 8 model = Attachment 9 fields = ('name', 'attachment',) 10# 投稿用form 11class PostForm(forms.ModelForm): 12 class Meta: 13 model = Post 14 fields =('title', 'text', 'attachment_name', )
python
1# app/views.py 2from django.views.generic import ListView 3from .models import Attachment, Post 4from .forms import AttachmentForm, PostForm 5 6# 投稿一覧を表示するためのView。ここで、添付するファイルのURLも取得したい。 7class PostList(ListView): 8 template_name = 'post_list.html' 9 model = Post 10 paginate_by = 50 11 def get_queryset(self): 12 return Post.objects.filter(is_valid=True).order_by('-updated_at')
python
1# app/urls.py 2from django.urls import path 3from .views import PostList 4 5urlpatterns = [ 6 ....., 7 path('post_list/', PostList.as_view(), name='post_list'), 8 ....., 9] 10
バージョン情報 python-3.9.5 Django=3.2.4 bootstrap 4.6
やりたいことは、投稿テーブルに添付ファイルテーブルを左結合したいだけなので至って簡単なはずなのですが、思うように実装できず、お力添えいただけますとありがたいです。
そもそものテーブルの設計についても、改善の余地があればご意見いただけると助かります。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/26 06:42