I have a model form to update the user profile and everything is saving correctly except of them image. If I use admin it updates fine but when I use my form it just stays as the default profile image.
Here is my form:
class EditProfileForm(forms.ModelForm):
birth_date = forms.DateField(label='birth_date', input_formats=['%Y-%m-%d'])
class Meta:
model = UserProfile
fields = (
"image",
"bio",
"location",
"birth_date",
)
Here is my model:
class UserProfile(models.Model):
user = models.OneToOneField(User)
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
image = models.ImageField(upload_to='profile_image', blank=True)
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
Here is my view:
def edit_profile(request):
instance = get_object_or_404(UserProfile, user=request.user)
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=instance)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
return redirect('/')
else:
form = EditProfileForm(instance=request.user)
return render(request, 'edit_profile.html', {'form': form})
And here is my html:
{% extends 'base.html' %}
{% block content %}
<h1>Edit Profile</h1>
<form method='POST' action=''>{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-outline-success">Save</button>
</form>
</body>
{% endblock %}
For file upload you need to specify form's enctype:
<form method='POST' action='' enctype="multipart/form-data">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-outline-success">Save</button>
</form>
And you should pass request's files to form instance in view:
form = EditProfileForm(request.POST, request.FILES, instance=instance)
Check this doc for details.
Related
This is function for updating user's info.
views.py
def UpdateProfile(request):
context = {}
user = request.User
if not user.is_authenticated:
return redirect('login')
if request.POST:
form = PersonalInfo(request.POST, instance=user)
if form.is_valid():
obj = form.Save(commit=False)
user = user.id
obj.user = user
obj.save()
return redirect('profile')
else:
#messages.error(request, ('Please correct the error below.'))
context['personal_form'] = form
else:
form = PersonalInfo(instance=user)
context['personal_form'] = form
return render(request, 'admission/signup.html', context)
This is the model I have created for storing user info.
models.py:
class ApplicantInfo(models.Model):
infield = models.AutoField(primary_key=True)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
profile_pic = models.ImageField(upload_to='media/', blank= True, null= True)
father_name = models.CharField(max_length=30)
user = models.OneToOneField(User, on_delete=models.CASCADE)
This is the form class I have created.
forms.py:
from .models import Applicant, ApplicantInfo
from django import forms
class PersonalInfo(forms.ModelForm):
class Meta:
model = ProfileInfo
fields = [
'first_name',
'last_name',
'profile_pic',
#'date_birth',
'father_name',
'street_adr',
'city',
'zip_code',
]
This is the frontend template which I have created, this is working fine.
Template
{%block content%}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form method="POST">
{% csrf_token %}
{% for field in personal_form %}
<p>
{{field.label_tag}}
{{field}}
{% if field.help_text %}
<small style="color:gray">{{field.help_text}}</small>
{% endif %}
</p>
{% endfor %}
{% for field in personal_form %}
<p>
{% for error in field.errors %}
<p style="color:red">{{error}}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit">Submit</button>
</form>
</body>
</html>
{% endblock content %}
The app has been able to load the form without any trouble but it just not throwing data to the backend.
Updated function for UpdateProfile
views.py
def UpdateProfile(request, id=None):
context = {}
user_obj = request.user
if not user_obj.is_authenticated:
return redirect('login')
if request.method == "POST":
form = PersonalInfo(request.POST)
if form.is_valid():
obj = form.save()
user_id = Applicant.objects.filter(app_id = user_obj.app_id).first()
obj.user = user_id
obj.save()
return redirect('profile')
else:
#messages.error(request, ('Please correct the error below.'))
context['personal_form'] = form
elif request.method == 'GET':
form = PersonalInfo(instance=user_obj)
context['personal_form'] = form
return render(request, 'admission/signup.html', context)
Updated code for forms method, only add #def cleaned_data function
forms.py
class PersonalInfo( forms.ModelForm):
class Meta:
model = ProfileInfo
fields = [
'first_name',
'last_name',
'profile_pic',
#'date_birth',
'father_name',
'street_adr',
'city',
'zip_code',
]
def clean(self):
if self.is_valid():
first_name = self.cleaned_data['first_name']
last_name = self.cleaned_data['last_name']
father_name = self.cleaned_data['father_name']
street_adr = self.cleaned_data['street_adr']
city = self.cleaned_data['city']
zip_code = self.cleaned_data['zip_code']
And model does not need to be change, you have choice either to add and autofield(PrimaryKey) or use the default one
The problem was in view.py where i just removed instance attribute from the form object, then I called user_id from user model which is in this case #Applicant model, then assigned to the obj object and saved obj.
Thanks to all of you who has spent precious time in this problem.
Cheers!!!
I'm building a post-comment model in one view, one page, something like facebook. I have two forms in my home.html and view.py: new post and new comment. In each post container, there is a new comment form.
I have a problem because I don't know how to relate comment to post - specifically how to pass post.id to my comment form.
Is it possible to pass my {{ post.id }} to my {{newCommentForm.field }}? That each comment has a default value of post's id?
My home.html:
{% for post in posts %}
<div class="container">
<a class="user" href="#">{{ post.author }}</a>, {{ post.date_posted }}
<img src="{{ post.author.profile.image.url }}" alt="{{ post.author }}"style="width:100%;">
<p>{{ post.content }}</p>
<form METHOD="POST" class="new_post">
{% csrf_token %}
{{ newCommentForm.content }}
{{ newCommentForm.post }}
<button type="submit" name="newCommentSubmit">Add</button>
</form>
</div>
{% endfor %}
models.py
class Post(models.Model):
content = models.TextField(max_length=1000)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.content
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(User, on_delete=models.CASCADE)
content = models.TextField(max_length=500)
date = models.DateTimeField(default=timezone.now)
def add_coment(self):
self.date = timezone.now()
self.save()
def __str__(self):
return self.content
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username}'
views.py
#login_required()
def home(request):
newPostForm = newPost()
newCommentForm = newComment()
if request.method == 'POST':
if 'newPostSubmit' in request.POST:
newPostForm = newPost(request.POST, prefix='newpost')
if newPostForm.is_valid():
instance = newPostForm.save(commit=False)
instance.author = request.user
instance.date_posted = timezone.now()
instance.save()
newCommentForm = newComment(prefix='newcomment')
elif 'newCommentSubmit' in request.POST:
newCommentForm = newComment(request.POST, prefix='newcomment')
if newCommentForm.is_valid():
instance = newCommentForm.save(commit=False)
instance.author = request.user
instance.date_posted = timezone.now()
instance.save()
newPostForm = newPost(prefix='newpost')
else:
newPostForm = newPost(prefix='newpost')
newCommentForm = newComment(prefix='newcomment')
context = {
'newPostForm': newPostForm,
'newCommentForm': newCommentForm,
'posts': Post.objects.all().order_by('-date_posted'),
'comments': Comment.objects.all()
}
return render(request, 'blog/home.html', context)
def about(request):
return render(request, 'blog/about.html')
My model is working now, comments are added, but I need to choose my post (post.id) manually from the default dropdown field witch all posts.
Add your post to comment like this:
if newCommentForm.is_valid():
instance = newCommentForm.save(commit=False)
instance.author = request.user
instance,=.post = request.post
instance.date_posted = timezone.now()
instance.save()
And send post in request!
I made a custom UserCreationForm. I can signup but after that I can't login into my web app. I can only login as a superuser. I imported the LoginView() but when I try to login it tells me "Please enter a correct username and password. Note that both fields may be case-sensitive.".
[views.py]
#csrf_exempt
def signup(request):
if request.method == 'POST':
user_form = UserForm(data=request.POST)
profile_form = UserProfileInfoForm(data=request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
profile = profile_form.save(commit=False)
profile.user = user
if 'profile_pic' in request.FILES:
print('found it')
profile.profile_pic = request.FILES['profile_pic']
profile.save()
# registered = True
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
return redirect('../')
else:
print(user_form.errors,profile_form.errors)
else:
user_form = UserForm()
profile_form = UserProfileInfoForm()
return render(request,'users/signup.html',
{'user_form':user_form,
'profile_form':profile_form,'registered':registered})
forms.py
class UserForm(UserCreationForm):
class Meta():
model = User
fields = ('username','email')
def __init__(self, *args, **kwargs):
super(UserCreationForm, self).__init__(*args, **kwargs)
for fieldname in ['username', 'password1', 'password2']:
self.fields[fieldname].help_text = None
class UserProfileInfoForm(forms.ModelForm):
class Meta():
is_photographer = forms.BooleanField()
model = UserProfileInfo
fields = ('portfolio_site','profile_pic', 'type_of_photography', 'is_photographer',)```
models.py
class UserProfileInfo(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
portfolio_site = models.URLField(blank=True)
profile_pic = models.ImageField(upload_to='profile_pics',blank=True)
is_photographer = models.BooleanField(default=False)
type_of_photography = models.CharField(max_length=120, blank=True)
def __str__(self):
return self.user.username
login.html
{% load staticfiles %}
{% block title %}
<title>Login</title>
<link rel="stylesheet" href="{% static 'css/login.css' %}"/>
{% endblock %}
{% block main %}
<div class="col-md-11 container login">
<div class="row">
<div class="col-md-7 left">
<div class="group">
<h1>Login</h1>
<h4>Welcome Back. Please login to your account.</h4>
<form enctype="multipart/form-data" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" value = "login">Login</button>
</form>
</div>
</div>
<div class="col-md-5 right">
<div class="group">
<h1>Don't have an account?</h1>
<h4>Create one now!</h4>
<button>Sign up</button>
</div>
</div>
</div>
</div>
{% endblock %}
views.py
#login_required(login_url='/account/login/')
def TaskCreateView(request,pk,todo_id):
if not request.user.is_authenticated:
return redirect('accounts:index')
else:
instance = get_object_or_404(Level, pk=pk)
qs = instance.todo_set.get(id = todo_id)
todo = Task.objects.filter(todo=qs, student=request.user)
if todo.exists():
messages.warning(request, 'You Already Completed This Task')
return HttpResponseRedirect(instance.get_absolute_url())
form = StudentTaskForm(request.POST or None, request.FILES or None)
if form.is_valid():
form.instance.user = User.objects.get(id=request.user.id)
obj = form.save(commit=False)
obj.student = request.user
obj.todo = qs
obj.level = instance
obj.save()
ImageFormSet = modelformset_factory(Images,
form=ImageForm, extra=3)
formset = ImageFormSet(request.POST, request.FILES,
queryset=Images.objects.none())
if request.method == 'POST':
if formset.is_valid():
for form in formset.cleaned_data:
image = form['image']
photo = Images(post=form, image=image)
photo.save()
return redirect('student:dashboard')
return render(request,'task_form.html',
{'form':form,"qs":qs,'formset':formset})
forms.py
class StudentTaskForm(forms.ModelForm):
title = forms.CharField(widget=forms.TextInput(attrs={'class':
'form-control',' type': "text",'placeholder':'Enter Title'}))
content = forms.CharField(widget=SummernoteWidget())
class Meta:
model = Task
fields = [
'title',
'content',
]
widgets = {
'content': SummernoteWidget(),
}
class ImageForm(forms.ModelForm):
image = forms.ImageField(label='Image')
class Meta:
model = Images
fields = ('image', )
I have two models Task and Images and I'm using two forms for the same.
Im trying to implement multiple image upload for the same. When I try to load the form I'm encountering this error. I have added the {{ formset.management_form }} in the template. The images model has a foreign key to the Task.
template:
<form id="post_form" action="" method="post"
enctype="multipart/form-data">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form %}
{{ field }} <br />
{% endfor %}
{{ formset.management_form }}
{% for form in formset %}
{{ form }}
{% endfor %}
<div class="panel-body">
<button type="submit" class="btn btn-primary m-t-10">Submit</button>
</div>
</form>
You should only instantiate the formset with request.POST for POST requests.
if request.method == 'POST':
formset = ImageFormSet(request.POST, request.FILES,
queryset=Images.objects.none())
...
else:
# GET request
formset = ImageFormSet(queryset=Images.objects.none())
...
Am trying to create a chat forum in django . but to do this i needed to extend the User Model, But after extending it the profile image does not save
This is my model
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
email = models.EmailField()
img = models.FileField(upload_to='media/', blank=True, null=True)
def __str__(self):
return self.user.username
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
My View:
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save()
user.refresh_from_db() # load the profile instance created by the signal
user.profile.email = form.cleaned_data.get('email')
user.profile.img = form.cleaned_data.get('img')
user.save()
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
login(request, user)
return redirect('home')
else:
form = SignUpForm()
return render(request, 'tforum/signup.html', {'form': form})
My Forms.py
class SignUpForm(UserCreationForm):
email = forms.EmailField(help_text='Required.')
img = forms.FileField(help_text='Upload Image')
class Meta:
model = User
fields = ('username', 'email', 'img', 'password1', 'password2', )
Signup.html
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit">Sign up</button>
settings.py
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
The problem is that the user is not created.
If i remove the img from the code the user saves.
I have stripped away most of the styling
you should create a profileForm
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('email', 'img')
and update your signup.py
def update_signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
profile_form = ProfileForm(request.POST, instance=request.user.profile)
if form.is_valid() and profile_form.is_valid():
user = form.save()
user.refresh_from_db() # load the profile instance created by the signal
user.profile.email = form.cleaned_data.get('email')
user.profile.img = form.cleaned_data.get('img')
profile_form.save()
user.save()
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
login(request, user)
return redirect('home')
else:
form = SignUpForm()
return render(request, 'tforum/signup.html', {'form': form})