1

I am trying to upload multiple files in Django form. I followed multiple methods. I am successful via models to views but I want via models to forms to views. I followed Use view/form in Django to upload a multiple files this question but my form is not submitting. Here I am sharing my codes. I hope to get the mistake I am doing by any expert.

#models.py

class Question(models.Model):
    description = models.TextField(blank=True, null=True)
    created_by = models.ForeignKey(User, blank=False, on_delete=models.CASCADE)

    def __str__(self):
        return self.description


class QuestionFile(models.Model):
    question = models.ForeignKey(
        Question, 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.question)


#forms.py
from django import forms
from .models import *


class QuestionForm(forms.ModelForm):
    class Meta:
        model = Question
        fields = ['description']


class QuestionFileForm(QuestionForm):  # extending Questionform
    file = forms.FileField(
        widget=forms.ClearableFileInput(attrs={'multiple': True}))

    class Meta(QuestionForm.Meta):
        fields = QuestionForm.Meta.fields + ['file', ]

    def clean(self):
        cleaned_data = super().clean()
        description = cleaned_data.get("description")
        file = cleaned_data.get("file")

        if not description and not file:
            self.add_error(
                'description', 'Kindly describe the question details or upload any file')


#views.py
def questionView(request):
    if request.method == 'POST':
        form = QuestionFileForm(request.POST or None, request.FILES or None)
        files = request.FILES.getlist('file')
        if form.is_valid():
            question = form.save(commit=False)
            question.created_by = request.user
            # add everything needed to add here
            question.save()
            if files:  # check if user has uploaded some files
                for file in files:
                    QuestionFile.objects.create(question=question, file=file)

            messages.success(request, 'Question asked successfully.')
            return redirect('url_name')
    else:
        form = QuestionFileForm()
    context = {
        "page_title": "Ask a Math Question",
        "form": form
    }
    return render(request, 'template.html', context)


#template.html
{% extends 'base.html' %}
<!-- title -->
{% block title %}{{ page_title }}{% endblock title %}

<!-- body -->
{% block content %}
<div class="ask_question text-center">
  <!--for message-->
  {% if messages %} {% for message in messages %}
  <div
    {% if message.tags %}
    class="alert alert-{{ message.tags }} text-center"
    {% endif %}
  >
    {{ message }}
  </div>
  {% endfor %} {% endif %}

  <form
    method="POST"
    action="{% url 'fask_question' %}"
    novalidate
    class="needs-validation"
    enctype="multipart/form-data"
  >
    {% csrf_token %}

    <div class="mb-3">
      <input
        type="file"
        class="clearablefileinput form-control-file"
        name="files"
        id="exampleFormControlFile1"
        multiple
      />
    </div>

    <div class="mb-3">
      <textarea
        class="form-control"
        id="exampleFormControlTextarea1"
        rows="8"
        placeholder="Type your question here"
        name="description"
      ></textarea>
    </div>

    <button type="submit" class="btn">Submit</button>
  </form>
</div>
{% endblock %}

I am unable to understand where I am making the mistake that my form is not submitting. If anyone can help I will be grateful. Thanks in advance.

Anny
  • 163
  • 1
  • 9

1 Answers1

1

Try to pass the form from the context in to the template

Change this part of your template

<form
    method="POST"
    action="{% url 'fask_question' %}"
    novalidate
    class="needs-validation"
    enctype="multipart/form-data"
  >
    {% csrf_token %}

    <div class="mb-3">
      <input
        type="file"
        class="clearablefileinput form-control-file"
        name="files"
        id="exampleFormControlFile1"
        multiple
      />
    </div>

    <div class="mb-3">
      <textarea
        class="form-control"
        id="exampleFormControlTextarea1"
        rows="8"
        placeholder="Type your question here"
        name="description"
      ></textarea>
    </div>

    <button type="submit" class="btn">Submit</button>
  </form>

To

  <form
    method="POST"
    action="{% url 'fask_question' %}"
    novalidate
    class="needs-validation"
    enctype="multipart/form-data"
  >
    {% csrf_token %}
  {{ form }}

    <button type="submit" class="btn">Submit</button>
  </form>
Thierno Amadou Sow
  • 2,523
  • 2
  • 5
  • 19
  • ok but later I might need font-awesome to upload file still lemme check – Anny Mar 30 '22 at 13:13
  • @Anny is it working now ? is the data saved in the db ? – Thierno Amadou Sow Mar 30 '22 at 13:14
  • 1
    Yup just now I checked it's perfectly working thanks a lot – Anny Mar 30 '22 at 13:16
  • but I want that way bro. can you explain me what was the wrong in the code so far! – Anny Mar 30 '22 at 13:16
  • @Anny i am happy i was able to help happy coding ).The problem was that you are using a manual form in your template and in your view(in `request.method=='post' you are using this form QuestionFileForm() but that form actually is not in your template that way it is unvalidated the form with None value so form.valid() will always return false`).this is a very good article https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Forms – Thierno Amadou Sow Mar 30 '22 at 13:21
  • but bro I tried earlier with different method as two forms in same views. That was working though! – Anny Mar 30 '22 at 13:50