8

I tried a minimalistic django implementation of generic views to upload profile pictures.

views.py

class UpdateProfile(UpdateView):
    form_class = UpdateUserProfileForm
    model = UserProfile
    success_url = reverse_lazy('show_profile')

models.py

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    website = models.URLField(blank=True)
    picture = models.ImageField(upload_to='user/img/%Y-%m-%d/', blank=True)

forms.py

class UpdateUserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ['website','picture']

userprofile_form.html

<form action="" enctype="multipart/form-data" method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="{% trans "Save" %}"/>
</form>

Everything works fine. Now error message. The website field will be updated properly, and a search button allows to choose a file for upload. However the file never appears in the system and the database field remains empty.

Unfortunately the django documentation on file upload (https://docs.djangoproject.com/en/1.10/topics/http/file-uploads/) does not include generic views, so I wonder if it is possible at all.

Update: Thanks to Alasdair's answer I updated my template so it works fine now as a minimalistic prototype for picture upload with generic views.

To display the picture, instructions of the documentation (https://docs.djangoproject.com/en/1.10/howto/static-files/) are quite helpful again.

Also the media settings are necessary to upload the files to the media folder.

settings.py

MEDIA_URL = '/media/'
MEDIA_ROOT = 'absolute-path-to/media'

urls.py

from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

template

{% if userprofile.picture.url|length > 0 %}
    <img src="{{ userprofile.picture.url }}" width="200px">
{% else %}
    <img src="{% static "/img/default_profile.jpg" %}" width="200px" />
{% endif %}

1 Answer 1

14

The problem is in your template. You haven't set enctype, so request.FILES will always be empty. It should be:

<form action="" enctype="multipart/form-data" method="post">{% csrf_token %}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.