I am trying to block logged in user to access other user update profile page.
My situation:
Suppose Person A is logged in to his profile and he know other user update profile URl. In this situation he can simple getting access of the update profile url of other user.
So , here i want to limit this restriction only to the same logged in user to update their profile only.
this is my code for updating profiles:
#login_required
def UpdateProfile(request, slug):
user = Profile.objects.get(slug=slug)
if request.method == "POST":
form = UpdateProfileForm(request.POST, request.FILES, instance=user)
if form.is_valid():
profile_pic = form.cleaned_data['profile_pic']
form.profile_pic = profile_pic
form.save()
messages.success(request,"Data Updated successfully")
return HttpResponseRedirect(reverse('updateaddress', args=(request.user.profile.slug,)))
else:
messages.error(request, "Please check all fields are valid")
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
else:
form = UpdateProfileForm(instance=user)
context = {
'user':user,
'form':form,
}
return render(request, "authentication/register/update/profile.html",context)
urls.py
path("<slug:slug>/update-profile/", UpdateProfile, name="updateprofile"),
You can just do like this:
#login_required
def UpdateProfile(request, slug):
user = Profile.objects.get(slug=slug)
if user.id == request.user.id:
# do something if the id of user you get from the slug matches the actual user id
if request.method == "POST":
form = UpdateProfileForm(request.POST, request.FILES, instance=user)
if form.is_valid():
# yada yada yada
You can compare the user object like below
#login_required
def UpdateProfile(request, slug):
user = Profile.objects.get(slug=slug)
if user != request.user:
message.info("You can't update the other user profile")
return
As described here in django documents :-
https://docs.djangoproject.com/en/4.0/topics/db/queries/#comparing-objects
You can try something like this in as a decorator
def verify_user_profile(view_func):
def wrapper_func(request, *args, **Kwargs):
user = Profile.objects.get(slug=args[0])
if user != request.user:
return
else:
return view_func(request, *args, **Kwargs)
return wrapper_func
View call will be :-
#verify_user_profile
#login_required
def UpdateProfile(request, slug):
...
...
Related
forms.py
class UserForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ('username','email','password1','password2')
def save(self,commit=True):
user = super(UserForm,self).save(commit=False)
user.set_password = self.cleaned_data['password1']
user.email = self.cleaned_data['email']
if commit:
user.save()
views.py
def register_view(request):
form = UserForm()
if request.method == 'POST':
form = UserForm(request.POST)
if form.is_valid():
user = form.save()
customer_group = Group.objects.filter(name='CUSTOMER').exists()
if customer_group:
Group.objects.get(name='CUSTOMER').user_set.add(user)
else:
Group.objects.create(name='CUSTOMER')
Group.objects.get(name='CUSTOMER').user_set.add(user)
messages.success(request,'註冊成功! 請按指示登入!')
return redirect('login')
else:
messages.error(request,'註冊無效! 請再試過!')
context = {'form':form}
return render(request,'customer/register.html',context)
When I try to register a new user, the form can be successfully saved and the group CUSTOMER can be added but I have a problem if I want to add that user to the group so are there any methods in order to add the user to the group automatically after that user had registered a new account along with the User model?
As #Iain Shelvington says, the form.save() method should return the user object. But there is no need to override the save() method: the UserCreationForm already does that.
class UserForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ('username','email')
# no save method
In the view you can simplify the logic to:
def register_view(request):
form = UserForm()
if request.method == 'POST':
form = UserForm(request.POST)
if form.is_valid():
user = form.save()
customer_group, __ = Group.objects.get_or_create(name='CUSTOMER')
customer_group.user_set.add(user)
messages.success(request,'註冊成功! 請按指示登入!')
return redirect('login')
else:
messages.error(request,'註冊無效! 請再試過!')
context = {'form':form}
return render(request,'customer/register.html',context)
here is my view.py
from models import Balance
def profile(request):
user = Balance.objects.get(user=request.user)
return render(request,'profile.html',{"balance":user.balance})
and created model here
class Balance(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
balance = models.IntegerField(default=0)
def __str__(self):
return self.user.username
here is my registration and i think i have made mistake here:
#unauthenticated_user
def register(request):
form = CreateUser()
if request.method == 'POST':
form = CreateUser(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
instance = Balance(user=request.user, balance=0)
instance.save()
messages.success(request, "Congrats !!" + username + "now you are member of the society")
return redirect('login')
context = {'form': form}
return render(request, "register.html", context)
I am able fetch the balance of the user in from the database at the time of showing the profile but not able save it into database while registration. As erorr returns:
ValueError at /register/
Cannot assign "<SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x7f98c64caa60>>": "Balance.user" must be a "User" instance
Your user is not signed in when you write this line:
instance = Balance(user=request.user, balance=0)
I assume your form CreateUser works properly. when a form is saved it returns the created instance so you can use it instead of request.user:
user = form.save()
instance = Balance(user=user, balance=0)
instance.save()
how can i use is_valid() with POST method to get inputs from user
my views.py i also use return redirect() and HttpResponseRedirect() but it doesn't work
#login_required
def about(request):
data= userdata.objects.all()
form=student(request.POST)
if request.method =='POST' or 'GET':
if form.is_valid():
name = request.POST.get('name')
email= request.POST.get('email')
password =request.POST.get('password')
fm = userdata(name=name,email=email,password=password)
fm.save()
form =student()
else:
form=student()
return render(request,'about.html',{'form':form ,'data':data})
try the code below
#login_required
def about(request):
# i think you don't need 'data' and thus pass it in the context with 'form'
# data= userdata.objects.all()
if request.method =='POST': # POST request
form=student(request.POST)
if form.is_valid():
name = request.POST.get('name')
email= request.POST.get('email')
password = request.POST.get('password')
fm = userdata(name=name,email=email,password=password)
fm.save()
# Add flash message and then redirect
messages.success(request, 'SUCCESS !')
return redirect(reverse_lazy('home'))
else:
messages.error(request, 'Please correct the errors below.')
# if 'form.is_valid()' return false you will get all errors in 'form.errors' bag
else: # GET request
form=student()
return render(request,'about.html',{'form':form})
refer to :
https://docs.djangoproject.com/fr/3.1/topics/forms/#the-view
https://www.django-antipatterns.com/antipatterns/rendering_content_after_a_successful_post_request.html
I want to restrict users to access the payment and checkout pages by typing the url in address bar like "home/shop/checkout/" and "home/shop/payment/"
I want to make these pages accessible only if either buy_now form is valid or items_buy_now form is valid
urls.py
path('payment/',views.payment,name='payment'),
path('checkout/', views.checkout, name="checkout"),
views.py
def checkout(request):
request.session.pop('data', None)
messages.success(request,'Done.Thanks for using our services.')
return redirect("shop:mycart")
def payment(request):
return render(request,'shop/payment.html')
def buy_now(request,slug):
if not request.user.is_authenticated:
messages.info(request, 'You have to logged in first.')
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
product = Product.objects.get(active=True, slug=slug)
if request.method == "POST":
form = BuyerDeliveryForm(request.POST)
if form.is_valid():
buyer = form.save(commit=False)
buyer.save()
return redirect('shop:payment')
else:
form = BuyerDeliveryForm()
return render(request, 'shop/delivery_form.html', {'form': form, 'products': product})
def items_buy_now(request):
if not request.user.is_authenticated:
messages.info(request, 'You have to logged in first.')
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
if request.method == "POST":
form = BuyerDeliveryForm(request.POST)
if form.is_valid():
buyer = form.save(commit=False)
buyer.save()
return redirect('shop:payment')
else:
form = BuyerDeliveryForm()
return render(request, 'shop/delivery_form.html', {'form': form})
The best way to do it is to :
Create a Mixin that manager either items_buy or items_buy
For all the views that have to handle the restriction, subclass it from the respective mixin.
In the get function of the subclass call the method to check if the user has the authorization to access to that page.
I'm trying to display a simple ModelForm for a user's profile and allow the user to update it. The problem here is that my logic is somehow flawed, and after a successful form.save() call, the old values show on the page. It isn't until a refresh that the appropriate value is shown. What is wrong here?
#login_required
def user_profile(request):
success = False
user = User.objects.get(pk=request.user.id)
upform = UserProfileForm(instance=user.get_profile())
if request.method == 'POST':
userprofile = UserProfileForm(request.POST, instance=user.get_profile())
if userprofile.is_valid():
up = userprofile.save(commit=False)
up.user = request.user
up.save()
success = True
return render_to_response('profile/index.html',
locals(), context_instance=RequestContext(request))
I'm just looking to update an existing profile, not add a new one.
Try this:
#login_required
def user_profile(request):
success = False
user = User.objects.get(pk=request.user.id)
if request.method == 'POST':
upform = UserProfileForm(request.POST, instance=user.get_profile())
if upform.is_valid():
up = upform.save(commit=False)
up.user = request.user
up.save()
success = True
else:
upform = UserProfileForm(instance=user.get_profile())
return render_to_response('profile/index.html',
locals(), context_instance=RequestContext(request))
You could also use a generic view:
from django.views.generic.create_update import update_object
#login_required
def user_profile(request):
return update_object(request,
form_class=UserProfileForm,
object_id=request.user.get_profile().id,
template_name='profile/index.html')