How do I connect a model instance to a user in django? - python

Im looking to make it so the logged in user that creates a profile is linked to their guestprofile model when they create their profile.
When I create the guest profile while logged in, it successfully creates the guest profile, but in the guest profile admin screen there is no user connected to the guest profile model created. Instead there is a dropdown menu listing all users, which makes the connection process manual. Thanks.
Forms.py
class AddProfileForm(forms.ModelForm):
name = forms.CharField(max_length=50, widget=forms.TextInput(attrs={'class': 'form-control'}))
location = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'class': 'form-control'}))
summary = forms.CharField(max_length=500, widget=forms.Textarea(attrs={'class': 'form-control'}))
profile_pic = forms.ImageField()
class Meta:
model = GuestProfile
fields = ('name', 'location', 'summary', 'profile_pic')
Models.py
class GuestProfile(models.Model):
user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
location = models.CharField(max_length=100)
summary = models.TextField(max_length=350)
profile_pic = models.ImageField(null=True, blank=True, upload_to="images/")
def __str__(self):
return str(self.user)
views.py
class AddProfileView(CreateView):
model = GuestProfile
form_class = AddProfileForm
template_name = 'profilemanip/addprofile.html'
success_url = reverse_lazy('home')
def get_object(self):
return self.request.user
Edit: I ended up solving my issue by changing my AddProfileView to the following:
def AddProfileView(request,*args,**kwargs):
form = AddProfileForm(request.POST or None)
if form.is_valid():
obj = form.save(commit=False)
obj.user = request.user
obj.save()
form = AddProfileForm()
return render(request, "profilemanip/addprofile.html", {"form": form})

Try adding this to your AddProfileForm in order to associate the user with the profile:
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user',None)
super(AddProfileForm, self).__init__(*args, **kwargs)

Related

How can I connect a model instance to a user in django?

Im looking to make it so the logged in user that creates a profile is linked to their guestprofile model when they create their profile.
When I create the guest profile while logged in, it successfully creates the guest profile, but in the guest profile admin screen there is no user connected to the guest profile model created. Instead there is a dropdown menu listing all users, which makes the connection process manual. Thanks.
Forms.py
class AddProfileForm(forms.ModelForm):
name = forms.CharField(max_length=50, widget=forms.TextInput(attrs={'class': 'form-control'}))
location = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'class': 'form-control'}))
summary = forms.CharField(max_length=500, widget=forms.Textarea(attrs={'class': 'form-control'}))
profile_pic = forms.ImageField()
class Meta:
model = GuestProfile
fields = ('name', 'location', 'summary', 'profile_pic')
Models.py
class GuestProfile(models.Model):
user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
location = models.CharField(max_length=100)
summary = models.TextField(max_length=350)
profile_pic = models.ImageField(null=True, blank=True, upload_to="images/")
def __str__(self):
return str(self.user)
views.py
class AddProfileView(CreateView):
model = GuestProfile
form_class = AddProfileForm
template_name = 'profilemanip/addprofile.html'
success_url = reverse_lazy('home')
def get_object(self):
return self.request.user
Edit: I ended up solving my issue by changing my AddProfileView to the following:
def AddProfileView(request,*args,**kwargs):
form = AddProfileForm(request.POST or None)
if form.is_valid():
obj = form.save(commit=False)
obj.user = request.user
obj.save()
form = AddProfileForm()
return render(request, "profilemanip/addprofile.html", {"form": form})

Profile ID not stored in User after creation Django

I wrote the following code:
class RegisterForm(UserCreationForm):
email = forms.EmailField(max_length=200, help_text='Required')
class Meta:
model = CustomUser
fields = ('username', 'email', 'password1', 'password2')
#login_required(login_url="/login")
def index(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
profile = Profile().save()
user = form
user.profile = profile
user.save()
return redirect('users')
else:
print(form.errors)
else:
form = RegisterForm()
user_model = get_user_model()
users = user_model.objects.all()
paginator = Paginator(users, 15)
page = request.GET.get('page')
users = paginator.get_page(page)
return render(request, 'users/index.html', {'users': users, 'form': form})
class Profile(models.Model):
has_premium_until = models.DateTimeField(null=True, blank=True)
has_premium = models.BooleanField(default=False)
has_telegram_premium_until = models.DateTimeField(null=True, blank=True)
has_telegram_premium = models.BooleanField(default=False)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
class CustomUser(AbstractUser):
email = models.EmailField(max_length=255, unique=True)
profile = models.OneToOneField(Profile, on_delete=models.CASCADE, null=True)
When I'm submitting the form the user as well as the profile is created but the profile is not stored in the user (the profile_id stays null).
Anyone who can help me out?
Change your code to
if form.is_valid():
profile = Profile().save()
user = form.save(commit=False)
user.profile = profile
user.save()
return redirect('users')
This way the user object will be created and then you refer to the profile ju just created and save it.
There is however another way of doing it with signals:
#receiver(models.signals.post_save, sender=CustomUser)
def create_profile_on_user_reg(sender, instance, created,**kwargs):
if created:
instance.profile = Profile()
instance.save()
Check out more on Django signals documentation

Get inputs from user into profile model of Django

I have a registration form which is an extension of UserCreationForm and I have a UserProfileForm. I am rendering both the forms to the same html during user registration.
The problem is, inputs are getting saved to the inbuilt users model but not to the Profile Model. No data is showing up in Profile Model.
I have tried many ways and looked for many solution but unable to find the mistake.
My forms.py looks like this -
class RegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
first_name = forms.CharField(required=True)
last_name = forms.CharField(required=True)
username = forms.CharField(required=True)
class Meta:
model = User
fields = ['username',
'first_name',
'last_name',
'email',
'password1',
'password2'
]
def save(self,commit):
user = super(RegistrationForm,self).save(commit=False)
if commit:
user.save()
return user
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
exclude = ['user']
def save(self,commit):
user = super(RegistrationForm,self).save(commit=False)
USN =self.cleaned_data['USN']
year = self.cleaned_data['year']
sem = super(RegistrationForm,self).save(commit=False)
if commit:
user.save()
return user
Have created UserProfile model in models.py
class UserProfile(models.Model):
alphanumeric = RegexValidator(r'^[0-9A-Z]*$', 'Only alphanumeric
characters are allowed.')
user = models.OneToOneField(User, related_name =
'profile',on_delete=models.CASCADE)
USN = models.CharField(max_length=50, blank=True, null=True, validators=
[alphanumeric])
year = models.IntegerField(default=0)
sem = models.IntegerField(default=0)
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
if kwargs['created']:
objects=models.Manager()
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender = User)
I have used both the forms in Views.py -
def register(request):
if request.method == 'POST':
form_1 = RegistrationForm(request.POST)
form_2 = UserProfileForm(request.POST)
if form_1.is_valid() and form_2.is_valid():
save_1 = form_1.save(commit = False)
save_2 = form_1.save(commit = False)
save_1.save()
save_2.save()
return render(request,'main/home.html')
else:
form_1 = RegistrationForm()
form_2 = UserProfileForm()
args = {'form_1':form_1,'form_2':form_2}
return render(request, 'account/register.html',args)
The username in the profile model object shows correctly, but other fields are not getting updated. I want other fields also getting updated in the profile object.

Django Admin - 'UserProfile' object has no attribute 'first_name'

I've tried a UserProfile using OneToOneField to extend User in Django which seems to work. Then, I've created a registration view and forms to be able to register new User using UserProfile module.
The problem is that when I've created a User using this form, Django Admin started to raise errors when I click on Users button in Admin page.
EDIT: Probably is worth to say that when I've created a new User, there were some exception that ID is not unique which is probably caused by post_save method in models.
Do you know where is the problem or what should I do?
Here are pieces of my code:
VIEWS.PY
def register(request):
if request.method == 'POST':
user_form = UserForm(request.POST)
profile_form = UserProfileForm(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
return register_success(request)
else:
print user_form.errors, profile_form.errors
else:
user_form = UserForm()
profile_form = UserProfileForm()
return render(request,"auth/registration/register.html",context={'user_form':user_form,'profile_form':profile_form})
FORMS.PY
class ContactUsForm(forms.Form):
contact_name = forms.CharField(required=True)
from_email = forms.EmailField(required=True)
subject = forms.CharField(required=True)
message = forms.CharField(
required=True,
widget=forms.Textarea
)
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('username', 'email', 'password')
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('telephone',)
MODELS.PY
class UserProfile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
# ATRIBUTY KTORE BUDE MAT KAZDY
telephone = models.CharField(max_length=40)
HOW_DO_YOU_KNOW_ABOUT_US_CHOICES = (
('coincidence',u'It was coincidence'),
('relative_or_friends','From my relatives or friends'),
)
how_do_you_know_about_us = models.CharField(max_length=40, choices=HOW_DO_YOU_KNOW_ABOUT_US_CHOICES, null=True)
MARITAL_STATUS_CHOICES = (
('single','Single'),
('married','Married'),
('separated','Separated'),
('divorced','Divorced'),
('widowed','Widowed'),
)
marital_status = models.CharField(max_length=40, choices=MARITAL_STATUS_CHOICES, null=True)
# OD KIAL STE SA O NAS DOZVEDELI
# A STAV
def __unicode__(self):
return '{} {}'.format(self.first_name,self.surname)
def create_profile_user_callback(sender,instance, **kwargs):
profile, new = UserProfile.objects.get_or_create(user=instance)
post_save.connect(create_profile_user_callback, User)
ADMIN.PY
admin.site.register(AdminContact)
class UserProfileInline(admin.StackedInline):
model = UserProfile
can_delete = False
verbose_name_plural = 'User_Profile'
class UserAdmin(BaseUserAdmin):
inlines = (UserProfileInline, )
admin.site.unregister(User)
admin.site.register(User,UserAdmin)
__unicode__ method, in your UserProfile model, it uses self.first_name and self.sur_name, which actually do not exist in this model.
self.user.first_name would be appropriate.
The problem is in your code..
def unicode(self):
return '{} {}'.format(self.first_name,self.surname)
here you call self.first_name,self.surname which in not define in UserProfile
define first_name and surname
like
first_name= models.CharField(max_length=255)
surname= models.CharField(max_length=255)
in your UserProfile class

upload_to doesn't work when updating user profile?

When my users create a profile, their image gets saved fine but when they update it it doesn't get saved. I also don't know how to pull the pic so that they can see it before updating it.
This is the form:
class UpdateProfileForm(forms.ModelForm):
city = models.ForeignKey(City)
class Meta:
model = UserProfile
fields = ('city', 'profilepic')
def save(self, commit=True):
profile = super(UpdateProfileForm, self).save(commit=False)
if commit:
profile.save()
return profile
This is the view:
def updateprofile(request):
if request.method == 'POST':
update_user_form = UpdateUserForm(request.POST, instance=request.user)
update_profile_form = UpdateProfileForm(request.POST, request.FILES, instance=request.user.profile)
if update_user_form.is_valid() and update_profile_form.is_valid():
update_user_form.save()
'''************************************************'''
profile = update_profile_form.save(commit=False)
if 'profilepic' in request.FILES:
profile.profilepic = request.FILES['profilepic']
profile.save()
'''************************************************'''
return HttpResponseRedirect(reverse('index'))
else:
update_user_form = UpdateUserForm(instance=request.user)
update_profile_form = UpdateProfileForm(instance=request.user.profile)
return render(request, 'updateprofile.html', {'update_user_form' : update_user_form, 'update_profile_form' : update_profile_form})
And this is model:
# this is model for user
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile')
hobbies = models.ManyToManyField(Hobby)
languages = models.ManyToManyField(Language)
profilepic = models.ImageField(upload_to='static/images/Profile Pictures', blank=True)
city = models.ForeignKey(City)
slug = models.SlugField(unique=True)
average_rating = models.IntegerField(default=0)
ratings_count = models.IntegerField(default=0)
def save(self, *args, **kwargs):
# Uncomment if you don't want the slug to change every time the name changes
self.slug = slugify(self.user.username)
super(UserProfile, self).save(*args, **kwargs)
def __unicode__(self):
return self.user.username
Thank you.
Add request.FILES to the form:
update_profile_form = UpdateProfileForm(request.POST, request.FILES,
instance=request.user)
By default django doesn't includes files in request.POST
Also, I think instance for UserProfile model should be request.user.profile instead of request.user or am I missing something here?
Follow instructions from django-docs

Categories

Resources