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.
Related
how do I not save the form data until the transaction is done which is in a different URL, if the shipping form and the payment options were to be in the same URL then there wouldn't be this problem but it's not so how do I go about this? thx!
views.py
def checkout(request):
if request.method == 'POST':
form = ShippingForm(request.POST)
if form.is_valid():
new_shipping = form.save(commit=False)
new_shipping.customer = customer
new_shipping.order = order
#how do I not save the data until the transaction is successful
new_shipping.save()
return redirect('store:checkout_shipping')
else:
form = ShippingForm()
else:
form = ShippingForm()
context = {"form": form}
return render(request, 'shop/checkout.html', context)
def checkout_payment(request):
return render(request, 'shop/checkout_payment.html', context)
urls.py
path('checkout', views.checkout, name="checkout"),
path('checkout_payment', views.checkout_payment, name="checkout_payment"),
forms.py
class ShippingForm(forms.ModelForm):
address_one = forms.CharField(max_length=200)
address_two = forms.CharField(max_length=200)
I think what might help is to use sessions. Django will store this temporary data using session cookies. Here's the idea:
from django.forms.models import model_to_dict
def checkout(request):
form = ShippingForm(request.POST or None)
if form.is_valid():
new_shipping = form.save(commit=False)
new_shipping.customer = customer
new_shipping.order = order
request.session['partial-data'] = model_to_dict(new_shipping)
return redirect('store:checkout_shipping')
context = {"form": form}
return render(request, 'shop/checkout.html', context)
def checkout_payment(request):
# I'm guessing here is where the rest of the data
# is to be filled in. The data of the previous view
# is already here stored in the cookie
full-form-data = request.session['partial-data']
full-form-data['extra-field-1'] = 'something'
full-form-data['extra-field-2'} = 'something else'
form = ShippingForm(full-form-data or None)
if form.is_valid():
form.save()
context = {
'form': form
}
return render(request, 'shop/checkout_payment.html', context)
i'm writing the logic in django where a newly created user would automatically get the free membership when they hit the signup button and i have tried diffrent solutions to fix this
views.py
def register(request):
reviews = Review.objects.filter(status='published')
info = Announcements.objects.all()
categories = Category.objects.all()
if request.method == "POST":
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
obj = request.user
get_membership = Membership.objects.get(membership_type='Free')
# error is showing "instance" is not access using visual studio code
instance = UserMembership.objects.create(user=obj, membership=get_membership)
messages.success(request, f'Account Successfully created for {username}! You can Login In Now')
return redirect('userauths:login')
elif request.user.is_authenticated:
return redirect('elements:home')
else:
form = UserRegisterForm()
context = {
'reviews': reviews,
'form': form,
'info': info,
'categories': categories
}
return render(request, 'userauths/register.html', context)
indentation error here:
elif request.user.is_authenticated:
return redirect('elements:home')
else:
form = UserRegisterForm()
You only need to tab once. Not twice.
elif request.user.is_authenticated:
return redirect('elements:home')
else:
form = UserRegisterForm()
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):
...
...
I have a problem in registration with django, here is my views code:
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
form = RegistrationForm()
args = {'form': form}
return render(request, 'users/reg_form.html', args)
,but i always get:
ValueError at /user/register/ The view Users.views.register didn't
return an HttpResponse object. It returned None instead. Request
Method: POST Request URL: http://127.0.0.1:3001/user/register/ Django
Version: 2.0.2 Exception Type: ValueError Exception Value: The view
Users.views.register didn't return an HttpResponse object. It returned
None instead. Exception
Location: /home/iah/.local/lib/python3.5/site-packages/django/core/handlers/base.py
in _get_response, line 139
Check you code and ask yourself what happens if you have a POST request and the form doesn't validate - you'll find out that in this case you have no explicit return path, so the function implicitely returns None.
The fix is dead simple : deindent the last two line of your function, so you when the form doesn't validate you return the rendered template too:
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
form = RegistrationForm()
# MAKE SURE WE ALWAYS RETURN A RESPONSE:
# we end up here when it's a GET request
# AND when it's a POST request and the form
# did not validate
args = {'form': form}
return render(request, 'users/reg_form.html', args)
You have to return response from the inner else block:
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
# here
...
Make sure you return something if the form is not valid and your form.is_valid() fails.
Example:
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
return redirect('/') # or render(...)/whatever you need to redirect to
else:
form = RegistrationForm()
args = {'form': form}
return render(request, 'users/reg_form.html', args)
Hope this helps!
You are missing the else code. Your if statement says: If the form is valid, save the form. But what if the form is not valid, What if the username is all special characters(ex: !##$%%%^^) or what if the username is only 1 Character long ex: (username:A). Or what if the password is only 3 characters long (ex: pas) In all these scenarios, the user should get the blank form back. You should also consider using class based views for registration This link will help
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
**if form.is_valid():**
# What if the form is not valid you haven't accounted for that
form.save()
return redirect('/')
else:
# Adding a else solves this problem. The user gets a blank form back
form = RegistrationForm()
args = {'form': form}
return render(request, 'users/reg_form.html', args)**
I'm reading the documentation on how to display a message to the user with Django messages. It says that in order to add a message in your views to call:
from django.contrib import messages
messages.add_message(request, messages.INFO, 'Hello world.')
I'm not sure where to put the second the second line, this is my view:
def sign_up(request):
if request.method == "POST":
form = IdForm(request.POST)
if form.is_valid():
post = form.save()
post.save()
ID = post.id_text
return HttpResponse('Thank you')
else:
return HttpResponse('That text is invalid')
else:
form = IdForm()
return render(request, 'checkin/base.html', {'form': form})
I want the message to appear and thank the user for signing up and display their input as well.
Bearing, in mind that it's customary to redirect to a success url on valid form submission, your code ought to look like this:
def sign_up(request):
if request.method == "POST":
form = IdForm(request.POST)
if form.is_valid():
post = form.save()
post.save()
ID = post.id_text
messages.add_message(request, messages.INFO, 'Hello world.')
return HttpResponseRedirect('/thank-you-page/')
else:
form = IdForm()
return render(request, 'checkin/base.html', {'form': form})
note that this also results in the user being told why exactly his form is invalid (assuming that you have set up the template propertly). It's always good to say what the problem is rather than to say there is a problem.
You can put the second line in view with example:
def contact(request):
if request.method == 'POST':
name = request.POST.get('name')
email = request.POST.get('email')
password = request.POST.get('password')
textarea = request.POST.get('textarea')
contact = Contact(name = name,email = email,password = password,textarea = textarea,date=datetime.today())
contact.save()
messages.success(request, 'Form has submitted')
return render(request,"contact.html")