I have a book page. On this page is the button "In favorite". If the user clicks on the button and is authenticated, it will use addBookmark view to add a new object into the database(and just reload the book page). However, if the user isn't authenticated, it'll redirect to the login page firstly.
#login_required
def addBookmark(request, slug):
book = Book.objects.get(slug=slug)
if BookMark.objects.filter(user=request.user, book=book).exists():
bookMark = BookMark.objects.get(user=request.user, book=book)
bookMark.delete()
return HttpResponseRedirect(request.META.get("HTTP_REFERER"))
newBookMark = BookMark.objects.create(user=request.user, book=book)
newBookMark.save()
return HttpResponseRedirect(request.META.get("HTTP_REFERER"))
The problem: When a user is redirected to the login page, the next URL will just add a new object in db and reload the page, but this is the login page. How can I redirect users back to the book page if the user isn't authenticated firstly?
Firstly, remove #login_required.
You can redirect user manually like this:
if not request.user.is_authenticated:
return redirect("bookmark_url")
Related
This is my first web development project. It is basically an e-voting website. The index page is the login page. So, when the user login using valid credentials, the website will take the user to the voting page where that contains a voting form and some other options like feedback, news updates, etc. in the Navigation bar. The login request is "POST". The vote submission request is also "POST". Here, if the user presses other option like submitting feedback or viewing the candidates, will take the user to that respective pages. And if the user presses the back button, the website should take him to the voting page again where he can again use other facilities voting, viewing candidates, or submit feedback. But the problem I face is if the user presses the back button from the 3rd page i.e., feedback page or viewing candidates page, it shows an error "Confirm Form Resubmission". Help me fix this bug. Thank You in advance.
views.py
from django.shortcuts import render,redirect
from django.contrib.auth.models import User, auth
from django.contrib import messages
from .models import voteoption,receive,received_feedback,updates
# Create your views here.
def index(request):
return render(request,"index.html")
def login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username,password=password)
if user is not None:
auth.login(request, user)
cand = voteoption.objects.all()
return render(request,"votepage.html", {'candidates': cand})
else:
messages.info(request,'Invalid Email or Password')
return render(request,'index.html')
else:
return render(request,'index.html')
def logout(request):
auth.logout(request)
return redirect("/")
def update(request):
news = updates.objects.all()
return render(request,'updates.html', {'upd': news})
def contact(request):
return render(request,'contact.html')
def feedback(request):
return render(request,'feedback.html')
def feedbacksubmit(request):
feedback = request.POST['feedback']
data = received_feedback(response=feedback)
data.save()
messages.info(request,'Feedback Submitted Successfully')
return render(request,'submitted.html')
def candidates(request):
cand = voteoption.objects.all()
return render(request,'candidates.html',{'candidates': cand} )
def submitvote(request):
reg_no = request.POST['reg_no']
selection = request.POST['selection']
voter = request.POST['voter']
if receive.objects.filter(mail=voter).exists():
messages.info(request,'You have already Voted')
return render(request,'submitted.html')
else:
data = receive(reg_no=reg_no,selection=selection,mail=voter)
data.save()
messages.info(request,'You have voted Successfully. Thank You!')
return render(request,'submitted.html')
What changes should I make?
Since this is my first project, there might be a lot of poor coding techniques. So, please suggest me with better codes where I should replace in my code even though if it is not related to this bug.
You will want to handle successful form submissions with the Post/Redirect/Get pattern to prevent the back button from returning to the previous post. In your Django project this is done by returning a redirect from the view instead of an HttpResponse. Redirect docs
from django.shortcuts import redirect
def view_function(request, ...):
... # code processing the POST
if post_request_successful:
return redirect(path)
else:
return HttpResponse(...) # or render(...) or whatever you usually return
Where path is a url. Most likely you want to either use the same path in the request request.path or get a path by reversing a url name from your urls.py file (from django.shortcuts import reverse). Reverse docs
I am using the Django-two-factor-auth library for my sites login. Everything is working fine, however when I try to login and redirect a new user to their profile page after sign up using login(request, user) I keep getting redirected to the login page.
The login works fine when the user re-enters their new login credentials however I want to redirect the user straight to their profile page after signup instead.
I am aware Django-two-factor-auth overides Django's built in authentication (Django.contrib.auth), however I am unsure why the login() function is not marking the user as authenticated.
views.py
from django.contrib.auth import login
def signup(request):
...
user = signup_form.save()
login(request, user)
return redirect('/profile')
You can add that to your settings:
LOGIN_REDIRECT_URL = 'yourUrl' # this is the name of the url
Resolved. Turns out the 'is_active' field of the newly created user was being modified by a model signal elsewhere in my code resulting in the user being redirected to the login page.
My form resubmits every time I refresh the page. I want to send context with my render
if request.method == 'POST' and 'search_form' in request.POST:
rol = request.POST['rol']
group = request.POST['group']
national_number = request.POST['national_number']
phone_number = request.POST['phone_number']
users = MyUser.objects.filter(Q(group__name=group)|Q(role__name=rol)|Q(national_number=national_number)|Q(phone_number=phone_number))
return render(request,'deletuser.html',locals())
If you directly render a page as the result of a POST, then refreshing that page will resubmit the form, because that's how you got there.
The usual way to avoid this is to issue an HTTP redirect after a POST, instead of rendering content directly. Then the user ends up on a page via GET, which can be refreshed without problems.
You can google search for "redirect after post" to get more details.
I'd like to do that, but this
return HttpResponseRedirect(request.path_info)
yields a redirect loop. I suspect it's because the request object is the website you're on at that time.
Whole function
def permit(request, pk):
if int(request.user.id) == int(pk):
return HttpResponseRedirect(request.path_info)
else:
return render_to_response('forbidden.html')
The user has clicked a link on a webpage. pk is the regx search term in urls.py. I want this to redirect to the page the user clicked on if the user is authorized, not the page he is currently on.
The problem is that as soon as the user is "redirected", the function permit is called. The if statement is true (since it is the authenticated user) and the redirect happens again... To prevent this loop, only redirect, if there was a post request:
def permit(request, pk):
if request.POST:
if int(request.user.id) == int(pk):
return HttpResponseRedirect(request.path_info)
else:
return render_to_response('forbidden.html')
## Return your login page here.
User not getting a chance to login. It just redirects to the 404 page:
Getting this 404 error:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/pk/invalid/
Using the URLconf defined in namekeepr.urls, Django tried these URL patterns, in this order:
The current URL, pk/invalid/, didn't match any of these.
This is my views.py file:
# Login Page
def login(request):
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = authenticate(username=username, password=password)
if user is not None and user.is_active:
# Correct password, and the user is marked "active"
auth.login(request, user)
# Redirect to a success page.
return HttpResponseRedirect("/pk/loggedin/")
else:
# Show an error page
return HttpResponseRedirect("/pk/invalid/")
Use the login_required() decorator for your view functions.
https://docs.djangoproject.com/en/1.3/topics/auth/#django.contrib.auth.decorators.login_required
from django.contrib.auth.decorators import login_required
#login_required
def my_view(request):
...
It will by default redirect your users to LOGIN_URL defined in your settings.py.
Example
Here's a simple example of what happens from the user's perspective when you use the #login_required decorator:
The user types into their browser url http://localhost:8000/my_view
This url's view has an #login_required, and the user is redirect to the login page: http://localhost:8000/login/?next=/my_view/
After the user logins again, he/she is redirected automatically to /my_view/.