Django form ImageField

Elgin Cahangirov picture Elgin Cahangirov · Dec 12, 2017 · Viewed 20.8k times · Source

I'm trying to establish CreateView for the model which holds ImageField. I can successfully upload and display images from django admin page. But, when I upload images from my own form, django doesn't upload images to "upload_to" folder. I'm writing my codes below:

models.py

from django.db import models


class Album(models.Model):
    title = models.CharField(max_length=127)
    artist = models.CharField(max_length=63)
    release_date = models.DateField()
    logo = models.ImageField(blank=True, upload_to='album_logos', default='album_logos/no-image.jpg')

    def __str__(self):
        return self.title

forms.py

from django import forms

from .models import Album
class AlbumCreateForm(forms.ModelForm):

    class Meta:
        model = Album
        fields = [
            'title',
            'artist',
            'release_date',
            'logo'
        ]

views.py

class AlbumCreateView(CreateView):
    form_class = AlbumCreateForm
    template_name = 'music/album_create.html'
    success_url = '/albums/'

album_create.html

{% extends 'base.html' %}

{% block content %}
<form method="post">{% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Create</button>
</form>

{% endblock %}

When I try to create album using "album_create.html" and upload image with django's default form, logo image isn't uploaded to "album_logos" folder and takes default value. Where am I doing wrong?

Answer

Elgin Cahangirov picture Elgin Cahangirov · Dec 13, 2017

I changed album_create.html by specifying "enctype" attribute for the "form" tag as stated in django documentation and my problem is solved.

DOCUMENTATION

forms.py

from django import forms

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length=50)
    file = forms.FileField()

A view handling this form will receive the file data in request.FILES, which is a dictionary containing a key for each FileField (or ImageField, or other FileField subclass) in the form. So the data from the above form would be accessible as request.FILES['file'].

Note that request.FILES will only contain data if the request method was POST and the that posted the request has the attribute enctype="multipart/form-data". Otherwise, request.FILES will be empty.


UPDATED album_create.html

{% extends 'base.html' %}

{% block content %}
<form method="post" enctype="multipart/form-data">{% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Create</button>
</form>

{% endblock %}