I am able to update the image of each user's profile picture.
But not through the code. Though it doesn't give me any error.
u_form = For changing the username.
p_form = For changing the picture in their profile.
NOTE: Profile has one to one relation with the Profile model.
settings.py file section:
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/'
models.py for Profile model:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpeg', upload_to='profile_pics')
status = models.TextField(max_length='200')
def __str__(self):
return self.user.username
forms.py for the same:
class ProfileUpdate(forms.ModelForm):
class Meta:
model = Profile
fields = ['image',]
Main views.py file:
.
.
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm as uc
from django.contrib.auth.forms import AuthenticationForm as af
.
.
#login_required(login_url='/login')
def update_profile(request):
user = request.user
if request.method == 'POST':
u_form = UserUpdate(request.POST, instance=user)
p_form = ProfileUpdate(request.POST, request.FILES, instance=user)
if u_form.is_valid() and p_form.is_valid():
u_form.save()
p_form.save()
messages.success(request, 'The profile has been updated.')
return redirect('/profile')
else:
#instance: to get pre-filled data of user
u_form = UserUpdate(instance=user)
p_form = ProfileUpdate(instance=user.profile)
context = {
'u_form': u_form,
'p_form': p_form
}
return render(request, 'update_profile.html', context)
HTML form "update_profile.html":
<form action="{% url 'update_profile' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ u_form }}
{{ p_form }}
<button type="submit">submit</button>
</form>
Try this:
p_form = ProfileUpdate(request.POST, request.FILES, instance=user.profile)
Related
Good day,
I am testing some stuff with Django image Fields and the user model. The point is simply that any user can upload and update a profile picture. But when I select a picture and press upload, I get the message 'This field is required. So it's as if I haven't selected anything.
\\photo.html
<form method="POST">
{% csrf_token %}
{{ form }}
<button type="submit">Upload</button>
</form>
\\views.py
def photo_view(request):
try:
profile = request.user.userimage
except UserImage.DoesNotExist:
profile = UserImage(user=request.user)
if request.method == 'POST':
form = UserImageForm(request.POST, instance=profile)
if form.is_valid():
form.save()
return redirect('/dashboard/user/profile')
else:
form = UserImageForm(instance=profile)
return render(request, 'photo.html', {'form': form})
\models.py
class UserImage(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL, default=None, null=True, on_delete=models.CASCADE)
photo = models.ImageField(
upload_to='images/', height_field=None, width_field=None, max_length=100)
def __str__(self):
return str(self.user)
\\settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
I tried it with this one
https://www.geeksforgeeks.org/imagefield-django-models/
Do someone know a solution? Or should I even use the ImageField when working with images?
Thank you very much! :-)
There are two problems here: if you upload files, you need to specify enctype="multipart/form-data":
form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<button type="submit">Upload</button>
</form>
furthermore you need to pass both request.POST and request.FILES to the form:
def photo_view(request):
try:
profile = request.user.userimage
except UserImage.DoesNotExist:
profile = UserImage(user=request.user)
if request.method == 'POST':
form = UserImageForm(request.POST, request.FILES, instance=profile)
if form.is_valid():
form.save()
return redirect('/dashboard/user/profile')
else:
form = UserImageForm(instance=profile)
return render(request, 'photo.html', {'form': form})
I have a profile page where I would like to allow a user to upload a profile picture. I can edit all of the text but cannot upload an image. It works if i add the image via the Admin, but not via the user's profile page on the website. Note that when created via admin--it is uploading correctly to the directory (profile_image) that i've specified in media folder. I've created some error handling on template page, but the error generated is this: "The 'image' attribute has no file associated with it." Below is my code:
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User)
first_name = models.CharField(default='',max_length=100 )
last_name = models.CharField(default='',max_length=100)
email = models.CharField(max_length=100, default='')
date_birth = models.DateField(default=datetime.datetime.now())
bio = models.TextField(default='')
image = models.ImageField(upload_to='profile_image', blank=True)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
views.py
#login_required
def edit_profile(request):
profile = get_object_or_404(models.UserProfile)
if request.method == 'POST':
form = forms.EditProfileForm(data=request.POST, instance=profile)
if form.is_valid():
form.save()
return redirect('/accounts/profile')
else:
form = forms.EditProfileForm(instance=profile)
args = {'form':form}
return render(request, 'accounts/edit_profile.html', args)
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserChangeForm
from . import models
class UserProfileForm(forms.ModelForm):
class Meta:
model = models.UserProfile
fields = [
'first_name',
'last_name',
'email',
'date_birth',
'bio',
'image',
]
class EditProfileForm(UserProfileForm):
model = models.UserProfile
fields = [
'first_name',
'last_name',
'email',
'date_birth',
'bio',
'image',
]
settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'accounts/media')
edit_profile.html
{% extends "layout.html" %}
{% block title %}User Profile | {{ user }}{{ super }}{% endblock %}
{% block body %}
<h1>My Profile</h1>
<form action="" method="POST" enctype="multipart/form-data">{% csrf_token %}
{{ form.as_p}}
<button type="submit">Save</button>
</form>
{% endblock %}
The file comes in request.FILES, not request.POST. Do the following in the view:
form = forms.EditProfileForm(data=request.POST, files=request.FILES, instance=profile)
See the documentation on file uploads:
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.
Please check your folder permissions also, DRF is not throwing any permission errors for me.
For Mac use : sudo chmod 777 *
For Live Server don't use this just check what is relevant and secure for your Os.
When I'm trying to upload a user profile picture using form, which allowing users to edit their account information - nothing is happening.
I'm not sure what should I do, to get this upload working.
models.py:
class UserProfile(models.Model):
objects = models.Manager()
user = models.OneToOneField(User)
image = models.ImageField(upload_to='profile_image', blank=True)
def __str__(self):
return self.user.username
forms.py:
class EditProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = (
'image',
)
views.py:
def edit_profile(request):
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user.userprofile)
if form.is_valid():
form.save()
return redirect(reverse('accounts:view_profile'))
else:
form = EditProfileForm(instance=request.user.userprofile)
args = {'form': form}
return render(request, 'accounts/edit_profile.html', args)
settings.py:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'mainapp/media')
edit-profile.html:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
If you want to upload files(include images) to Django View, you should get FILES from request.FILES. so like this:
if request.method == 'POST':
form = EditProfileForm(request.POST, request.FILES, instance=request.user.userprofile)
if form.is_valid():
data = form.save(commit=False)
data.user = request.user
data.save()
return redirect(reverse('accounts:view_profile'))
Hello I followed steps here;Need a minimal Django file upload example I'm not sure what I did wrong. I'm trying to add a feature that user to be able to post pictures as well. Here's my try
settings.py
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_in_env", "media_root")
MEDIA_URL = '/media/'
models.py
class Category(models.Model):
image = models.ImageField(upload_to='images',blank=True, null=True)
forms.py
class CategoryForm(forms.ModelForm):
name = forms.CharField(max_length=128)
description = forms.CharField(max_length=300)
image = forms.ImageField()
class Meta:
model = Category
my views.py
#login_required
def add_category(request):
if not request.user.is_superuser and Category.objects.filter(author=request.user).exists():
return render(request,'main/category_already_exists.html')
if request.method == 'POST':
category = Category(author=request.user)
form = CategoryForm(request.POST, instance=category)
if form.is_valid():
form.save(commit=True)
return redirect('index')
else:
form = CategoryForm()
return render(request, 'main/add_category.html', {'form':form})
category.html
{% load staticfiles %}
{{category.image}}
I am assuming you are missing enctype form attribute in your template.
<form method="POST" enctype="multipart/form-data">
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
Also, in your views, instantiating your form should be
form = CategoryForm(request.POST, request.FILES, instance=category)
I was creating a user registration system in django1.8. But when I click register button on the form, it does not redirect to the success url. I am also not sure if this is the right way to save a user information in the database. Please recommend if there is a better way to approach user registration in django.
Models.py
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User)
age = models.IntegerField(blank=True)
gender_choices = (('M', 'Male'), ('F', 'Female'))
gender = models.CharField(max_length=1, choices=gender_choices, default='Male')
forms.py
from django import forms
from .models import UserProfile
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
exclude = ['user']
Views.py
from django.shortcuts import render, redirect
from django.core.urlresolvers import reverse
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .forms import UserProfileForm
# Create your views here.
def registerView(request):
if request.method == "POST":
user_form = UserCreationForm(request.POST)
user_profile_form = UserProfileForm(request.POST)
if user_form.is_valid() and user_profile_form.is_valid():
new_user = user_form.save()
new_user_profile = user_profile_form.save()
return redirect(reverse('success'))
else:
return render(request, 'register.html', {'user_form': user_form, 'user_profile_form': user_profile_form})
else:
user_form = UserCreationForm(request.POST)
user_profile_form = UserProfileForm(request.POST)
return render(request, 'register.html', {'user_form': user_form, 'user_profile_form': user_profile_form})
def successView(request):
username = User.objects.get('username')
return render(request, 'success.html', {'username': username})
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.registerView, name='register'),
url(r'^success/$', views.successView, name='success')
]
register.html
<h1> Welcome </h1>
<form method="POST" action="{% url 'success' %}">
{% csrf_token %}
{{ user_form.as_p }}
{{ user_profile_form.as_p }}
<input type="button" value="Register"/>
</form>
success.html
<h4> Yo Mr...{{ username }}</h4>
<h1>Welcome</h1>
You need to make the following changes:
<h1> Welcome </h1>
<form method="POST" action="{% url 'register' %}">
{% csrf_token %}
{{ user_form.as_p }}
{{ user_profile_form.as_p }}
<input type="submit" value="Register"/>
</form>