Django:How to return nowhere? - python

(sorry for my bad english)
hello mans.i have a such view in django:
if request.user.is_authenticated:
favelan = get_object_or_404(elan,id = id)
isfav = True
if favelan.favorit.filter(id = request.user.id).exists():
favelan.favorit.remove(request.user)
messages.success(request,'Elan Uluzlulardan Silindi!')
isfav = False
return redirect("/",{'isfav':isfav})
else:
favelan.favorit.add(request.user)
messages.success(request,'Elan Uluzlulara Elave Olundu!')
isfav = True
return redirect("/",{'isfav':isfav})
return redirect('/hesablar/qeydiyyat')
i want this view redirect user nowhere.how i do this?i tried:
reqabspath = request.path
return redirect(reqabspath,{'isfav':isfav})
but its not working.i want redirect user nowhere.please help me.thanks now.

You can use render
from django.shortcuts import render
...
return render(request, 'yourTemplate.html', {'isfav': isfav})

You can redirect to the page on which user was before sending request with return HttpResponseRedirect(request.META['HTTP_REFERER']). So user will stay on same page after request.
from django.http import HttpResponseRedirect
def your_function(self, request):
...
return HttpResponseRedirect(request.META['HTTP_REFERER'])
META['HTTP_REFERER'] stores url of referring page, if any. So you just redirect to it. But be aware, this header is not required, so it would be better to use some default_url, in case browser won't send HTTP_REFERER header. It could be handled like this:
return HttpResponseRedirect(request.META.get('HTTP_REFERER', YOUR_DEFAULT_URL))
So it will redirect to HTTP_REFERER if it exist, and if not, it'll redirect to YOUR_DEFAULT_URL

Related

How to redirect to page where request came from in Django

I currently work on a project an i want to redirect to page where request is came form, when request method is GET.
this is my views.py file
Views.py
def delete_patient(request):
if request.method == 'POST':
patient_id = request.POST['patient_id']
rem = Patient.objects.get(pk=patient_id)
rem2 = CustomUser.objects.get(aid=patient_id, role=4)
rem.delete()
rem2.delete()
return JsonResponse({'delete': 1})
else:
// //
so please tell me what I want to write in else part of view.
Typically for that, the server responds with a 405 method not allowed. Especially since it is not even said that the request "comes from somewhere". For example one can make such request with curl, wget, etc. You can work with a #require_POST decorator [Django-doc] for example to return a 405 in case the method is something else than a POST (GET, PUT, PATCH, etc.):
from django.views.decorators.http import require_POST
#require_POST
def delete_patient(request):
patient_id = request.POST['patient_id']
rem = Patient.objects.get(pk=patient_id)
rem2 = CustomUser.objects.get(aid=patient_id, role=4)
rem.delete()
rem2.delete()
return JsonResponse({'delete': 1})
If you really want to redirect to the referring page, you can try to access the HTTP_REFERER key from the request.META dictionary. But not all browsers per se send the referring page, and it is not even said that the request comes from a web client in the first place.
You thus can work with:
from django.http import HttpResponseNotAllowed, HttpResponseRedirect
def delete_patient(request):
if request.method == 'POST':
patient_id = request.POST['patient_id']
rem = Patient.objects.get(pk=patient_id)
rem2 = CustomUser.objects.get(aid=patient_id, role=4)
rem.delete()
rem2.delete()
return JsonResponse({'delete': 1})
elif 'HTTP_REFERER' in request.META:
return HttpResponseRedirect(request.META['HTTP_REFERER'])
else:
return HttpResponseNotAllowed(['POST'])

Django Views, having 2 redirects in 1 view

Is it possible to have 2 redirect() in the same django view. so when the like button is in the home page, i want it to redirect back to home page, if like button is in detail page, i want to redirect back to detail page?
For instance:
def LikeView(request, slug):
context = {}
post = get_object_or_404(BlogPost, slug=slug)
post.likes.add(request.user)
if in homepage:
return redirect('HomeFeed:detail', slug=slug)
else:
return redirect('HomeFeed:main')
def delete_blog_view(request,slug):
context = {}
user = request.user
#YOU WANT to check if user is authenticated. if not, you need to authenticate! redirect you to that page
if not user.is_authenticated:
return redirect("must_authenticate")
account = Account.objects.get(pk=user_id)
blog_post = get_object_or_404(BlogPost, slug=slug)
blog_post.delete()
return redirect(request.META.get('HTTP_REFERER', 'account:view', kwargs={'user_id': account.pk }))
Pass the redirect URL in a next URL param. Like so:
<!-- In homepage template -->
Like
<!-- in Detail template -->
Like
or simply:
Like
To always pass the current URL as the redirect URL.
And then in your LikeView:
def LikeView(request, slug):
...
next = request.GET.get("next", None)
if next and next != '':
return HttpResponseRedirect(redirect_to=next)
# Then have a default redirect URL in case `next` wasn't passed in URL (Home for Example):
return HttpResponseRedirect(redirect_to="/home")
As mentioned in the Django Docs, this isn't safe (for most apps), so you have to check if URL is safe then redirect to next otherwise just return a default safe in-app URL.
Read on the url_has_allowed_host_and_scheme function to check if URL is safe on this Docs page

How to redirect to the same page after an action in django

I have this function add_to_cart once a product is added to cart it should redirect to the same.( since the the answers have not solved the issue ).
I have changed at least should redirect to product detail page requires to pass an argument either slug or product id any idea
def add_to_cart(request, **kwargs):
------------------------
------------------------
messages.info(request, "item added to cart")
return redirect(reverse('products:single_product',args=(request)))
url for product detail
url(r'^(?P<slug>.*)/$',single, name="single_product"),
You can do:
return HttpResponseRedirect(request.path_info)
You can also read about how Request/Response works in Django but also about the request.path_info in the docs
You can use request.path to find the current url of the request and then redirect.
from django.shortcuts import redirect
return redirect(request.path)
Send the address where you are calling from in kwargs and redirect to that.
HttpRequest
from django.http import HttpResponseRedirect
return HttpResponseRedirect(request.path_info)
Use "request.path" to get the current url as shown below:
# "views.py"
from django.shortcuts import redirect
def my_view(request):
return redirect(request.path) # Here
Or, use "request.path_info" to get the current url as shown below:
# "views.py"
from django.shortcuts import redirect
def my_view(request):
return redirect(request.path_info) # Here

Django - being able to access page only after HttpResponseRedirect

I have a class based view in which I process the form and redirect the user on successful submission like so:
views.py
def get(self,request):
form = self.form_class()
return render(request, template_name, { 'form' : form })
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
...
return HttpResponseRedirect(reverse('success'))
return render(request, template_name, { 'form' : form })
urls.py
...
url(r'^submit/success', SubmitView.as_view(), name='success'),
...
It is possible to access url directly by typing success/submit. I don't use any authentication on the site and want the user only be able to access the submit/success page after redirection, so that they are not able to access it directly. How do I do it?
If you are using sessions, you can accomplish it like so:
# in the view where form is submitted
if form.is_valid():
request.session['form-submitted'] = True
return HttpResponseRedirect(reverse('success'))
# in the success view
def get(self, request):
if not request.session.get('form-submitted', False):
# handle case where form was not submitted
else:
# render the template
Instead of redirecting, you could POST to the 'success' page.
Then use if request.method == 'POST':
But beware, this is NOT secure, as headers can be spoofed.
Better to just call the success view from within the POST method, I think.
Have you tried something like this:
if form.is_valid():
...
return HttpResponseRedirect(SubmitView.as_view())
Not sure if this works out of the box, but with a few more tricks you might get what you want.
To add to the answer #miki725 posted I would also make sure you change
request.session['form-submitted'] = False
after you have entered the
if not request.session.get('form-submitted', False):
In order to prevent accessing the page directly or using the back and forward on the browser.

Creating a fake request to render a view to a string in django

Problem
I'd like to render an arbitrary view, by calling the view (capture the response and extract the rendered content), to a string, inside another view.
The problem being I'd like to have a dummy user "logged-in" during the rendering of that view, along with changing a few other minor things in the request.
What I'd like to avoid is building a request completely from scratch, as 90% of the request I'll have at hand in the parent view will be the same.
I'm wondering how I should go about this as far as best practice is concerned, as well as technically?
I'm currently thinking something like this: (But I can't help but feel this is horrible and there's got to be a better way, I just cannot think of it)
View stuff...
Log current user out
Create/Login dummy user
Somehow modify request a bit
Render view to string
Log out dummy user
Log back in original user
End of view stuff...
Any ideas? Or a pointer into a better direction?
Thanks,
dennmat
Depending upon how much you're relying on getting information from the request during the view, it might be best that you just create a function to do all of the view's dirty work, and have your real view just pass in the values it needs into this function. So, instead of a view function that takes a request, create another function that takes a user:
def _real_view(user):
return render_to_response('template.html', {'user' : user})
def view(request):
# Now both of these are possible...
response = _real_view(User.objects.get(5))
response = _real_view(request.user)
return response
Then, when you want to a view using a different user, you only need to grab the information for that user and pass it into the view. No need to change the current user or modify the request at all.
You don't actually need to log the current user out, you could just change the user in the HttpRequest object you plan to use to render the other view. You could do something like this:
from django.contrib.auth.models import User
from django.http import HttpResponse
def view_inside_a_view(request):
return HttpResponse('hello %s' % request.user)
def view(request):
# change to dummy user, or whoever
request.user = User.objects.get(id=1)
response = view_inside_a_view(request)
return HttpResponse('rendered view: %s' % response.content)
If you need to login your dummy user you could use django.contrib.auth.authenticate or or django.contrib.auth.login to do so. Example using login (avoids necessity of using dummy user's password):
from django.contrib.auth.models import User
from django.contrib.auth import login, get_backends
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
#login_required
def view_inside_a_view(request):
return HttpResponse('hello %s' % request.user)
def view(request):
# login dummy user
user = User.objects.get(id=2)
backend = get_backends()[0]
user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
login(request, user)
# change request's user
request.user = user
# get response from view
response = view_inside_a_view(request)
return HttpResponse('rendered view: %s' % response.content)
just use the test client - it's not only good for testing:
from django.test import Client
c = Client()
# login if necessary
c.login(username='dummy', password='user')
# get the view
response = c.get(reverse('my-view', args=[foo,bar])
html = response.content
Since 1.6 this is even officially documented, however it works in older versions too: https://docs.djangoproject.com/en/1.6/topics/testing/tools/#module-django.test.client

Categories

Resources