I'm trying to create a project where I need user profiles.I have extended django default User. I am able create users successfully,but I'm not able to add data into profile model,
for example:
I have created user an user 'Demouser', user is successfully created and I'm also able to login with created user.But next step is to updata data about 'Demouser' in profiles model,for that I have created register view and form but doesn't seem to work.
Forms.py file:
class ProfileForm(forms.ModelForm):
class Meta:
model = profiles
exclude=(
'id','Username','User',
)
Models.py :
class profiles(models.Model):
class Meta:
verbose_name_plural='Profile\'s'
Username=models.OneToOneField(
User,
on_delete=models.CASCADE,
unique=True,
related_name='profile',
)
first_name=models.CharField(
max_length=25,
)
last_name=models.CharField(
max_length=25,
)
email_id=models.EmailField()
previous_projects=models.TextField(
null=True,
blank=True,
)
Views.py :
class ProfileEditView(views.View):
def get(self,request,*args,**kwargs):
if request.user.is_authenticated:
return render(request,'editprofile.html',context={'form':ProfileForm})
else:
messages.success(request,('You must Login into system for access'))
return redirect('profiles:Login')
def post(self,request,*args,**kwargs):
user=User.objects.get(username=request.user.username)
print(user)
form=ProfileForm(request.POST,instance =user)
if form.is_valid():
form.save()
messages.success(request,('Profile Edited succesfully'))
return render(
request,
'editprofile.html',
context={
'form':ProfileForm
}
)
When I update the data using ProfileEditView, suppose I update the First name of logged in User, The data is updated in default django User model , I want it to be updated in my profiles model...
thanks in advance
One of the possible solution is to bring your profile instance and save your profile there. What i want to say from your post method
def post(self,request,*args,**kwargs):
user=User.objects.get(username=request.user.username)
print(user)
form=ProfileForm(request.POST)
if form.is_valid():
// profile is valid now bring profile instance
profile = Profile.objects.get(username=user)
profile.first_name = form.cleaned_data['first_name']
profile.save()
messages.success(request,('Profile Edited succesfully'))
return render(
request,
'editprofile.html',
context={
'form':ProfileForm
}
)
Related
I've created a custom user abstract model and profile model to collect additional information once the user registers.
I am collecting "User type: Employer/employee" at the time of registration but this doesn't seem to be recognized in the profile view. Despite the user being correctly added into the DB (I checked via Admin).
For example, I created user: asus23910 (employer user type). But when I login and redirect to http://127.0.0.1:8000/employer_profile/asus23910/, I get following error:
'User' object has no attribute 'user_type'C:\Users\ASUS\PycharmProjects\Content\content\content\views.py, line 112, in employer_profile_view
1. Here's my employer_profile_view.py code:
def employer_profile_view(request, username):
user = User.objects.get(username=username)
if user.user_type != User.EMPLOYER:
# Redirect to the correct profile page if the user type is not employer
return redirect('employee_profile', username=request.user.username)
if request.method == 'POST':
form = EmployerProfileForm(request.POST, instance=user.employerprofile)
if form.is_valid():
employer_profile = form.save(commit=False)
employer_profile.user = user
employer_profile.save()
return redirect('employer_profile', username=request.user.username)
else:
form = EmployerProfileForm(instance=user.employerprofile)
context = {
'form': form,
'username': username,
}
return render(request, 'employer_profile.html', context)
2. Employer Profile model and connector
class EmployerProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
user_type = models.CharField(
max_length=10,
choices=User.USER_TYPE_CHOICES,
default=User.EMPLOYER
)
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
title = models.CharField(max_length=255)
company_name = models.CharField(max_length=255)
company_logo = models.ImageField(upload_to='company_logos/')
company_location = models.CharField(max_length=255)
company_website = models.URLField()
company_twitter = models.URLField()
#one-2-one connector
#receiver(post_save, sender=User)
def create_employer_profile(sender, instance, created, **kwargs):
if created:
EmployerProfile.objects.create(user=instance, user_type=instance.user_type)
print('Employer Profile created')
#receiver(post_save, sender=User)
def save_employer_profile(sender, instance, **kwargs):
instance.employerprofile.user_type = instance.user_type
instance.employerprofile.save()
print('Employer Profile saved')
3. User model
#model one to store the user into db
class User(AbstractUser):
EMPLOYER = "employer"
EMPLOYEE = "employee"
USER_TYPE_CHOICES = [
(EMPLOYER, "Employer"),
(EMPLOYEE, "Employee"),
]
user_type = models.CharField(
max_length=10,
choices=USER_TYPE_CHOICES,
default=EMPLOYEE
)
email = models.EmailField(default='example#example.com')
username = models.CharField(max_length=150, default='example_user')
password = models.CharField(max_length=128, default='!')
groups = models.ManyToManyField(
Group,
blank=True,
related_name='content_groups'
)
user_permissions = models.ManyToManyField(
Permission,
blank=True,
related_name='content_user_permissions'
)
`
**
What I've tried:**
Flushing and starting new DB (as I used in-built Django user model before and some old users weren't fairing well with the new user-type field).
Adding the user type with default employer option to employer view and fetching the usertype from user model.
**
What I expect:**
The profile view to connect with the custom user model and allow the user to add additional information to their user profile. And ofcourse the profile page to have the user-type attribute as initially stored from user class.
You probably import User not from your models file, but from django.
Anyway I highly recommend (if you overwrote AUTH_USER_MODEL) using built-in get_user_model() method from Django e.g.:
from django.contrib.auth import get_user_model
def employer_profile_view(request, username):
user = get_user_model().objects.get(username=username)
if user.user_type != User.EMPLOYER:
...
And don't use User name for model, I prefer to use CustomUser by myself but you can name it differently, just to avoid mistakes.
check the updated pic
When I save the model, The object name is None, but I need to save the username instead of object name (None) automatically while I saving the Model
here is pic of admin site
Models.py
class solo_21_6_2021(models.Model):
user = models.OneToOneField(User,null=True,on_delete=models.CASCADE)
player1_pubg_id = models.PositiveIntegerField(null=True,blank=True)
player1_pubg_name = models.CharField(max_length=15,null=True,blank=True)
def __str__(self):
return str(self.user)
Views.py
def solo(request):
form = SoloForm()
if request.method=="POST":
form=SoloForm(request.POST)
if form.is_valid():
form.save()
return render(request, 'bgmiapp/solo.html',{'form':form})
Forms.py
class SoloForm(forms.ModelForm):
class Meta():
model = solo_21_6_2021
fields=['player1_pubg_id','player1_pubg_name'
Admin.py
class SoloAdmin(admin.ModelAdmin):
list = ('user','player1_pubg_id','player1_pubg_name')
admin.site.register(Profile)
admin.site.register(solo_21_6_2021,SoloAdmin)
you have set user field to null so the model is created without it, so when you want to show objects by user, it does not have this info so it shows None.
modify models to :
class solo_21_6_2021(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
player1_pubg_id = models.PositiveIntegerField(null=True,blank=True)
player1_pubg_name = models.CharField(max_length=15,null=True,blank=True)
def __str__(self):
return str(self.user)
so now it is required and related as it is supposed to be
and inf the forms:
class SoloForm(forms.ModelForm):
class Meta():
model = solo_21_6_2021
fields=['user','player1_pubg_id','player1_pubg_name']
so it display the choice of user in the html form
now when you submit the form, the user name will display in the admin page
*Alternatively you could make your authenticated user the one who is creating the object, so no need to show list of your users to everyone:
def solo(request):
form = SoloForm()
if request.method=="POST":
form=SoloForm(request.POST)
if form.is_valid():
f = form.save(commit=False)
f.user = request.user
f.save()
return render(request, 'bgmiapp/solo.html',{'form':form})
and get rid of user in forms:
class SoloForm(forms.ModelForm):
class Meta():
model = solo_21_6_2021
fields=['player1_pubg_id','player1_pubg_name']
Ps: since you have a OnetoOne relation, you can create only one object by user, creating another will throw a user_id unique constraint error
I'm trying to create my own User class called Customer which extends the AbstractUser model and has an additional field called address. When I register, I see the user has been created in Django admin and all the fields (username, first name, last name and email) are seen in the django admin screen but I see no value in the "address" field. How do I know if the address is being saved and how can I display it in the admin site?
Below is my code for the models.py
class Customer(AbstractUser):
username = models.CharField(unique=True, max_length=20)
deladdress = models.CharField(max_length=100)
views.py
def signupPage(request):
signForm = CreateCustomer()
if request.method=='POST':
signForm = CreateCustomer(request.POST)
if signForm.is_valid():
signForm.save()
return render(request, 'trial_app/signup.html', {'signForm':signForm})
forms.py
class CreateCustomer(UserCreationForm):
address = forms.CharField(widget=forms.Textarea)
class Meta:
model = Customer
fields = ['username','first_name','last_name','email','address','password1','password2']
def save(self, commit=True):
user = super(CreateCustomer, self).save(commit=False)
user.address = self.cleaned_data["address"]
if commit:
user.save()
return user
Here are some pictures that are the input to my html form and the value in the admin site
It seems like when you save a form in its save method you use
user.address = self.cleaned_data["address"], however, Customer model does not have address field, it has deladdress, so try to rename a field, or use user.deladdress in your save method of CreateCustomer form.
I was looking for solution for my problem here, but it didnt solve my problem.
I want to create user's profile while their signing up.
To signup I use CreateView
class UserRegisterView(generic.CreateView):
form_class = SignUpForm
template_name = 'registration/register.html'
success_url = reverse_lazy('login')
#this method doesn't work and I get
# `Profile.user" must be a "User" instance`
def form_valid(self,form):
Profile.objects.create(user=self.request.user)
My Profile model looks like:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
#rest of fields like bio, social urls etc
My main point is to automatically create user's profile when their create their account.
What is the best way to solve this?
I will suggest to avoid using signals, since you have a form.
self.request.user will return an user object only when an user is logged in using any form of authentication (Session, token etc.)
def form_valid(self,form):
user = form.save()
Profile.objects.create(user=user)
return super(UserRegisterView, self).form_valid(form)
I'm using Django Rest Framework and I've created an extended UserProfile model as follows:
class UserProfile(models.Model):
user = models.OneToOneField(User)
#Some Fields for UserProfile
def user_profile_url(self):
return reverse('user_profile', args=(self.user.id, "{}-{}".format(self.user.first_name, self.user.last_name)))
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
However, on signing up using rest_auth's /registration endpoint: http://django-rest-auth.readthedocs.org/en/latest/api_endpoints.html#registration, the UserProfile is not being created even though the User is created. In my serializers.py, I've done the following for users who sign up
class UserSignUpSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email',)
def create(self, validated_data):
user = User(email=validated_data['email'], username=validated_data['email'])
user.set_password(validated_data['password'])
user.save()
profile = UserProfile(user=user)
profile.save()
return user
Where am I going wrong?
Because request goes here https://github.com/Tivix/django-rest-auth/blob/master/rest_auth/registration/views.py#L38 and doesn't call serializer.create() actually.
Try to override signup form as suggested in the docs:
ACCOUNT_FORMS = {
'signup': 'path.to.custom.SignupForm'
}
example of the profile form:
https://djangosnippets.org/snippets/2081/