RelatedObjectDoesNotExist while using custom User model in Django - django

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.

Related

how to identify and set User model foreign keys in User details database on submitting my User Registration form

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')

How to add 2 models in a registration form in Django?

I want to create a Registration form which includes two models. One model is my custom model (Profile) and the other is the default User model in Django. I created two separate forms within the same template but the data is not successfully stored. This is what I had done so far:
models.py:
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
company = models.CharField(max_length=100, blank=True, null=True)
address = models.TextField()
views.py:
def register(request):
if request.method == 'POST':
user_form = UserForm(request.POST)
profile_form = ProfileForm(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
return redirect('login')
else:
user_form = UserForm()
profile_form = ProfileForm()
return render(request, 'register_page.html', {'user_form': user_form, 'profile_form': profile_form})
forms.py:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile
class UserForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['company', 'address']
However, when I tried to register a new user, the data gets saved in the User model (username, email, password) but not in the Profile model (company, address).
I am getting this error instead:
RelatedObjectDoesNotExist at /
Profile has no user.
What should I do?
Since your Profile model is connected to the User model through OneToOne relation so you need to assign the user to your profile like this.:
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
profile = profile_form.save(commit = False)
# assign user to your profile
profile.user = user
profile.save()
return redirect('login')

Django form : Setting the user to logged in user

I am trying to create an address book website where logged in user is able to fill in a form and store contact information. I was able to implement the login and logout functionality. But the problem is that I am not able to set the username to current logged in user. Here is what I have implemented so far:
Models.py
class UserProfileInfo(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE,primary_key=True)
#additional
def __str__(self):
return self.user.usernname
class UserContacts(models.Model):
current_user = models.ForeignKey(User,on_delete=models.CASCADE)
first_name = models.CharField(max_length = 150)
last_name = models.CharField(max_length = 150)
phone_number = models.CharField(max_length = 150)
email_address = models.CharField(max_length = 150)
street_address = models.CharField(max_length = 350)
def __str__(self):
return '{}'.format(self.first_name)
Forms.py
class UserForm(forms.ModelForm):
password = forms.CharField(widget = forms.PasswordInput())
class Meta():
model = User
fields = ('username','email','password')
class UserContactForm(forms.ModelForm):
class Meta():
model = UserContacts
fields = "__all__"
views.py:
#login_required
def new_contact(request):
form = UserContactForm()
current_user = request.user.get_username()
user = User.objects.filter(username=current_user).first()
output = UserContacts.objects.filter(current_user_id=user.id).first()
if request.method == "POST":
form = UserContactForm(request.POST)
if form.is_valid():
form.save(commit=True)
return index(request)
else:
print('Error Form Invalid')
return render(request,'basic_app/contact.html',{'form':form})
Here is how the output looks like when the logged in user tries to enter contact information details:
Updating contact screenshot. As you can see the current user has to select his username to fill out the contact information.
How to overcome this and by default set the username in the form to the current logged in user
Change your UserContactForm to include an extra perameter in __init__, and set the initial value on the user field:
class UserContactForm(forms.ModelForm):
class Meta():
model = UserContacts
fields = "__all__"
def __init__(self, *args, **kws):
# To get request.user. Do not use kwargs.pop('user', None) due to potential security hole
self.user = kws.pop('user')
super().__init__(*args, **kws)
self.fields['user'].initial = self.user
Then change you view to add in the request.user to the form construction:
#login_required
def new_contact(request):
form = UserContactForm(user=request.user)
current_user = request.user.get_username()
user = User.objects.filter(username=current_user).first()
output = UserContacts.objects.filter(current_user_id=user.id).first()
if request.method == "POST":
form = UserContactForm(request.POST, user=request.user)
if form.is_valid():
form.save(commit=True)
return index(request)
else:
print('Error Form Invalid')
return render(request,'basic_app/contact.html',{'form':form})
You could probably remove the:
current_user = request.user.get_username()
user = User.objects.filter(username=current_user).first()
output = UserContacts.objects.filter(current_user_id=user.id).first()

Seller object has no attribute profile

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

Django - User creates User and Profile in same form

Hi have changed my view from this:
How to make User able to create own account with OneToOne link to Profile - Django
For some reason the profile_form is not saving the 'user' information to the database. I have checked the information in the print(profile_form.user) data and does show the username in the terminal. It is not however saving this foreign key to the database, it just leaves it Null.
To this:
Views.py
class IndexView(View):
template_name = 'homepage.html'
form = UserCreationForm
profile_form = ProfileForm
def post(self, request):
user_form = self.form(request.POST)
profile_form = self.profile_form(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
profile_form.save(commit=False)
profile_form.user = user
print(profile_form.user)
print(profile_form)
profile_form.save()
return render(request, self.template_name)
else:
return render(request, self.template_name, {'user_form': self.form,
'profile_form': self.profile_form})
def get(self, request):
if self.request.user.is_authenticated():
return render(request, self.template_name)
else:
return render(request, self.template_name, {'user_form': self.form, 'profile_form': self.profile_form})
Forms.py
class ProfileForm(ModelForm):
"""
A form used to create the profile details of a user.
"""
class Meta:
model = Profile
fields = ['organisation', 'occupation', 'location', 'bio']
Models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
organisation = models.CharField(max_length=100, blank=True)
occupation = models.CharField(max_length=100, blank=True)
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
The user is an attribute of the instance, not the form.
user = user_form.save()
profile = profile_form.save(commit=False)
profile.user = user
print(profile.user)
profile.save()