I am using Django's built in authentication to manage users on a social media website. I am using a one-to-one relationship to attach a profile to each user. I can update all the parts of the profile I have attached using an UpdateView. However I don't know how to do that with Django's built in User. So I created a form that uses the _meta class. I have gotten to the point where my form will add a new user instead of update the current one. I was hoping one of you could help me fix my code. Thanks in advance for any help you can offer
views.py
class PrivProfileUpdate(View):
form_class = UserUpdateForm
template_name = 'user/user_form.html'
#display a blank form
def get(self, request, pk):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
#proces form data
def post(self, request, pk):
form = self.form_class(request.POST)
user = User.objects.get(pk=pk)
if form.is_valid():
user = form.save(commit=True)
print("we are trying to save")
#cleaned (normalized) data
username = form.cleaned_data['username']
password = form.cleaned_data['password']
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
email = form.cleaned_data['email']
user.set_password(password) #this is the only way to change a password because of hashing
user.save()
return render(request, self.template_name,{'form': form})
forms.py
class UserUpdateForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'email', 'password', 'first_name', 'last_name']
SOLUTION:
in views.py
class PrivProfileUpdate(UpdateView):
model = User
form_class = UserUpdateForm
template_name = 'user/user_form.html'
def form_valid(self, form):
user = form.save(commit=True)
password = form.cleaned_data['password']
user.set_password(password)
user.save()
return redirect('user:index')
There's nothing special about the User class here. Just as with any other model, to update an existing instance you pass it as the instance argument to the form.
However, you do not actually need to do this at all yourself. You should be using an UpdateView, which does this for you; then you do not need to define get and post. The only method you need to define here is form_valid, to set the password:
class PrivProfileUpdate(UpdateView):
form_class = UserUpdateForm
template_name = 'user/user_form.html'
def form_valid(self, form):
user = form.save(commit=True)
password = form.cleaned_data['password']
user.set_password(password)
user.save()
return HttpResponseRedirect(self.get_success_url())
Related
I have created an abstract user model in Django. The user belongs to multiple services. When I register the user to database then the user has been register instead user_services. user_services are not stored in database while we register the new user.
models.py
class UserAbstract(AbstractUser):
user_services = models.ManyToManyField(UserServices, related_name='services', blank=True)
is_expert = models.BooleanField(default=False)
forms.py
class UserRegistrationForm(UserCreationForm):
class Meta:
model = UserAbstract
fields = [
'username',
'email',
'password1',
'password2',
'user_services',
'is_expert',
]
views.py
def Register(request):
if request.method == 'POST':
form = UserRegistrationForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
user = form.save()
if user is not None:
login(request, user)
messages.success(request, f'{username} account has been registered!')
return redirect('profile')
else:
messages.error(request, "Invalid username or password.")
else:
form = UserRegistrationForm()
return render(request, 'user/register.html', {'form': form})
I just need to add this line after save the user!
user = form.save()
user.user_services.set(services) # services
I am developing a django website where seller can open their accounts and update their profiles,so while while creating seller account I want to create a profile objects,my code of user registration form is given below,
class UserRegisterForm(UserCreationForm):
email = forms.EmailField(required=True)
date_of_birth = forms.DateField(required=True,
input_formats=settings.DATE_INPUT_FORMATS)
class Meta:
model = User
fields = ['username', 'email', 'date_of_birth', 'password1',
'password2']
def save(self, commit=True):
date_of_birth = self.cleaned_data.pop('date_of_birth', None)
user = super(UserRegisterForm, self).save(commit)
seller = Seller.objects.create(name=user.username,
date_of_birth=date_of_birth, created_by=user)
profile = Profile.objects.create(seller=seller)
return user
my code for become_seller in views.py is,
def become_seller(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
return redirect('seller_dashboard')
else:
form = UserRegisterForm()
return render(request, 'become_seller.html',{'form':form})
all of this is working fine,but when I go for edit profile,my code for edit in views.py is,
#login_required
def edit(request):
if request.method == 'POST':
profile_form =
ProfileEditForm(instance=request.user.seller.profile,
data=request.POST, files=request.FILES)
if profile_form.is_valid():
profile_form.save()
else:
profile_form =
ProfileEditForm(instance=request.user.seller.profile)
return render(request, 'profile_edit.html',
{'profile_form':profile_form})
so,while working for this I found the following error message
AttributeError at /seller/edit/ 'Seller' object has no attribute 'profile'
can anyone help me to sort out this issue please
try register also ListingAdmin like admin.site.register(Listing, ListingAdmin) instead of trying to register only model class
ListingAdmin is not registered in admin.site.register()
The issue is solved by using related_name = profile
Here is the model. I have created my own user model
class Profile(models.Model):
user = models.OneToOneField(User)
favorite_food = models.CharField(max_length=100)
def set_password(self, raw_password):
self.user.set_password(raw_password)
Here is the view:
class UserFormView(View):
form_class = UserForm
template_name = 'templates/core/profile_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']
password = form.cleaned_data['password']
user.set_password(password)
user.save()
return render(request, self.template_name, {'form': form})
Here is UserForm
class UserForm(forms.ModelForm):
username = forms.CharField(max_length=10)
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = Profile
fields = ['username', 'password', 'favorite_food']
Where seems to be the problem here? It also says that Profile has no user I have tried changing it to AbstractUser however, it also displays about an error about reverse accessor
Try to exclude user from form and add save method to the form:
class ProfileForm(forms.ModelForm):
username = forms.CharField(max_length=10)
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = Profile
fields = ['username', 'password', 'favorite_food']
exclude = ['user']
def save(self, user = None, force_insert=False, force_update=False, commit=False):
username = self.cleaned_data['username']
password = self.cleaned_data['password']
profile = super(ProfileForm, self).save(commit=commit)
if user:
profile.user = user
profile.set_password(password)
profile.save()
return profile
In you view:
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
profile = form.save(user = request.user, commit=False)
I have created a custom User registration form, from the UserCreationForm. When I try to register, it does register successfully, and I can see a newly created user with the username and its email. But there's no password for that user.
In the admin, the password field for that user is No password set.. Please correct me where I am wrong. Thank you.
forms.py:
from album.forms import MyRegistrationForm
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class MyRegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2',)
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
views.py:
def register_user(request):
if request.method == "POST":
form = MyRegistrationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/register_success/')
else:
form = MyRegistrationForm()
return render(request, 'register.html', {'form':form})
When calling save on the superclass using super, use the form MyRegistrationForm, not its superclass UserCreationForm.
user = super(MyRegistrationForm, self).save(commit=False)
I've been stuck on this for a while now and can't seem to figure out what's going on. I'm just starting to learn Django and I got my login set up and now want to implement a registration page.
I used the UserCreationForm form at first and that worked fine, but I want to add fields for Email, First name, and Last name. I figured I could just subclass UserCreationForm and add the fields but that doesn't seem to work. Also I tried overriding the save method, but it still doesn't work.
My custom form looks like this:
class RegistrationForm(UserCreationForm):
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
email = forms.EmailField(max_length=75)
class Meta:
model = User
fields = ("first_name", "last_name", "email",)
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.first_name = self.cleaned_data["first_name"]
user.last_name = self.cleaned_data["last_name"]
user.email = self.cleaned_data["email"]
if commit:
user.save()
return user
The view to handle this is the following:
def Register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
new_user = form.save();
new_user = authenticate(username=request.POST['username'], password=request.POST['password1'])
login(request, new_user)
return HttpResponseRedirect('/members/home')
else:
form = RegistrationForm()
return render_to_response('register.html', {'form' : form}, context_instance=RequestContext(request))
The form loads just fine with the new fields and everything, but when I submit I get the error:
AttributeError at /register/
'AnonymousUser' object has no attribute 'backend'
Oh, and also I'm using Django 1.3.
Any idea what I'm doing wrong?
My guess is that your meta class fields doesn't include username.
You are inheriting the form field from UserCreationForm but it's not saving to the User model and therefore authenticate is failing, and crashing on login()
The docs suggest you check whether authenticate() is successful before using login()