I want to allow users to change their usernames, so I have a form:
class UserForm(models.ModelForm):
class Meta:
model = User
fields = ('username', 'first_name', 'last_name')
In template, I have a greeting block, something like Hello, {{ request.user.username }}
When I submit a form with a username that already exists, it throws an error "User with this Userame already exists.", but in the greeting block I see Hello, username (where username is this one I have submitted).
What am I doing wrong? Anyone faced something similar?
Here is a view code:
#login_required
def persona_edit(request):
form = PersonaForm(request.POST or None, instance=request.user.persona)
user = User.objects.get(pk=request.user.pk)
user_form = UserForm(request.POST or None, instance=user)
if form.is_valid() and user_form.is_valid():
form.save()
user_form.save()
messages.success(request, _(u'Profile updated'))
return redirect('identity:dashboard')
payload = {'form': form, 'user_form': user_form}
return render(request, 'identity/persona_edit.html', payload)
Related
I want to sign in to be able to use the site. However, I'm having a problem: 'LoginForm' object has no attribute 'cleaned_data'. Please tell me how can I solve it. I apologize in advance for my English
My forms.py
class LoginForm(forms.Form):
user_name = forms.CharField(max_length=20, widget=TextInput(attrs={'type':'text','class': 'form-control','placeholder': 'Input username'}))
passWord = forms.CharField(max_length=25, widget=TextInput(attrs={'type':'password','class': 'form-control','placeholder': 'Input password'}))
class Meta:
fields = ['user_name', 'passWord']
My views.py
def login_view(request):
template_name = 'main/login.html'
action_detail = ''
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid:
username = form.cleaned_data.get('user_name')
password = form.cleaned_data.get('passWord')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('/')
else:
action_detail = 'invalid username or password'
else:
form = LoginForm()
context={
'title': 'Login',
'form': form,
'action_detail': action_detail,
}
return render(request, template_name, context)
is_valid is a function.
https://docs.djangoproject.com/en/4.0/ref/forms/api/#django.forms.Form.is_valid
You should call it.
if form.is_valid():
I'm trying to create a form that allows a user to update their username or avatar. The problem that I am running into is that if I update the profile picture without changing the username, the django form validation if form.is_valid() will recognize the form as invalid, since the username already exists in the database. I'm using an update view, though I'm not sure I've implemented it correctly.
When I try to update the avatar without changing the username, I get a page that says "Form is invalid" from the line: HttpResponse("Form is invalid"). Is there a workaround to remove the form validation? I have tried removing if form.is_valid(): but received the error 'User_form' object has no attribute 'cleaned_data'.
I feel like there has to be an easy way around this that I have not been able to find, as so many sites allow you to update only one attribute at a time.
Views.py
model = User
form = User_form
fields = ['username', 'avatar']
template_name_suffix = '_update_form'
def update_profile(request, user_id):
if request.method == "POST":
form = User_form(request.POST, request.FILES)
if form.is_valid():
user = User.objects.get(pk=user_id)
username = form.cleaned_data['username']
avatar = form.cleaned_data['avatar']
if username != user.username:
user.username = username
if avatar != user.avatar:
if avatar:
user.avatar = avatar
user.save()
return redirect('index')
else:
return HttpResponse("Form is invalid")
models.py
class User(AbstractUser):
followed_by = models.ManyToManyField("User", blank=True, related_name="following")
avatar = models.ImageField(upload_to='profilepics/', verbose_name='Avatar', null=True, blank=True)
class User_form(ModelForm):
class Meta:
model = User
fields = ['username', 'avatar']
user_update_form.html
<form action="/profile/{{user.id}}/update" method="post" enctype='multipart/form-data'>
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Update">
</form>
You are doing too much work yourself. Django's ModelForms can not only create data, but update data as well. You pass the instance through the instance=… parameter:
from django.shortcuts import get_object_or_404
def update_profile(request, user_id):
user = get_object_or_404(User, pk=user_id)
if request.method == 'POST':
form = User_form(request.POST, request.FILES, instance=user)
if form.is_valid():
form.save()
return redirect('index')
else:
return HttpResponse('Form is invalid')
else:
form = User_form(instance=user)
return render(request, 'some_template.html', {'form': form})
For uniqness checks, it will exclude the instance when checking if the username already exists. So one can change the username, given the new username of course does not yet exists.
I am having edit profile template and I wrote view for letting the user to edit the account but I am not getting the form even I wrote the url and view correctly can you please help me out how to let the user edit user model in the front end
my views.py:
def edit_profile(request):
if request.method == 'POST':
form = UserChangeForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('modsy:account'))
Forms.py:
class EditProfileForm(UserChangeForm):
template_name='edit_profile'
class Meta:
model = User
fields = (
'email',
'first_name',
'last_name',
'password'
)
else:
form = UserChangeForm(instance=request.user)
args = {'form': form}
return render(request,'edit_profile.html')
I am only getting the submit button in editprofile page but form is not coming can you please say what mistake I had did
You are handling only for POST request only but not for GET.Also here your form name is EditProfileForm not UserChangeForm so change your view like this:
def edit_profile(request):
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('modsy:account'))
else:
form = EditProfileForm()
return render(request,'Your_template',{'form':form})
I want to create a landing page similar to linkedin's where it has the signup form and the login form at the navbar. I'm currently using a single form for both the signup and login in forms.py:
forms.py
class UserRegisterForm(UserCreationForm):
firstname = forms.CharField(max_length=200, label='')
lastname = forms.CharField(max_length=200, label='')
email = forms.EmailField(label='')
class Meta:
model = User
fields = ['username', 'firstname', 'lastname', 'email', 'password1']
My template includes 2 {{ form }}s and each has a submit button.
Button for the sign up {{ form }}:
name='signupbtn' type='submit'
Button for the login {{ form }}:
name='loginbtn' type='submit'
Now I have trouble trying to login or authenticate the user that I created (which is the super user). My signup/login view goes as follows:
def index(request):
if request.method == 'POST':
if 'signupbtn' in request.POST:
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'Your account has been created! You may now login.')
return redirect('index')
elif 'loginbtn' in request.POST:
username = request.POST['username']
password = request.POST['password1']
form = UserRegisterForm(request.POST)
if form.is_valid():
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
form = UserRegisterForm()
return render(request, 'users/index.html', {'form': form})
Is it possible that I need to create 2 forms in my forms.py? When I try to login, it doesn't go past the form.is_valid() under elif 'loginbtn' in request.POST:. Also both forms have {% csrf_token %}.
I got everything to work by just simply REMOVING the form.is_valid() and adjusting the view after that.
I'm maintaining a Django application and have encountered a bug where if a user edits their profile then their password is corrupted; it seems that set_password is not being used and so the password is set to an unencrypted value which is hardcoded in the form. It's not clear how I could change the existing setup to get around this nuisance, and would welcome any suggestions. The update code looks like this:
#login_required
def profile(request):
user = request.user
profile, created = UserProfile.objects.get_or_create(user=user)
if request.method == 'POST':
userform = UserForm(request.POST, instance=user)
profileform = ProfileForm(request.POST, instance=profile)
if profileform.is_valid():
profileform.save()
if userform.is_valid():
userform.save()
return redirect('user_profile_page')
else:
profileform = ProfileForm(instance=profile)
userform = UserForm(instance=user)
render(request, 'profiles/edit_profile.html', {'profileform': profileform, 'userform': userform})
return render(request, 'profiles/edit_profile.html', {'profileform': profileform, 'userform': userform})
Then, the userform which is causing the problem contains this odd-looking code:
class UserForm(forms.ModelForm):
class Meta:
model = User
exclude = ('last_login', 'date_joined', 'is_active', 'is_superuser', 'is_staff')
username = forms.CharField(widget=forms.TextInput(attrs={'readonly': 'readonly'}))
password = forms.CharField(widget=forms.PasswordInput(attrs={'readonly': 'readonly', 'value': '00000000000000000'}))
I'm not really sure what the value attr in password is meant to be doing. Anyway, I tried to modify this by adding the following to the UserForm:
def save(self, commit=True):
user = super(UserForm, self).save(commit=False)
password = self.cleaned_data["password"]
if len(password) > 0 and password != '00000000000000000':
user.set_password(self.cleaned_data["password"])
if commit:
user.save()
return user
I had no luck with this either, and if I simply omit the password field from the userform or the relevant html then the form does not validate.
<form method="post" action="" class="wide">
{% csrf_token %}
.....
<label for="id_password">Password:</label>
{{ userform.password }}
Can anyone suggest how this might be cleaned up?
Use a separate form for editing the password and remove it from this one. Add password to the exclude list and remove the field declaration.