Convert function view to class based view - django

I am trying to write a a Function-based View (FBV) as a Class-based View (CBV), specifically a CreateView. So far I have been able to write the FBV as a generic View but not as a CreateView. How would I go about doing this?
FBV
def register(request):
registered = False
if request.method == 'POST':
user_form = UserCreationForm(data=request.POST)
if user_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
registered = True
else:
print(user_form.errors)
else:
user_form = UserCreationForm()
return render(request,'accounts/registration.html', {'user_form':user_form, 'registered':registered})
Converted View
class RegisterView(View):
def get(self, request):
registered = False
user_form = UserCreationForm()
return render(request,'accounts/registration.html', {'user_form':user_form, 'registered':registered})
def post(self, request):
registered = False
user_form = UserCreationForm(data=request.POST)
if user_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
registered = True
else:
print(user_form.errors)
return render(request,'accounts/registration.html', {'user_form':user_form, 'registered':registered})

You may follow it
class RegisterView(CreateView):
model = User
form_class = UserCreationForm
template_name = 'accounts/registration.html'
def post(self, request, *args, **kwargs):
registered = False
user_form = UserCreationForm(data=request.POST)
if user_form.is_valid():
user = user_form.save(commit=False)
user.set_password(user.password)
user.save()
registered = True
else:
print(user_form.errors)
return render(request,'accounts/registration.html', {'user_form':user_form, 'registered':registered})

Related

Django form-wizard form save

I would like to save the form and log in in a session wizard I used to do it using requests how would I use it like so>? Within the done function.
class UserWizard(SessionWizardView):
template_name = "registration/signup.html"
form_list = [SignUpForm]
def done(self, form_list, **kwargs):
process_data(form_list)
return redirect('home')
""" 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('password1')
user = authenticate(username=username, password=raw_password)
login(request, user)
return redirect('home')
else:
form = SignUpForm()
return render(request, 'registration/signup.html', {'form': form}) """
class UserWizard(SessionWizardView):
template_name = "registration/signup.html"
form_list = [SignUpForm]
def done(self, form_list, **kwargs):
#process_data(form_list)
form_list[0].save()
userCreate = form_list[0]
username = userCreate.cleaned_data.get('username')
raw_password = userCreate.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password)
if user:
auth_login(self.request, user)
return redirect('home')
Just create a user by saving the form and then use auth_login.

Django form creating new record instead of updating

I'm creating a user update form in my app. but every time when the form is submitted , it creates a new record and if you try submitting again will return Integrity Error(duplicate username that both are null).
ERROR message: django.db.utils.IntegrityError: UNIQUE constraint failed: auth_user.username
forms.py:
class UserChangeForm(forms.ModelForm):
class Meta:
model = User
fields = ['email', 'first_name', 'last_name']
def __init__(self, username, *args, **kwargs):
super(UserChangeForm, self).__init__(*args, **kwargs)
self.username = username
views.py:
def profile(request):
user = request.user
if request.method == 'POST':
user_form = UserChangeForm(user, request.POST)
if user_form.is_valid():
user_form.save()
messages.success(request, f'Your account has been updated!')
return redirect('users:profile')
else:
email = request.user.email
first_name = request.user.first_name
last_name = request.user.last_name
user_form = UserChangeForm(user, initial={
'email': email,
'first_name': first_name,
'last_name': last_name
})
context = {
'user_form': user_form,
}
return render(request, 'users/profile.html', context)
you need to pass the user as instance in the if condition and in else too like this
def profile(request):
if request.method == 'POST':
user_form = UserChangeForm(request.POST , instance = request.user)
if user_form.is_valid():
user_form.save()
messages.success(request, f'Your account has been updated!')
return redirect('users:profile')
else:
user_form = UserChangeForm(instance=request.user)
context = {
'user_form': user_form,
}
return render(request, 'users/profile.html', context)

creation of the profile editing view

hello everyone it's been a while since I haven't coded but I noticed some pref changes so I have some problem with the profile application edited the profile my code
views
#login_required
def edit_profile(request):
if request.method =='POST':
user_form =UserEditForm(data=request.POST or None, instance=request.user)
profile_form=ProfileEditForm(data=request.POST or None, instance=request.user.profile ,files =request.FILES)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
else:
user_form=UserEditForm(instance=request.user)
profile_form=ProfileEditForm(instance=request.user.profile)
context ={
'user_form':user_form,
'profile_form':profile_form,
}
return render(request,'accounts/edit_profile.html',context)
form
class UserEditForm(forms.ModelForm):
class Meta:
model=User
fields=('username', 'email')
class ProfileEditForm(forms.ModelForm):
class Meta:
model=Profile
fields=('description', 'image')
another try to see the same error
form
class EditProfileForm(UserChangeForm):
class Meta:
model=User
fields=('username', 'email')
view
#login_required
def edit_profile(request):
if request.method =='POST':
form= EditProfileForm(request.POST,instance=request.user)
if form.is_valid():
form.save()
return redirect("/profile/")
else:
form=EditProfileForm(instance=request.user)
args={'form': form}
return render(request,'accounts/edit_profile.html',args)
error
The view accounts.views.edit_profile didn't return an HttpResponse object. It returned None instead.
As the error says the view did not return a response.
Your return render... was indented under your POST method:
#login_required
def edit_profile(request):
# You need to define these before the POST method
user_form=UserEditForm(instance=request.user)
profile_form=ProfileEditForm(instance=request.user.profile)
if request.method =='POST':
user_form =UserEditForm(data=request.POST or None, instance=request.user)
profile_form=ProfileEditForm(data=request.POST or None, instance=request.user.profile ,files =request.FILES)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
# I would return a success message here
else:
# Inform the user their form was not valid
context = {
'user_form':user_form,
'profile_form':profile_form,
}
return render(request,'accounts/edit_profile.html',context)

AttributeError at /basic_app/register/ : 'tuple' object has no attribute 'get'

I know this question have been asked alot and most of the time its due to render or HttpResponse in the views.py, i double checked mine but the code looks good to me, dont know where the problem is.
This is a views.py file for a very basic django form but i can't get it to work
def register(request):
registered = False
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_from.save()
user.set_password(user.password)
user.save()
profile = profile_form.save(commit = False)
profile.user = user
if 'profile_pic' in request.FILES:
profile.profile_pic = request.FILES['profile_pic']
profile.save()
registered = True
else:
return (user_form.errors,profile_form.errors)
else:
user_form = UserForm()
profile_form = UserProfileInfoForm()
return render(request,'basic_app/register.html',{'user_form': user_form,
'profile_form':profile_form,
'registered':registered})
You can not return (user_form.errors, profile_form.errors), since that is not a HttpResponse object. What response should the server return in that case.
Usually in case the form is invalid, the server will rerender the content. The form will, if you render it properly display the errors.
Note that in case the POST request was successful, you usually should redirect to implement the Post/Redirect/Get pattern [wiki]. You furthermore probably want to use a UserCreationForm [Django-doc]. This will set the password of the user in the correct way (with .set_password(..)), and run a password validator if you configured this.
You thus can rewrite your view as follows, but you probably should replace UserForm with UserCreationForm:
from django.shortcuts import redirect
def register(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_from.save(commit=False)
user.set_password(user.password)
user.save()
profile = profile_form.save(commit=False)
profile.user = user
if 'profile_pic' in request.FILES:
profile.profile_pic = request.FILES['profile_pic']
profile.save()
return redirect('name-of-view')
else:
user_form = UserForm()
profile_form = UserProfileInfoForm()
return render(
request,
'basic_app/register.html',
{'user_form': user_form, 'profile_form':profile_form })

Django require user when creating password, don't require when editing

my ModelForm definition looks like this:
class UserForm(ModelForm):
password = forms.CharField(required=True, label="Password", widget=forms.PasswordInput)
So password is required when I'm creating a new user. However I'd like to NOT require it when editing the user. My edit/add is handled in views.py in the following way
#user_passes_test(lambda u: u.is_superuser)
def add(request):
if request.method == 'POST':
form = UserForm(request.POST)
if form.is_valid():
new_user = User.objects.create_user(form.cleaned_data['username'], form.cleaned_data['email'], form.cleaned_data['password'])
new_user.save()
messages.success(request, "User '%s' created" % new_user.username)
return HttpResponseRedirect('/user')
else:
form = UserForm()
return render(request, 'user/add.html', {"form": form})
#user_passes_test(lambda u: u.is_superuser)
def edit(request, id):
user = User.objects.get(id=id)
if request.method == 'POST':
f = UserForm(request.POST, instance=user)
if f.is_valid():
f.save()
messages.success(request, "User '%s' altered" % user.username)
return HttpResponseRedirect('/user')
else:
form = UserForm(instance=user)
return render(request, 'user/edit.html', {"form": form, "user": user})
Thanks for the answer.
Michal
This is what I would do:
class UserForm(ModelForm):
def __init__(self, *args, **kwargs):
is_edit = kwargs.get('is_edit', False)
if 'is_edit' in kwargs:
del kwargs['is_edit']
super(UserForm, self).__init__(*args, **kwargs)
if is_edit:
self.fields['password'].required = False
Then, in your edit() function:
f = UserForm(request.POST, instance=user, is_edit=True)
I use this type of thing fairly regularly in our codebase.