Reputation: 66
Lets say I have
.decs
def unwelcome_user(unwelcome_roles=[]):
def decorator(view_func):
def wrapper_func(request, *args, **kwargs):
if request.user.is_authenticated:
for group in request.user.groups.all():
if group.name in unwelcome_roles:
return redirect('main:unwelcome-user-type',
user_type=group.name)
else:
return view_func(request, *args, **kwargs)
else:
return view_func(request, *args, **kwargs)
return wrapper_func
return decorator
.urls
urlpatterns = [
path('error-unwelcome/<str:user_type>', views.unwelcome_user, name='success')
]
.views
@unwelcome_user(unwelcome_roles=['xyz'])
def success(request)
return render(request, 'success_page.html', {})
def unwelcome_user(request, user_type):
return render(request, 'errors/unwelcome_user.html', {})
I can access the unwelcome_user view directly by typing something like mysite.com/error-unwelcome/xyz in the browser even without going through the subsequent process that should result in showing that page. How do I prevent that?
Upvotes: 0
Views: 2375
Reputation: 66
I'm still new to Django so I couldn't try out the cookie/sessions answers given (I still have to learn sessions). In the meantime, here's what I'm using:
def get_referer(request):
referer = request.META.get('HTTP_REFERER')
if not referer:
return None
return referer
then in any view
def my_view(request):
if not get_referer(request):
raise Http404
return render(request, 'sample.html', {})
Here I'm assuming that if there's no referer, then it means the person typed in the URL into the browser.
Upvotes: 2
Reputation: 21812
You can try using sessions [Django docs]. If you are redirecting a user to the page, before redirecting just add a variable to the session indicating that they can access the view.
So just before the redirect:
request.session['is_unwelcome'] = True
return redirect('main:unwelcome-user-type', user_type=group.name)
In the view you would simply check whether the variable is present in the session:
def unwelcome_user(request, user_type):
if 'is_unwelcome' not in request.session:
# Redirect or raise Http 404?
# return redirect('somewhere')
# raise Http404()
del request.session['is_unwelcome']
return render(request, 'errors/unwelcome_user.html', {})
Upvotes: 0
Reputation: 6565
Give this a try
The process_page will only render success.html if your_subsequent_process()
returns a True
, otherwise, the process.html will be rendered.
def proces_page(request):
"""Your Process View"""
if your_subsequent_process():
return render(request, 'success.html', {})
return render(request, 'proces.html', {})
Upvotes: 0
Reputation: 85
If the page is part of a chain of pages for the user to navigate, you will need to pass some state when moving from one page to the next. You can either use a cookie and check the value of the cookie in the view, or pass a GET query parameter:
def success(request):
token = request.GET.get('token', None)
if token is None or not Token.objects.filter(value=token).exists():
return redirect(...) # previous step or beginning
return render(...) # page
Previous pages should create this token. Then pass it in the URL:
/success/?token=<token>
Upvotes: 0