Django - perform action on Profile while creating User - python

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)

Related

How to redirect user from registration page to profile if user is already registered?

I am using Django class-based views for my project and trying to redirect user from registration view if he is already authenticated. I've done it already with LoginView and it was pretty simple and looked just like adding few lines of code:
class Login(LoginView):
authentication_form = CustomAuthenticationForm
redirect_authenticated_user = True
LOGIN_REDIRECT_URL = "core:profile"
So after going to url for login, user ends up at his profile url. Absolutely simple and works perfectly.
However, there is no CBV for registration and therefore CreateView should be used, which doesn`t have any attributes for checking if user is authenticated.
The one method of doing something similar is UserPassesTestMixin, but it only gives me 403 Forbidden if user is authenticated, not redirect.
Here is my current registration view:
class Registration(UserPassesTestMixin, CreateView):
form_class = RegistrationForm
template_name = "registration/user_form.html"
success_url = reverse_lazy("core:profile")
def test_func(self):
return self.request.user.is_anonymous
def form_valid(self, form):
print(self.kwargs)
self.object = form.save(commit=True)
self.object.is_active = True
self.object.save()
login(self.request, self.object, backend="core.auth_backend.AuthBackend")
return HttpResponseRedirect(self.success_url)
Maybe somebody have done it already?
Would be very grateful for every advice!
In your Registration class, add a get method and remove your test_func:
def get(self,request,*args,**kwargs):
if self.request.user.is_authenticated:
return HttpResponseRedirect('redirect_url')
return super().get(request,*args,**kwargs)

How to attach current logged in user to object when object is created from django admin

I'm working on website whose an app which has class called Members whose a field that is related to the builtin User class from django.contrib.auth.models and it looks like
class Members(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
member_image = models.ImageField(upload_to='unknown')
member_position = models.CharField(max_length=255)
...
So as you can see when I'm adding member_image as a user I have also to select the user which doesn't make sense to me because I want to detect which user is logged in and pass his/her id as default parameter
like
class Members(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, default=request.user.id)
and after remove the user field in the admin panel like
class MembersAdmin(admin.ModelAdmin):
fields = ('member_image', 'member_position', ...)
so that if the user field doesn't selected it will set the logged in user_id by default
but to access request out of the views.py is not possible.
so how will I achieve this I also tried the following answers
Access session / request information outside of views in Django
Accessing request.user outside views.py
Django: How can I get the logged user outside of view request?, etc
but still not get it
Modify MembersAdmin save_model method and attach request.user to the object prior to saving.
class MembersAdmin(admin.ModelAdmin):
fields = ('member_image', 'member_position', ...)
def save_model(self, request, obj, form, change):
obj.user = request.user
super().save_model(request, obj, form, change)
For exclude the current logged in User for particular page or view, You can try this :-
from django.contrib.auth import get_user_model
User = user_model()
def some_view(request):
exclude_current_user = User.objects.exclude(user=request.user)

Django : Can I use CreateView to create a User object where User is just Django's built in User model?

I am trying to create a simple user login system where a user gets to sign up on one page and then use those credentials to login to the website on another page. Here's my sign-up and login views:
class SignupView(CreateView):
model = User
form_class = SignupForm
template_name = 'journal_app/signup.html'
success_url = reverse_lazy('home')
class LoginUserView(LoginView):
template_name = 'journal_app/login.html'
As you can see I'm using the CreateView to create User objects. After the user signs up I can see that the record is successfully updated in the Users group in my Admin console. The problem is that when I try to login, it always throws me a username/password don't match error. Any ideas what could be the reason? I am a beginner at Django so it could be something pretty simple.
SignupForm-
class SignupForm(forms.ModelForm):
class Meta:
model = User
fields = ['first_name', 'username', 'password']
widgets = {
'password': forms.PasswordInput()
}
The problem is that you need to hash the password. Django stores a hash of the password [Django-doc]. If you make a custom user model, you should normally implement a UserManager [Django-doc] as well. This takes a password, and will hash it, for examply by calling a method .set_password(…) [Django-doc]. This method will then hash the password.
You thus can rewrite the form to save the user with:
class SignupForm(forms.ModelForm):
class Meta:
model = User
fields = ['first_name', 'username', 'password']
widgets = {
'password': forms.PasswordInput()
}
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data['password'])
if commit:
user.save()
return user

Update data in profiles model,using extended django User model

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

Save filled form data in Django if user is not logged in?

I search Django-way to do some non tipical feature (I think). My env is Django 2.0.2, PostgreSQL 9.6 and Python 3.6.4. So, I have model and form like:
# ./app/models.py
from users.models import User # custom user model
class SubscribeModel(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
phone = models.CharField(max_length=80)
# ./app/forms.py
class SubscribeForm(forms.Form):
phone = forms.EmailField(label='Phone Number', max_length=100)
Also, my view for this model like:
# ./app/views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from users.models import User
class SubscribeView(LoginRequiredMixin, View):
login_url = '/login/'
redirect_field_name = 'redirect_to'
template_name = 'app/subscribe.html'
form_class = SubscribeForm
def post(self, request):
user = get_object_or_404(User, id=request.user.id)
form = self.form_class(request.POST, instance=user)
if form.is_valid():
form.save()
return redirect('/')
return render(request, self.template_name, {'client': user, 'form': form})
Would be great to understand what to do that logic after save form:
Anonymous user fill the form and click Save;
He is redirecting to login page (because LoginRequiredMixin);
After enter to the site, all data which he filled — saved to his account (automatically).
This feature we can see when online shopping: we choose goods, add to
our cart and only later, site ask us for login to site, if we are not (for save our order).
I think, my question solve saving data to request.session and re-save to DB after logged in, but I have no idea how to do that on my code and is this correctly? I am newbie in Django... yet!
Actually using request.session to store the data without saving it to the database is one approach, you can eighter save it to the localStorage or sessionStorage if you are developing mainly javascript AJAX frontent. But if you render every view with django then is using request.session better for you. Consider storing ids of the objects in the request.session in array and then use it as you want, remember to seralize it to JSON (json.dumps(list of ids)) before assigning it to the request.session.

Categories

Resources