this is my blog : http://gorani-dncvb.run.goorm.io/
I am trying to build a signup page for my django blog.
I finished writing codes for template/view/form/url, and successfully connected to the page : http://gorani-dncvb.run.goorm.io/accounts/signup.
So I came to think there is no problem in template/url. but the problem arises after trying signup, It saids :
IntegrityError at /accounts/signup
UNIQUE constraint failed: auth_user.username
and this is my view code :
def signup(request):
if request.method == "POST":
form = SignupForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
raw_password = form.cleaned_data.get('password')
user = User.objects.create_user(username=username, password=raw_password)
return redirect("post_list")
else:
form = SignupForm()
return render(request, 'registration/signup.html', {'form':form})
and this is form code :
class SignupForm(forms.ModelForm):
class Meta:
model = User
fields = ('username','password',)
(I didn't used UserCreateForm on purpose)
There's definitely no overlapping another user, so why I'm seeing this error message?
The reason for duplicating the user is that django creates the user when saving the form.
When a form is a child of ModelForm, saving it will create a new object of the model class related to the form.
Just delete or comment the code lines for user creation and it wil work fine:
def signup(request):
if request.method == "POST":
form = SignupForm(request.POST)
if form.is_valid():
user = form.save()
user.set_password(user.password)
user.save()
return redirect("post_list")
else:
form = SignupForm()
return render(request, 'registration/signup.html', {'form':form})
Best regards.
Related
When user updates profile with username which is already in use ,message appear of "A user with that username already exists." but username on profile is changed to which user requested.
for example: if user with username test001 update profile with already taken username "test0012"
this will happen:
Notice:username is updated with "test0012"
Code in frontend for username:
<h2 id="user-name" class="account-heading user__name">#{{ user.username }}</h2>
also going on "my posts" will redirect to posts of user "test0012".
code for profile and update:
#login_required
def profile(request):
if request.method=="POST":
u_form=UserUpdateForm(request.POST,instance=request.user)#,op_email=request.user.email)
p_form=ProfileUpdateForm(request.POST,request.FILES,instance=request.user.profile)
if u_form.is_valid() and p_form.is_valid():
u_form.save()
p_form.save()
messages.success(request,f'Your Account has been updated!')
#changing email on profile
tusername=u_form.cleaned_data.get('username')
temail=u_form.cleaned_data.get('email')
registeruser=User.objects.get(username=tusername)
registeruser.email=temail
registeruser.save()
return redirect('profile')
else:
u_form=UserUpdateForm(instance=request.user)
p_form=ProfileUpdateForm(instance=request.user.profile)
userupdateform code:
class UserUpdateForm(forms.ModelForm):
email=forms.EmailField()
username=forms.CharField(required=True,validators=[username_check,])
class Meta:
model =User
fields =['username','email']
ProfileUpdateForm:
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model=Profile
fields=['image']
username_check:
def username_check(someusername):
if someusername!=someusername.lower():
raise forms.ValidationError("Only Lower case allowed.")
The model form first does it's own cleaning / validation, after which it assigns this data to the instance that you passed to it and calls that instance's full_clean method which is what gives you the error A user with that username already exists. But as you notice this is already too late as the instance is already modified, although this does not get saved to the database you are displaying the same instance.
The solution to this is to get a copy of the user instance from the database just to pass it to the form, so that the instance associated with the request stays unchanged and clean:
from django.contrib.auth import get_user_model
UserModel = get_user_model()
#login_required
def profile(request):
user = UserModel.objects.get(pk=request.user.pk)
if request.method == "POST":
u_form = UserUpdateForm(request.POST, instance=user)
p_form = ProfileUpdateForm(request.POST, request.FILES, instance=user.profile)
...
else:
u_form = UserUpdateForm(instance=user)
p_form = ProfileUpdateForm(instance=user.profile)
I would like to automatically add the User who submitted the form to the users many to many field on the below-given model when the form submits, how could I do this from the view?
The model:
class Project(MainAbstractModel):
users = models.ManyToManyField(User)
title = models.CharField(max_length=25, default="Conflict")
The view:
def myconflicts(request):
if request.method == "POST":
form = ProjectForm(request.POST)
if form.is_valid():
form.save()
else:
form = ProjectForm()
return render(request, 'conflictmanagement/myconflicts.html')
And my form is simply:
class ProjectForm(ModelForm):
class Meta:
model = Project
fields = ["title"]
You can add the user in the view, for example with:
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect
#login_required
def myconflicts(request):
if request.method == 'POST':
form = ProjectForm(request.POST)
if form.is_valid():
project = form.save()
project.users.add(request.user)
return redirect('name-of-some-view')
else:
form = ProjectForm()
return render(request, 'conflictmanagement/myconflicts.html', {'form': form})
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.
Note: You can limit views to a view to authenticated users with the
#login_required decorator [Django-doc].
I am trying to make a custom registration form in Django, using HTML and CSS and not Django's form.as_p and Bootstrap. I have the following code in views.py:
def signUp(request):
if request.POST:
username = request.POST['username']
email = request.POST['email']
password = request.POST['password']
password_confirm = request.POST['password-confirm']
if(valid_form(username, email, password, password_confirm)) {
#create the new user
} else {
#send some error message
}
return render(request, 'index.html')
I have my own function valid_form to check if the form fields entered by the user are valid. However, I am not sure how I can create the new user using Django's User Model. In all of the code examples regarding registration forms I have seen something like this:
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('main-page')
else:
form = UserCreationForm()
return render(request, 'users/register.html', {'form': form})
Where they use form.save() to create the new user. Since I am not using Django's form model, how can I create a new user after validating form data? Any insights are appreciated.
You can create new Users in your web app by modifying your views.py as below:
from django.contrib.auth import get_user_model
def signUp(request):
if request.POST:
username = request.POST['username']
email = request.POST['email']
password = request.POST['password']
password_confirm = request.POST['password-confirm']
if(valid_form(username, email, password, password_confirm)) {
user = get_user_model().objects.create(
username=username,
email=email,
)
user.set_password(password)
user.save()
} else {
#send some error message
}
return render(request, 'index.html')
I got the problem with form that is not saving to the datebase.
views.py
...
#login_required
def create_task(request):
if request.method == 'POST':
form = CreateTaskForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect('index')
else:
form = CreateTaskForm()
context = {'form': form}
return render(request, 'tasks/task_form.html', context)
...
forms.py
from django import forms
from .models import Task
class CreateTaskForm(forms.ModelForm):
class Meta:
model = Task
fields = (
'name',
'end_date',
'description',
)
Is it the problem with a create_task view or CreateTaskForm?
The problem is with the create_task view:
if request.method == 'POST':
form = CreateTaskForm(request.POST)
if form.is_valid():
# if you have user in your model task make commit to false then set the user
form.save(commit=false)
form.user = request.user
#if not save directly you form
form.save()
return redirect('index')
then check if your url is:
path('create_task', create_task, name="create_task")
First off, since you are using POST, which means you are creating, there is no need for instance=request.user - which is used to compare previous data against new data provided by the form. Looking at your form, it does not look like it has anything to do with the user.
Second, you are not displaying or returning form errors. So it may be silently failing validation at the model level without your knowledge. Try adding a return with form errors.
#login_required
def create_task(request):
form = CreateTaskForm()
if request.method == 'POST':
form = CreateTaskForm(request.POST)
if form.is_valid():
form.save()
return redirect('index')
context = {'form': form}
return render(request, 'tasks/task_form.html', context)
You can look in form.errors on the template side to see validation errors.
I have added python-social-auth in my project for social logins. I also have a signup form of my own for new users. For social logins, I added some authentication backends.
Now, the social logins are working fine, but the signup form causes some problems.
After I enter the details, and click signup, this error comes up.
I see in the admin panel, the user was added even after this error.
ValueError: You have multiple authentication backends configured and therefore must provide the `backend` argument or set the `backend` attribute on the user.
Now, it is asking me to set the backend attribute of the user. How to set that ?
Here is the view for signup,
def signup(request):
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
raw_pass = form.cleaned_data.get('password')
user = authenticate(username=username,password=raw_pass)
login(request,user)
return redirect('location:get_location')
else:
form = SignupForm()
return render(request, 'signup.html', {'form':form})
Worked for me:
if request.method == 'POST':
form = UserCreateForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
return redirect('/')
else:
pass