Home > Blockchain >  How to show files in django templates from database?
How to show files in django templates from database?

Time:04-11

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 %}

enter image description here 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 enter image description here enter image description here

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)
  • Related