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
Related
I would like users to have the ability to update their email address. I created a profile that has fields, but the email address is in the users table. I created a form that adds a custom form field and it works for update. However, I can't find a way to pre-populate this field on a REQUEST.GET.
# forms.py
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('name', 'timezone')
class ProfileUpdateForm(ProfileForm):
email = forms.EmailField(max_length=254)
class Meta(ProfileForm.Meta):
fields = ProfileForm.Meta.fields + ('email',)
# views.py
#login_required
#require_http_methods(["GET","POST"])
def profile_update_view(request):
context = {}
# Get the logged in users profile
profile_object = Profile.objects.get(user=request.user.id)
if request.method == 'GET':
profile_form = ProfileUpdateForm(None, instance=profile_object)
context["form"] = profile_form
# how can I add User.objects.get(id=request.user.id).email to the custom field
if request.method == 'POST':
profile_form = ProfileUpdateForm(request.POST or None, instance=profile_object)
context["form"] = profile_form
if profile_form.is_valid():
try:
# email address exists
user = User.objects.get(email=profile_form.cleaned_data.get('email'))
messages.error(request, 'Failed profile update. Email address already exists.')
except:
# email address available
# get user object
user = User.objects.get(id=request.user.id)
user.email = profile_form.cleaned_data.get('email')
# update user object
user.save()
profile_form.save()
messages.success(request, 'Successful profile update.')
return render(request, "profile.html", context)
I tend to favour class-based views, and things like this are where they come into their own. The form:
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('name', 'timezone')
email = forms.EmailField(max_length=254) #add non-model form field
And a class-based view. Handle the initial value for email in get_initial(), and updating of self.request.user in form_valid():
class ProfileUpdateView( UpdateView):
model = Profile
form_class = ProfileUpdateForm
template_name = 'profile.html' # profiles/update_profile.html would be better
# other declarations ...?
def get_initial(self):
initial = super().get_initial()
initial['email'] = self.request.user.email
return initial
# #transaction.atomic might be a good idea
def form_valid(self, form):
new_email = form.cleaned_data['email']
user = self.request.user
if user.email != new_email: # don't do a pointless non-update save
user.email = new_email
user.save()
return super().form_valid( form) # will save the profile
# forms.py
def __init__(self, *args, **kwargs):
self.email = kwargs.pop("email")
super(ProfileUpdateForm, self).__init__(*args, **kwargs)
self.initial['email'] = self.email
# views.py
if request.method == 'GET':
profile_form = ProfileUpdateForm(None, instance=profile_object, email=request.user.email)
context["form"] = profile_form
if request.method == 'POST':
profile_form = ProfileUpdateForm(request.POST or None, instance=profile_object, email=request.POST.get('email'))
context["form"] = profile_form
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
As I mentioned above I want to automatically identify the User's id from the User model and set it in my User details model as foreign key on Submitting Registration form curenty I am making changes manully to testing purpose which is not a practice for standalone website
models.py
class Student_Details(models.Model):
u_id=models.ForeignKey(User,null=True,on_delete=models.SET_NULL)
field=models.CharField(max_length=400,null=True)
class Institute_Details(models.Model):
I_id=models.ForeignKey(User,null=True,on_delete=models.SET_NULL)
name=models.CharField(max_length=400,null=True)
zipcode=models.CharField(max_length=6,null=True)
def __str__(self):return str(self.name)
class Staff_Details(models.Model):
s_id=models.ForeignKey(User,null=True,on_delete=models.SET_NULL)
Institute_from=models.ForeignKey(Institute_Details,null=True,on_delete=models.SET_NULL)
def __str__(self):return str(self.s_id)
form.py
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['id','username','first_name','last_name','email', 'password1', 'password2']
class Institute_form(ModelForm):
class Meta:
model = Institute_Details
fields=['name','zipcode']
viewspy
#unauthenticated_user
def registerPage(request):
form = CreateUserForm()
form2 = Institute_form(request.POST)
if request.method == 'POST':
form = CreateUserForm(request.POST)
form2 = Institute_form(request.POST)
if form.is_valid():
if request.POST.get('user_type') == 'User':
user1 = form.save()
group1 = Group.objects.get(name='Student')
user1.groups.add(group1)
elif request.POST.get('user_type') == 'Institute':
user2 = form.save()
form2.save()
group2 = Group.objects.get(name='Institute')
user2.groups.add(group2)
return redirect('default')
context = {'form': form,'Iform':form2}
return render(request, "htmls/signup.html", context)
def logoutUser(request):
logout(request)
return redirect('default')
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())
I have an account app in which I have created a Profile model by extending the custom user model. I have created a view which allows the user to edit his profile info and also I have corresponding UserEditForm and ProfileEditForm. As of now, no user has a profile so when I open the edit form I get an error: "RelatedObjectDoesNotExist at /account/edit/".
" User has no profile "
I tried to create the profile using admin , then the error goes away. How can I correct this in my views.py file.
views.py
#login_required
def edit(request):
if request.method =='POST':
user_form = UserEditForm(instance=request.user,data=request.POST)
profile_form = ProfileEditForm(instance=request.user.profile,data=request.POST,files=request.FILES)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
messages.success(request,'Profile updated successfully')
else:
messages.error(request,'Error updating your profile')
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,'account/edit.html',context)
models.py
CATEGORY_CHOICES = (
('SA','School Admin'),
('T','Teacher'),
('S','Student'),
('P','Parent'),
)
class Profile(models.Model):
eduser = models.OneToOneField(settings.AUTH_USER_MODEL)
photo = models.ImageField(upload_to='users/%Y/%m/%d',blank=True)
about_me = models.TextField(max_length=200,blank=True)
category = models.CharField(max_length=1,choices=CATEGORY_CHOICES,blank=True)
date_of_birth = models.DateField(blank=True,null=True)
def __str__(self):
return 'Profile for user {}'.format(self.eduser.username)
forms.py
class UserEditForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name','last_name','email')
class ProfileEditForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('category','date_of_birth','about_me','photo')
You need to catch the error. You can do it at the top of the function:
try:
profile = request.user.profile
except ObjectDoesNotExist:
profile = Profile(user=request.user)
and pass that profile into the ProfileEditForm in both if branches.