I’m keeping getting this redirect wrong either I got the code wrong or it keeps running in an infinite loop.
urls.py first app
urlpatterns = [
path("",views.pomo,name="pomo"),
path("agenda/",views.agenda,name="agenda"),
path("notes/",views.notes,name="notes"),
]
urls.py main
urlpatterns = [
path('admin/', admin.site.urls),
path("", include('pomofocus.urls')),
path ("login/", include('accounts.urls'))
]
urls.py accounts(2nd app)
urlpatterns = [
path("register/",views.register_request, name="register")
]
views.py
from django.contrib import messages
def register_request(request):
if request.method == "POST":
form = NewUserForm(request.POST)
if form.is_valid():
#save user
user = form.save()
#login user
login(request,user)
#send success message
messages.success(request,"Congrats you are registered now")
return redirect(“pomofocus:pomo")
messages.error(request,"Unsuccesful registration.Try again.")
form = NewUserForm()
return render(request,"account/registration.html",context={"register_form":form})
You create a new form if the POST request is unsuccessful. You should keep the old form, such that errors can be displayed. You thus should change the logic such that you only create a new form in case the request is not a POST request:
from django.contrib import messages
def register_request(request):
if request.method == 'POST':
form = NewUserForm(request.POST, request.FILES)
if form.is_valid():
#save user
user = form.save()
#login user
login(request,user)
#send success message
messages.success(request, 'Congrats you are registered now')
return redirect('pomo')
else:
messages.error(request, 'Unsuccesful registration.Try again.')
else: # ← only in case it is not a POST request
form = NewUserForm()
return render(request,'account/registration.html', {'register_form': form})
Related
This is my page url within the urls.py file:
path('login/',views.login_view, name="login"),
This is my page view with the views.py file:
def login_view(request):
if request.method == "POST":
user_name = request.POST.get("username")
pass_word = request.POST.get("password")
user = authenticate(request, username=user_name, password=pass_word)
# print("user1 -->", user)
if user is not None:
# print("user-->",user)
login(request, user)
return render(request, "index.html")
else:
return render(request,"http://127.0.0.1:8000/login")
else:
# return render(request, "order.html")
return render(request, "login.html")
The error I am getting is:
TypeError at /login/logincheck/login() missing 1 required positional
argument: 'user'
first create a forms.py file:
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(max_length=63)
password = forms.CharField(max_length=63, widget=forms.PasswordInput)
your views.py should seem like this:
from django.contrib.auth import login, authenticate
from . import forms
def login_view(request):
form = forms.LoginForm()
message = ''
if request.method == 'POST':
form = forms.LoginForm(request.POST)
if form.is_valid():
user = authenticate(
username=form.cleaned_data['username'],
password=form.cleaned_data['password'],
)
if user is not None:
login(request, user)
message = f'Hello {user.username}! You have been logged in'
else:
message = 'Login failed!'
return render(
request, 'authentication/login.html', context={'form': form, 'message': message})
Just to add to #enes islam's approach... It's okay with what he posted as his answer but according to your project you have another view in your views.py file called login so maybe it's using that view and not the django login method you imported.
# You have this import line here
from django.contrib.auth import authenticate, logout, login
# But I noticed further down you have a defined login method
def login(request): # -> rename this method name to loginDjano or another name.
return render(request, "login.html")
That defined method is what is really being called here... So I'd suggest you delete or rename that method then go ahead and use that line again.
if user is not None:
# Remember to pass both request and user objects to this login method
login(request, user)
message = f'Hello {user.username}! You have been logged in'
else:
message = 'Login failed!'
Ideally, that should work.
Like in facebook. after logging in users are prompted to user homepage. but it prevents the logged in users to going back to login page unless users logout. so how to prevent the logged in users from going back after loggin in
def register(request):
form = self.register_form(request.POST)
if request.method=='POST':
if form.is_valid():
user = form.save(commit=False)
firstName=form.cleaned_data.get('firstName')
lastName=form.cleaned_data.get('lastName')
username=form.cleaned_data.get('username')
email=form.cleaned_data.get('email')
password=form.cleaned_data.get('password1')
user.set_password(password)
user.save()
messages.success(request, f'Account successfully created!')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'registration/register.html', {'form': form})
path('login/', auth_views.LoginView.as_view(template_name='registration/login.html',redirect_authenticated_user=True), name='login'),
# path('logout/', auth_views.LogoutView.as_view(template_name='registration/logout.html'), name='logout'),
path('register/', views.register, name='register'),
LOGIN_REDIRECT_URL = 'home:index'
LOGIN_URL = 'login'
LOGOUT_REDIRECT_URL = 'index'
Below are some option. try reading django doc https://docs.djangoproject.com/en/2.1/topics/auth/
Option 1
This can be one of the way. You check if the user is logged in and return suitable html page.
views.py
def home(request):
if not request.user.is_anonymous:
return render("home.html")
else:
return render("login.html")
Option 2
Check if the user is logged in , if so redirect to home page endpoint
from django.shortcuts import render, HttpResponseRedirect
from django.contrib.auth import login_required
def login(request):
if not request.user.is_anonymous:
return HttpResponseRedirect('/home')
#login_required
def home(request):
# Render you home page response
What you can do is redirect the user to the home page even if the user clicks the login/signup link.
For this you can do something in the login and signup views:
def login(request):
# if the user is already logged in, redirect to user home page
if request.user.is_authenticated:
# redirect to the home page
else:
# do something like defining get or post method request conditions
def signup(request):
# if the user is already logged in, redirect to user home page
if request.user.is_authenticated:
# redirect to the home page
else:
# do something like defining get or post method request conditions
This is one way to redirect the logged in user to the home page even if the user clicks the login/signup link or tries going back to the login page.
I have a form that is filled out on a webpage. The goal of the form is to gather some basic info, and then save the IP of the sender to the DB too. The form submits a POST request to my Django view, but Django gives me the error:
if request.method() == 'POST':
TypeError: 'str' object is not callable
Here is the view:
from .form import SignUpForm
from django.shortcuts import render
from django.http import HttpResponseRedirect
def index(request):
if request.method() == 'POST':
form = SignUpForm(request.POST)
if form.is.valid():
signup_item = form.save(commit=False)
signup_item.ip_address = request.META['HTTP_X_FORWARDED_FOR']
signup_item.save()
return HttpResponseRedirect(request.path)
else:
form = SignUpForm()
return render(request, 'index.html', {'form': form})
Here is the urls.py
from django.conf.urls.import url
from django.contrib import admin
from form import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', views.index, name='home')
]
I think the issue is with request.method(); method is a string data member, not a member function. Remember - this is python, where 'getters' are often dropped in favor of directly accessing class members.
So, try:
if request.method == 'POST':
form = SignUpForm(request.POST)
etc.
In my app I try to redirect after submitting a form, but it seems to does not work.
Here is my urls.py
from django.conf.urls import url
from po_contest_app import views
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^$', views.home, name='home'),
url(r'^signup/$', views.graduate_signup, name='signup'),
url(r'^signup/success/$', views.signup_success, name='signup_success')
]
and views.py. The actual problem is in graduate_signup view. After receiving POST request I want to create a User and then save additional info about it. For that purpose I use User Profile approach as described here:
def graduate_signup(request):
if request.method == 'POST':
form = GraduateSignUpForm(request.POST)
print('POST has been received')
if form.is_valid():
user = form.save()
user.refresh_from_db() # load the profile instance created by the signal
user.graduate.birth_date = form.cleaned_data.get('birth_date')
user.save()
print('user is signed up')
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
login(request, user)
print('user is signed in')
return redirect('signup_success')
else:
print('form has some errors')
print(form.errors)
else:
form = GraduateSignUpForm()
return render(request, 'graduate_signup.html', {'form': form})
def signup_success(request):
return render(request, 'signup_finished.html')
After submitting form in browser, I can see logs in Django console:
System check identified no issues (0 silenced).
January 19, 2018 - 08:05:32
Django version 1.11.7, using settings 'po_contest.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[19/Jan/2018 08:05:34] "GET / HTTP/1.1" 200 922
[19/Jan/2018 08:05:36] "GET /signup/ HTTP/1.1" 200 6484
POST has been received
user is signed up
user is signed in
[19/Jan/2018 08:05:56] "POST /signup/ HTTP/1.1" 302 0
[19/Jan/2018 08:05:56] "GET /signup/success/ HTTP/1.1" 200 758
However in browser I still see my signup page with the form, and no page I'm trying redirect to.
My question: what can cause the problem?
The proper way to achieve this is to provide LOGIN_URL and LOGIN_URL_REDIRECT in settings.py file of your project. And then provide some logic in confirmation, something like:
def confirmation(request):
if request.method == 'POST':
form = ConfirmationForm(request.POST, instance=request.user)
if form.is_valid():
user.first_login = False
user.save()
return redirect('some_page')
else:
if not user.first_login:
login(request, request.user)
return redirect('some_page')
form = ConfirmationForm(instance=request.user)
context = {
'form': form,
}
return render(request, 'confirmation.html', context)
Instead of return redirect change it to HTTPResponseRedirect
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
def graduate_signup(request):
if request.method == 'POST':
form = GraduateSignUpForm(request.POST)
print('POST has been received')
if form.is_valid():
user = form.save()
user.refresh_from_db() # load the profile instance created by the signal
user.graduate.birth_date = form.cleaned_data.get('birth_date')
user.save()
print('user is signed up')
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
login(request, user)
print('user is signed in')
return HttpResponseRedirect('/signup/success/')
else:
print('form has some errors')
print(form.errors)
else:
form = GraduateSignUpForm()
return render(request, 'graduate_signup.html', {'form': form})
def signup_success(request):
return render(request, 'signup_finished.html')
I am trying to create a system where certain pages can't be accessed unless the request is from a specific location. I currently have everything working except after the location is checked and the request is redirected to the next view, the form on that next view isn't posting properly. It's still trying to post the location data form.
You'll see what I mean more in my views.py:
def add(request):
if request.method == 'POST':
form = StudentModelForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/')
else:
form = StudentModelForm()
context_data = {'form': form}
return render(request, 'add.html', context_data)
def location_check_add(request):
if request.method == 'POST' and 'lat' in request.POST:
user_lat = request.POST.get('lat')
user_lon = request.POST.get('lon')
if good_location(user_lat,user_lon):
return add(request)
else:
return render(request, 'location.html')
return render(request, 'checking.html')
So I'm trying to redirect to the add() view if good_location is true. It redirects properly but then when a user tries to post the form on add.html django thinks it's submitting the form in location_check_add again.
Edit: Adding urls.py for reference
import users.views
urlpatterns = patterns('',
url(r'^$', users.views.index, name = 'index'),
url(r'^admin/', include(admin.site.urls)),
url(r'^add/', users.views.location_check_add, name = 'add'),
)
You need to redirect, not just call the view.
if good_location(user_lat,user_lon):
return redirect('add')
Alright! After a lot of documentation searching and googling I found out about Django's sessions feature. Documentation here:
Documentation
In the end my code ended up looking like:
def add(request):
if request.session.get('at_work', False):
if request.method == 'POST':
form = StudentModelForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/')
else:
form = StudentModelForm()
context_data = {'form': form}
return render(request, 'add.html', context_data)
else:
return redirect(location_check_add)
def location_check_add(request):
if request.method == 'POST' and 'lat' in request.POST:
user_lat = request.POST.get('lat')
user_lon = request.POST.get('lon')
if good_location(user_lat,user_lon):
request.session['at_work'] = True
return redirect(add)
else:
return render(request, 'location.html')
return render (request, 'checking.html')
Basically I just passed around the session variable "at_work" to make sure the location was correct before rendering the page in the add() view. Then I was able to use the regular redirect function since I could have a url directed at add() in urls.py without people getting around the location check.