I'm trying to upload a user photo and show it in homepage.
problem 1 : When i upload an image from admin section it gets saved in database but it doesn't show up in 'homepage.html'.
Problem 2 : When i try to upload an image using 'profile.html' template the image is not even saved in database.
I've tried several solution from stackoverflow but failed to solve my problem. My code is given below:
models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
first_name= models.CharField(max_length=100, default='', blank=True)
last_name = models.CharField(max_length=100, default='', blank=True)
email = models.CharField(max_length=100, default='', blank=True)
pro_pic = models.ImageField(upload_to='profilepic',blank=True)
phone = models.CharField(max_length=20, blank=True, default='')
city = models.CharField(max_length=100, default='', blank=True)
country = models.CharField(max_length=100, default='', blank=True)
job = models.CharField(max_length=20, blank=True, default='')
organization = models.CharField(max_length=100, default='', blank=True)
def __str__(self):
return self.user.username
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
forms.py
from django.contrib.auth.models import User
from django import forms
from .models import UserProfile
class UserForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ['first_name', 'last_name', 'email']
class ProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ['pro_pic','phone', 'city', 'country', 'job', 'organization']
settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT=os.path.join(BASE_DIR,'obs/media')
views.py
@login_required
@transaction.atomic
def update_profile(request):
if request.method == 'POST':
user_form = UserForm(request.POST, instance=request.user)
profile_form = ProfileForm(request.POST, instance=request.user.profile)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
messages.success(request,'Your profile was successfully updated!')
return redirect('obs:homepage')
else:
messages.error(request, 'Please correct the error below.')
else:
user_form = UserForm(instance=request.user)
profile_form = ProfileForm(instance=request.user.profile)
return render(request, 'obs/profile.html', {
'user_form': user_form,
'profile_form': profile_form
})
profile.html
{% extends 'obs/base.html' %}
{% block body %}
{% load staticfiles %}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link href='https://fonts.googleapis.com/css?family=Satisfy' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="{% static 'obs/profilecss.css' %}"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<head>
<title>Profile</title>
</head>
<div class="container">
<div class="row">
<div class="col-md-5 col-md-offset-3">
<div class="panel panel-default">
<div class="panel-heading">
<span class="glyzphicon glyphicon-user"></span> Update User Profile</div>
<div class="panel-body">
{% if error_message %}
<p><strong>{{ error_message }}</strong></p>
{% endif %}
<form method="post" class="hello">
{% csrf_token %}
{% for field in user_form %}
<div class="form-group">
<label class="col-sm-15 control-label">
{{ field.label_tag }}</label>
{{ field }}
</div>
{% endfor %}
{% for field in profile_form %}
<div class="form-group">
<label class="col-sm-15 control-label">
{{ field.label_tag }}</label>
{{ field }}
</div>
{% endfor %}
<center>
<div class="buttonHolder">
<button class="button tick" type="submit"></button>
</div>
</center>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
homepage.html
<div class="profile-userpic">
<img src="{{ profile_form.pro_pic.url }}" class="img-responsive" alt="">
</div>
urls.py (project)
from django.conf.urls import include, url
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^onlinebookshare/', include('registration.urls', namespace="accounts")),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
view for homepage:
@login_required
@transaction.atomic
def update_home(request):
user_form = UserForm(instance=request.user)
profile_form = ProfileForm(instance=request.user.profile)
return render(request, 'obs/homepage.html', {
'user_form': user_form,
'profile_form': profile_form
})
First you need to create the MEDIA_ROOT directory and upload_to directory as you specified.
MEDIA_ROOT=os.path.join(BASE_DIR,'obs/media')
pro_pic = models.ImageField(upload_to='profilepic',blank=True)
In the form tag where you upload the profile pic you need to add the following enctype='multipart/form-data' like
<form method="post" enctype="multipart/form-data" class="hello">.
In the update_profile view change the following line:
profile_form = ProfileForm(request.POST, instance=request.user.profile)
to
profile_form = ProfileForm(request.POST, instance=request.user.profile, request.FILES or None)
Hope this will help.