Search code examples
pythondjangodjango-formsdjango-database

Django - FileField won't upload to database


I'm trying to upload some file with a FileField but when I hit the submit button and run the form.save() I have a new line in my database table but the file I tried to upload is not there.

I've been searching for some time to solve my problem but the only thing I've seen is about the enctype="multipart/form-data", but as you can see in the files bellow, I already have it ...

views.py

class AdminFichiersPhyto(CreateView):
    template_name = 'phyto/phyto_admin_fichiers.html'
    model = models.PhytoFile
    fields = ['general_treatment', 'other']

    def form_valid(self, form):
        print("GONNA SAVE")
        form.save()
        if self.request.POST.get('autre'):
            print("autre")
            # gonna add some code to read the 'other' file
        if self.request.POST.get('trtm_gen'):
            print("traitement généraux")
            # gonna add some code to read the 'general_treatment' file

phyto_admin_fichiers.html

{% block forms %}

{% if user.is_staff%}

    <form method="post" action="" enctype="multipart/form-data">
        <fieldset>
            <div style="display: inline-block; margin-left: 22%; text-align: center"><b>Traitements généraux</b>{{ form.general_treatment }}</div>
            <div style="display: inline-block; text-align: center"><b>Autres traitements</b>{{ form.other }}</div>
        </fieldset>
    </form>

    <p style="margin-top: 2%">
     <input id="submit" class="btn btn-primary" type="submit" value="Synchronisation Traitements généraux" name="trtm_gen"/>
     <input id="submit" class="btn btn-primary" type="submit" value="Synchronisation Autre" name="autre"/>
    </p>
{% endif %}
{% endblock %}

forms.py

class PhytoFileForm(forms.ModelForm):
    class Meta:
        model = models.PhytoFile
        fields = ['general_treatment', 'other']

    def __init__(self, *args, **kwargs):
        super(PhytoFileForm, self).__init__(*args, **kwargs)

models.py

class PhytoFile(models.Model):
    date = models.DateTimeField("Date", default = datetime.datetime.now)
    general_treatment = models.FileField("Traitements généraux", upload_to='fichiers_phyto/', blank=True, null=True)
    other = models.FileField("Autres traitements", upload_to='fichiers_phyto/', blank=True, null=True)

    class Meta:
        verbose_name = "Liste - Fichier phyto"
        verbose_name_plural = "Liste - Fichiers phyto"

    def __str__(self):
        return str(self.date)

But when even if it doesn't work via the form I can upload files thanks to the admin page. I really hope one of you will have the solution to help me, I've been stucked for a while now ...

EDIT after Akhilendra answer

There is the lastest code I have:

views.py

class AdminFichiersPhyto(View):
    template_name = 'phyto/phyto_admin_fichiers.html'
    form = forms.PhytoFileForm()

    def get(self, request):
        return render(request, self.template_name, {'form': self.form})

    def post(self, request):
        form = forms.PhytoFileForm(request.POST, request.FILES)
        form.save()
        return render(request, self.template_name, {'form': self.form})

phyto_admin_fichiers.html

{% block forms %}

{% if user.is_staff%}

    <form method="post" action="" enctype="multipart/form-data">
      {% csrf_token %}
        <fieldset>
            <div style="display: inline-block; margin-left: 22%; text-align: center"><b>Traitements généraux</b>{{ form.general_treatment }}</div>
            <div style="display: inline-block; text-align: center"><b>Autres traitements</b>{{ form.other }}</div>
        </fieldset>

      <p style="margin-top: 2%">
        <input id="submit" class="btn btn-primary" type="submit" value="Synchronisation Traitements généraux" name="trtm_gen"/>
        <input id="submit" class="btn btn-primary" type="submit" value="Synchronisation Autre" name="autre"/>
      </p>

    </form>
{% endif %}
{% endblock %}

forms.py and models.py didn't change

EDIT SOLUTION

With Akhliendra we dug deeper into my problem and we finaly discovered that the problem came from the inheritance of templates, which would override the enctype="multipart/form-data". So in order to fix that I created a duplicate of the parent template and I added the enctype part in the overriding form tag. Hope this edit would help some people ;)


Solution

  • First submit button should within <form> Tag, And also {% csrf_token %}

    {% block forms %}
    
    {% if user.is_staff%}
    
    <form method="post" action="" enctype="multipart/form-data">
     {% csrf_token %}
     <fieldset>
         <div style="display: inline-block; margin-left: 22%; text-align: center"> <b>Traitements généraux</b>{{
             form.general_treatment }}
         </div>
         <div style="display: inline-block; text-align: center"><b>Autres traitements</b>{{ form.other }}</div>
     </fieldset>
     <p style="margin-top: 2%">
         <input id="submit" class="btn btn-primary" type="submit"
                value="Synchronisation Traitements généraux" name="trtm_gen"/>
         <input id="submit" class="btn btn-primary" type="submit"
                value="Synchronisation Autre" name="autre"/>
     </p>
        </form>
       {% endif %}
    {% endblock %}
    

    Now come to view.

    class AdminFichiersPhyto(View):
        template_name = "phyto/phyto_admin_fichiers.html"
        form = PhytoForm()
    
        def get(self, request):
            return render(request, self.template_name, {'form': self.form})
    
        def post(self, request):
            form = PhytoForm(request.POST, request.FILES)
            form.save()
            return render(request, self.template_name, {'form': self.form})
    

    Hope this will help you.