I am setting up a website in Django, where users can see their profiles and update details (like email, password, etc) or delete own account. But updating the form is not acknowledged at all by the user. I am using the standard built-in User model.
forms.py:
class UserDetailsForm(forms.ModelForm):
password = forms.CharField(widget = forms.PasswordInput())
class Meta:
model = User
fields = ('first_name','last_name','email','password','is_active')
views.py:
#login_required
def edit_profile(request):
user = User.objects.get(username=request.user)
form = UserDetailsForm(request.POST or None,
initial={'first_name':user.first_name,
'last_name':user.last_name,
'email':user.email,
'password':user.password,
'is_active':user.is_active,})
if request.method == 'POST':
if form.is_valid():
user.save()
messages.info(request, 'This is a debug message')
return HttpResponseRedirect(reverse('account'))
context = {"form": form}
return render(request, "iFood/user-account.html", context)
user-profile.html:
...
<form method="POST" action="{% url 'account' %}" class="" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<input type="submit" name="" value="Edit and Save">
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li class="{{ message.tags }}">
{{ message }}
</li>
{% endfor %}
</ul>
{% endif %}
First of all you can't change a password like that. You should take the password that user entered and set it with user_obj.set_password():
Django docs: Change password
And for your form:
You doing it wrong with user.save(). There is nothing to save for user object. You should save the form using form.save().
Also request.user is the actual user object not the username.
forms.py:
class UserDetailsForm(forms.ModelForm):
password = forms.CharField(widget = forms.PasswordInput())
class Meta:
model = User
fields = ('first_name','last_name','email'','is_active')
views.py:
#login_required
def edit_profile(request):
user = request.user
form = UserDetailsForm(request.POST or None, instance=user)
if request.method == 'POST':
if form.is_valid():
# Save the changes but password
form.save()
# Change password
new_password = form.cleaned_data.get('password')
if new_password:
user.set_password(new_pass)
messages.info(request, 'This is a debug message')
return HttpResponseRedirect(reverse('account'))
context = {"form": form}
return render(request, "iFood/user-account.html", context)
Related
I've two forms rendering in a single function based view, it is diplaying validation errors of only one form when i click the signup button but when i click the login button it just reload my page
and doesn't showing any validation error
views.py
def register(request):
form = RegisterForm()
form_b = LogInForm()
if request.POST.get('submit') == 'sign_up':
form = RegisterForm(request.POST)
if form.is_valid():
form.save()
elif request.POST.get('submit') == 'log_in':
form1 = LogInForm(request=request, data=request.POST)
if form1.is_valid():
uname = form1.cleaned_data['username']
upass = form1.cleaned_data['password']
user = authenticate(username=uname, password=upass)
if user is not None:
login(request, user)
return redirect('/shop/')
else:
form = RegisterForm()
form_b = LogInForm()
return render(request, 'reg.html', {'form': form, 'form1': form_b})
forms.py
from distutils.command.clean import clean
from xml.dom import ValidationErr
from django import forms
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth.models import User
class RegisterForm(UserCreationForm):
password1 = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ['username', 'email']
class LogInForm(AuthenticationForm):
username = forms.CharField(widget=forms.TextInput())
password = forms.CharField(widget=forms.PasswordInput())
reg.html
<form class="loginForm" action="" method="POST" novalidate>
{% csrf_token %}
{% for field in form %}
<p> {{field.label_tag}} {{field}} </p>
<p> {{field.errors}} </p>
{% endfor %}
<button type="submit" class="btnLogin" name='submit' value='sign_up'>Sign Up</button>
</form>
<form class="loginForm" action="" method="post" novalidate>
{% csrf_token %}
{% for field in form1 %}
<p> {{field.label_tag}} {{field}} </p>
<p> {{field.errors | striptags}} </p>
{% endfor %}
<button class="btnLogin" type="submit" name='submit' value='log_in'>Log In </button>
</form>
Try to create seperate view for both register and login.
try this way:
views.py:
def register(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid:
form.save()
username = form.cleaned_data.get('username')
# messages.success(request,f'Welcome { username }')
return HttpResponseRedirect('/users/')
else:
form = RegisterForm()
return render(request,'users/register.html',{'form':form})
And in urls.py:
path('login',auth_views.LoginView.as_view(template_name='users/login.html'),name='login'),
I am trying to create a user profiles for users in my Django app. I have the form displaying where I want it to and when I try to submit, nothing happens.
I put a print statement after the form.is_valid in my view.py and found that it wasn't 'valid' but I have no idea why.
I have tried several different ways to 'clean' / 'validate' data but I can't get past the form being 'invalid.'
Any help would be greatly appreciated!
urls:
path('userinfo/', views.user_info, name='userinfo')
form template:
{% extends "base.html" %}
{% load bootstrap4 %}
{% block content %}
<div class="container">
<h1>Enter User Info</h1>
<form method="POST" class="form">
{% csrf_token %}
{% bootstrap_form form %}
<input type="submit" class="btn btn-primary" value="Create Profile">
</form>
</div>
{% endblock %}
view:
def user_info(request):
form = ProfileForm()
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
form.save()
else:
form = ProfileForm()
return render(request, 'miraDashboard/form.html', context={'form': form})
model:
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
name = models.CharField("Full Name", max_length=1024)
job_role = models.CharField("Role", max_length=254, default="Seeking Job Opportunities")
zip_code = models.CharField("Zip Code", max_length=5)
user_image = models.ImageField("Upload Profile Picture", upload_to='images/')
def __str__(self):
return f'{self.user.username} Profile'
form:
from django.forms import ModelForm
from .models import Profile
class ProfileForm(ModelForm):
class Meta:
model = Profile
fields = ['name','job_role','zip_code', 'user_image']
if you want to see errors in form change else statmant:
def user_info(request):
form = ProfileForm()
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
form.save()
else:
print(form.errors.as_data()) # here you print errors to terminal
return render(request, 'miraDashboard/form.html', context={'form': form})
after form.is_valid() you don't need to set it again (form = ProfileForm() in else statment). this way your form will get errors( you cen see them in form.errors).
I am having an issue with my forms, I've been trying to upload an image when a user registers but it does not submit because an error message is sent which says "This field is required". I'm not too sure where the issue is but I have tried to do this "a_form=InformationForm(request.POST, request.FILES)". But I still got the error message("This field is required") upon registration of the user, even though I have selected the image to be uploaded with the user when registering. I would like to know if a solution could be proffered. The image and code snippet show the issue too. Thanks
FORMS
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Information
class UserRegisterForm(UserCreationForm):
email = forms.EmailField(widget=forms.TextInput(attrs={'placeholder': 'Email'}))
username = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Username'}))
first_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'First name'}))
last_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Last name'}))
password1 = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
password2 = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Confirm'}))
class Meta:
model = User
fields = ['username','first_name','last_name', 'email', 'password1', 'password2']
class InformationForm(forms.ModelForm):
#sex=forms.ChoiceField(choices=CHOICES)
department = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Department'}))
majors = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Majors'}))
nationality = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Nationality'}))
date_of_birth = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'yyyy/mm/dd'}))
passport_number = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Passport number'}))
phone_number = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Phone number'}))
student_passport = forms.ImageField()
class Meta:
model=Information
fields=['department','majors','degree','years','nationality','date_of_birth','passport_number','phone_number','sex','student_passport']
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['email']
class InformationUpdateForm(forms.ModelForm):
class Meta:
model=Information
fields=['phone_number']
VIEWS
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import UserRegisterForm,UserUpdateForm ,InformationUpdateForm,InformationForm
def home(request):
return render(request, 'student/home.html')
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
a_form=InformationForm(request.POST, request.FILES)
if form.is_valid() and a_form.is_valid():
user = form.save()
information = a_form.save(commit=False)
information.user = user
information.save()
messages.success(request, f'Your account has been created! You are now able to log in')
return redirect('login')
else:
form = UserRegisterForm()
a_form = InformationForm()
context={'form':form,'a_form':a_form }#,'a_form':a_form
return render(request, 'student/register.html', context)
#login_required
def profile(request):
return render(request, 'student/profile.html')
#login_required
def passport(request):
return render(request,'student/passport.html')
#login_required
def profile_update(request):
if request.method == 'POST':
u_form=UserUpdateForm(request.POST,instance=request.user)
i_form=InformationUpdateForm(request.POST,request.FILES,instance=request.user.information)
if u_form.is_valid() and i_form.is_valid():
u_form.save()
i_form.save()
messages.success(request, f'Your account has been updated!')
return redirect('profile')
else:
u_form=UserUpdateForm(instance=request.user)
i_form=InformationUpdateForm(instance=request.user.information)
context={'u_form': u_form,
'i_form':i_form}
return render(request, 'student/profile_update.html',context)
REGISTER.HTML
{% extends "student/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group" enctype="multipart/form-data">
<legend class="border-bottom mb-4">Join Today</legend>
{{ form|crispy }}
{{ a_form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit" value="submit">Sign Up</button>
</div>
</form>
<div class="border-top pt-3">
<small class="text-muted">
Already Have An Account? <a class="ml-2" href="{% url 'login' %}">Sign In</a>
</small>
</div>
</div>
{% endblock content %}
Have you added enctype="multipart/form-data" in form tag?
<form action="" method="post" enctype="multipart/form-data">
{{form}} //your form stuff
</form>
you applied enctype="multipart/form-data" to <fieldset> please add in <form> tag
def login(request):
if request.method=='POST':
user = auth.authenticate(username=request.POST['username'],password=request.POST['password1'])
if user is not None:
auth.login(request,user)
return redirect('../')
else:
return render(request,'login.html',{'error':'username or password is wrong'})
else:
return render(request,'login.html')
You need to define your login form that is to be passed to the template.
For example:
forms.py
class LoginForm(forms.Form):
username = forms.CharField(label='Your Email/Username', max_length=100)
password = forms.CharField(label='Your Password', max_length=100)
Then in your views.py, you can define a view function as:
views.py
from .forms import LoginForm
def login(request):
if request.method == "POST":
if form.is_valid:
user = auth.authenticate(username=request.POST['username'],password=request.POST['password1'])
if user is not None:
auth.login(request,user)
return redirect('../')
else:
return render(request,'login.html',{'form': form, 'error':'username or password is wrong'})
else:
form = LoginForm()
return render(request,'login.html', {'form': form})
Then in your template, you can render the form as:
<form method="post">
{% csrf_token %}
{{ form.as_p }} <--render the form in other ways as preferred-->
{% for error in form.errors %} //for displaying the fields where errors have occured
{{ error }}
{% endfor %}
<button type="submit">Login</button>
</form>
you can use django inbuilt loginview:-
in urls.py
from django.contrib.auth.views import LoginView
urlpatterns =[
path('login/' , LoginView.as_view(template_name='login.html') , name ='login')
]
in ur login.html
<h1> login page!! </h1>
<form method='POST'>
{% csrf_token %}
{{ form.as_p }}
<input type='submit' value='Login'>
</form>
When the user enters a username, I want to check the db if that username already exists and display an error message. How would I do that without refreshing the page? With AJAX?
registration_form.html
<div class="container-fluid userformcontainer">
<div class="row">
<div class="col-md-offset-2 col-sm-offset-1 col-sm-8 userformdiv">
<h1 class="title userformtitle">Sign up</h1>
<form method="POST" class="post-form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="save btn btn-default btn-lg userformbutton center-block">Register</button>
{% endbuttons %}
</form>
</div><!--col-->
</div><!--row-->
</div><!--container-->
views.py
class UserFormView(View):
form_class = SignUpForm
template_name = 'card/registration_form.html'
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
username = form.cleaned_data['username']
user.first_name = form.cleaned_data['first_name']
user.last_name = form.cleaned_data['last_name']
if not User.objects.filter(username=username).exists():
password = form.cleaned_data['password']
user.set_password(password)
user.save()
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('card:deck_list')
else:
pass
else:
pass
forms.py
class SignUpForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'first_name', 'last_name', 'password']
You can build your form manually (at least the username field) as per django documentation below:
https://docs.djangoproject.com/en/1.10/topics/forms/#rendering-fields-manually
Then you can set "onchange" event for your field to call a javascript fuction that does the AJAX work for you and display the success/failure message in a div tag of your own.
Alternatively, you may want to let a javascript code that runs on page load to attach an "onchange" event to the "username" field based on its name to the same job for you.