Как показать файлы в шаблонах django из базы данных?
Я пытаюсь отобразить файлы в шаблонах django. Из базы данных они успешно отображаются. Я не понимаю, почему он не отображается из шаблонов. Здесь я делюсь своими кодами на данный момент.
#models.py
class Answer(models.Model):
description = models.TextField(blank=True, null=True)
question_id = models.ForeignKey(
Question, blank=False, on_delete=models.CASCADE)
created_by = models.ForeignKey(User, blank=False, on_delete=models.CASCADE)
def __str__(self):
return self.question_id.description
class AnswerFile(models.Model):
answer = models.ForeignKey(
Answer, on_delete=models.CASCADE, related_name='files', null=True, blank=True)
file = models.FileField(
'files', upload_to=path_and_rename, max_length=500, null=True, blank=True)
def __str__(self):
return str(self.answer)
Поскольку мне нужно несколько файлов, я создал другую модель файла с внешним ключом
#forms.py
class AnswerForm(ModelForm):
# question_id = forms.IntegerField(required=True)
class Meta:
model = Answer
fields = ['description']
widgets = {
'description': forms.Textarea(attrs={"class": "form-control", "id": "exampleFormControlTextarea1", "rows": 5, "placeholder": "Add a reply"}),
}
class AnswerFileForm(AnswerForm): # extending Answerform
file = forms.FileField(
widget=forms.ClearableFileInput(attrs={'multiple': True}), required=False)
class Meta(AnswerForm.Meta):
fields = AnswerForm.Meta.fields + ['file', ]
def clean(self):
cleaned_data = super(AnswerFileForm, self).clean()
file = cleaned_data.get("file")
description = cleaned_data.get("description")
if not file and not description:
raise forms.ValidationError("This is a required field.")
return cleaned_data
в формах я также стараюсь держаться подальше и все прекрасно работает в views.py
#views.py
def question_details(request, pk):
question = Question.objects.filter(id=pk).first()
# answers list
answers = Answer.objects.filter(question_id=pk).order_by('-id')
# end answers list
answerForm = AnswerFileForm()
# start of the answer submission
if request.method == "POST":
answerForm = AnswerFileForm(
request.POST or None, request.FILES or None)
files = request.FILES.getlist('file')
if answerForm.is_valid():
question = Question.objects.filter(id=pk).first()
if question:
answer = answerForm.save(commit=False)
answer.created_by = request.user
answer.question_id = question
answer.save()
if files: # check if user has uploaded some files
for file in files:
AnswerFile.objects.create(answer=answer, file=file)
return redirect("fsingle_question", question.pk)
context = {
"page_title": "Question Details",
"question": question,
"answerForm": answerForm,
"answers": answers
}
return render(request, 'ask_question/question_details.html', context)
вот шаблон на данный момент
<div class="ms-5">
<div class="">{{ answer.description }}</div>
<img src="{{ answer.files }}" width="120" />
</div>
на изображении видно, что поле описания отображается отлично, но для файлов я пробовал несколько способов.
хотя из базы данных все работает отлично

Если кто-то может помочь мне, это будет очень признательно.
Заранее спасибо.
Для решения этой проблемы попробуйте следующее.
обратите внимание .url что очень важно при показе поля FileField/ImageField.
{% for answer in answers %}
<div class="ms-5">
<div class="">{{ answer.description }}</div>
{% for file in answer.answerfile_set.all %}
<img src="{{ file.file.url }}" width="120" />
{% endfor %}
</div>
{% endfor %}
Вы захотите изучить QuerySet API здесь Django Docs, и выяснить, что вам больше подходит select_related или prefetch_related, которые оба по-разному используют отношения внешних ключей.
Использование select_related:
AnswerFile.objects.all().select_related("answer__question_id").filter(answer__question_id__id = pk)