I am trying to display files in django templates. It's showing successfully from the database. I don't why it's not showing from templates. Here I am sharing my codes so far.
#project urls.py
# for DEBUG=False
from django.conf.urls import url
from django.views.static import serve
urlpatterns = [
url(r'^assets/(?P<path>.*)$', serve,
{'document_root': settings.MEDIA_ROOT}), # for DEBUG=False
url(r'^static/(?P<path>.*)$', serve,
{'document_root': settings.STATIC_ROOT}), # for DEBUG=False
] static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
and here is the code for others
#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)
As I need multiple files so I have created another file model with foreign key
#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
in forms I also try to stay clear and everything is working perfectly in 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)
here is the template so far
{% for answer in answers %}
<div >
<div >{{ answer.description }}</div>
<img src="{{ answer.files }}" width="120" />
</div>
{% endfor %}
in the image you can see the description field is showing perfectly but for files I tried several ways.
though from database it's working perfectly
If anyone can help me that will be really appreciable.
Thanks in advance.
CodePudding user response:
To solve this Try this.
note .url
that is very important on showing a FileField/ImageField.
{% for answer in answers %}
<div >
<div >{{ answer.description }}</div>
{% for file in answer.answerfile_set.all %}
<img src="{{ file.file.url }}" width="120" />
{% endfor %}
</div>
{% endfor %}
CodePudding user response:
You'll want to study the QuerySet API here Django Docs, and find out what suits you better of select_related
or prefetch_related
which both follows foreign key relationships in different ways.
Using select_related
:
AnswerFile.objects.all().select_related("answer__question_id").filter(answer__question_id__id = pk)