Django won't change url on redirect - python

Upon registration I check the user_type and move the user to one of three web pages.
It is showing the correct page layout but the url stays the same as the registration page.
EG: url says "http://127.0.0.1:8000/users/register/"
Page shows: "user type 1 information"
I thought using redirect should change the url but it doesn't seem to be working.
views.py:
def register(request):
if request.method == 'POST':
form = RegisterForm(data=request.POST)
if form.is_valid():
# profile = form.save(commit=False)
# profile.user = request.user
# profile.save()
user = form.save()
profile = user.userprofile
user_group = form.cleaned_data.get('user_type')
profile.user_type = user_group
profile.save()
# form.save()
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password1')
user_group = form.cleaned_data.get('user_type')
user = authenticate(username = username, password = password)
login(request, user)
print(user_group)
print(type(user_group))
if user_group == '1':
return HttpResponseRedirect("/users/business/")
# return
# HttpResponseRedirect('http://127.0.0.1:8000/users/business/')
# return HttpResponseRedirect(reverse('users:business'))
# return redirect(request, 'users/business.html')
elif user_group == '2':
return redirect(request, 'users/student.html')
elif user_group == '3':
return redirect(request, 'users/tourist.html')
# else:
# return redirect('main:index')
else:
print(RegisterForm.errors)
else:
form = RegisterForm()
def business_view(request):
# return redirect(request, 'users/business.html')
# return HttpResponseRedirect('users/business.html')
# return redirect('/users/business/')
return redirect('users/business')
def student_view(request):
return redirect(request, 'users/student.html')
def tourist_view(request):
return redirect(request, 'users/tourist.html')
urls.py
urlpatterns = [
# Login page
#url(r'^login/$', login, {'template_name': 'users/login.html'},
name='login'),
url(r'^login/$', login, {'template_name': 'users/login.html'},
name='login'),
#url(r'^login/$', views.log_in, name='login'),
# Register page
url(r'^register/$', views.register, name='register'),
# Business page
#url(r'^business/$', views.business_view, name='business'),
url(r'^$',views.business_view),
# Student page
url(r'^student/$', views.student_view, name='student'),
# Tourist page
url(r'^tourist/$', views.tourist_view, name = 'tourist'),
]
Thanks for any help.

Use urlname only in redirect argument, i.e. to redirect on student page use return redirect('student') (name defined while defining urls). Eg.
if user_group == '2':
return redirect('student')
Also in your views where you want to show html page, use render instead. Eg.
from django.shorcuts import render
def student_view(request):
return render(request, 'users/student.html')

Related

How can I use slugs in Django url like mysite.com/user

I want to create a directory like website.com/user after the user get logged in!
And I'm not sure which url pattern in my app/urls.py should call this myfun to capture slug: user in url
def myfun(request, user):
user = TwitterUser().objects.get(user=user)
return render(request, 'authorization/home.html', {'user' : user})
models.py
class TwitterUser(models.Model):
screen_name = models.CharField(max_length=255)
name = models.CharField(max_length=255)
user = models.SlugField('auth.User', unique=True, null=True)
app/urls.py
urlpatterns = [
path('', views.index, name='index'),
path('twitter_login/', views.twitter_login, name='twitter_login'),
path('twitter_callback/', views.twitter_callback, name='twitter_callback'),
path('twitter_logout/', views.twitter_logout, name='twitter_logout'),
]
view.py
def twitter_login(request):
twitter_api = TwitterAPI()
url, oauth_token, oauth_token_secret = twitter_api.twitter_login()
if url is None or url == '':
messages.add_message(request, messages.ERROR, 'Unable to login. Please try again.')
return render(request, 'authorization/error_page.html')
else:
twitter_auth_token = TwitterAuthToken.objects.filter(oauth_token=oauth_token).first()
if twitter_auth_token is None:
twitter_auth_token = TwitterAuthToken(oauth_token=oauth_token, oauth_token_secret=oauth_token_secret)
twitter_auth_token.save()
else:
twitter_auth_token.oauth_token_secret = oauth_token_secret
twitter_auth_token.save()
return redirect(url)
def twitter_callback(request):
if 'denied' in request.GET:
messages.add_message(request, messages.ERROR, 'Unable to login or login canceled. Please try again.')
return render(request, 'authorization/error_page.html')
twitter_api = TwitterAPI()
oauth_verifier = request.GET.get('oauth_verifier')
oauth_token = request.GET.get('oauth_token')
twitter_auth_token = TwitterAuthToken.objects.filter(oauth_token=oauth_token).first()
if twitter_auth_token is not None:
access_token, access_token_secret = twitter_api.twitter_callback(oauth_verifier, oauth_token, twitter_auth_token.oauth_token_secret)
if access_token is not None and access_token_secret is not None:
twitter_auth_token.oauth_token = access_token
twitter_auth_token.oauth_token_secret = access_token_secret
twitter_auth_token.save()
# Create user
info = twitter_api.get_me(access_token, access_token_secret)
if info is not None:
twitter_user_new = TwitterUser(twitter_id=info[0]['id'], screen_name=info[0]['username'],
name=info[0]['name'], profile_image_url=info[0]['profile_image_url'])
twitter_user_new.twitter_oauth_token = twitter_auth_token
user, twitter_user = create_update_user_from_twitter(twitter_user_new)
if user is not None:
login(request, user)
return redirect('index')
else:
messages.add_message(request, messages.ERROR, 'Unable to get profile details. Please try again.')
return render(request, 'authorization/error_page.html')
else:
messages.add_message(request, messages.ERROR, 'Unable to get access token. Please try again.')
return render(request, 'authorization/error_page.html')
else:
messages.add_message(request, messages.ERROR, 'Unable to retrieve access token. Please try again.')
return render(request, 'authorization/error_page.html')
#login_required
#twitter_login_required
def index(request):
return render(request, 'authorization/home.html')
#login_required
def twitter_logout(request):
logout(request)
return redirect('index')
Your response will be highly appreciated :)
Add it to your urls.py with the relevant placeholder and get the placeholder as parameter in the view:
urlpatterns = [
path('', views.index, name='index'),
path('<str:user>', views.myfun, name='myfun')
]
You can see more info here in Django documentation https://docs.djangoproject.com/en/4.1/topics/http/urls/

Password reset confirm page not loading

I am building the reset password page, the first page where the users enter his email work fine, he receive the reset password email with success. The problem it with the page where the user actually write his new password.
When I click on the link / go to the page it give me this error:
assert uidb64 is not None and token is not None # checked by URLconf
I am following this docs here: https://docs.djangoproject.com/en/1.8/_modules/django/contrib/auth/views/
here is my views.py
#sensitive_post_parameters()
#never_cache
def password_reset_confirm(request, uidb64=None, token=None,
template_name='users/password_reset_confirm.html',
token_generator=default_token_generator,
set_password_form=SetPasswordForm,
post_reset_redirect=None,
current_app=None, extra_context=None):
"""
View that checks the hash in a password reset link and presents a
form for entering a new password.
"""
UserModel = get_user_model()
assert uidb64 is not None and token is not None # checked by URLconf
if post_reset_redirect is None:
post_reset_redirect = reverse('password_reset_complete')
else:
post_reset_redirect = resolve_url(post_reset_redirect)
try:
# urlsafe_base64_decode() decodes to bytestring on Python 3
uid = force_text(urlsafe_base64_decode(uidb64))
user = UserModel._default_manager.get(pk=uid)
except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
user = None
if user is not None and token_generator.check_token(user, token):
validlink = True
title = ('Enter new password')
if request.method == 'POST':
form = set_password_form(user, request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(post_reset_redirect)
else:
form = set_password_form(user)
else:
validlink = False
form = None
title = ('Password reset unsuccessful')
context = {
'form': form,
'title': title,
'validlink': validlink,
}
if extra_context is not None:
context.update(extra_context)
if current_app is not None:
request.current_app = current_app
return TemplateResponse(request, template_name, context)
here is my urls.py
urlpatterns = [
path('password_reset/', views.password_reset, name='password_reset'),
path('password_reset/done/', views.password_reset_done, name="password_reset_done"),
path('reset/MTU/set-password/', views.password_reset_confirm, name="password_reset_confirm")
]

ValueError at /accounts/login/ The view accounts.views.signinView didn't return an HttpResponse object. It returned None instead

accounts/views.py :
from django.shortcuts import render, redirect
from .forms import CustomUserCreationForm
from .models import CustomUser
from django.contrib.auth.models import Group
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import login, authenticate, logout
def signupView(request):
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
signup_user = CustomUser.objects.get(username=username)
customer_group = Group.objects.get(name='Customer')
customer_group.user_set.add(signup_user)
else:
form = CustomUserCreationForm()
return render(request, 'signup.html', {'form':form})
def signinView(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect('phoneshop:allProdCat')
else:
return redirect('signup')
else:
form = AuthenticationForm()
return render(request, 'signin.html', {'form': form})
def signoutView(request):
logout(request)
return redirect('signin')
accounts/urls.py:
from django.urls import path
from phoneshop import views
from .views import signupView, signinView, signoutView
urlpatterns = [
path('create/', signupView, name='signup'),
path('login/', signinView, name='signin'),
path('logout/', signoutView, name='signout'),
]
main/urls.py:
from django.urls import path
from . import views
app_name ='phoneshop'
urlpatterns = [
path('', views.allProdCat, name ='allProdCat'),
path('<uuid:category_id>/', views.allProdCat, name='products_by_category'),
path('<uuid:category_id>/<uuid:product_id>/', views.prod_detail, name='prod_detail'),
]
I can't seem to figure out why the return value is None. I believe the issue to be in the urls somewhere as I have an issue with redirection. I have the same error when trying to logout as well. I just can't seem to see the error.
You indented the else: part in the signinView too much, as a result the else binds with if form.is_valid():, but you should bind this with if request.method == 'POST'. If you trigger this if the form is not valid, then there is no code to run when you make a GET request to that view. We however want in that case to construct a new form and render the tempate:
def signinView(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect('phoneshop:allProdCat')
else:
return redirect('signup')
# &downarrow; indent to the left.
else:
form = AuthenticationForm()
return render(request, 'signin.html', {'form': form})
Note: Functions are normally written in snake_case, not PerlCase, therefore it is
advisable to rename your function to signin_view, not signinView.

how can i restrict users to some specific urls

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.

Django: Can't log in using normal auth

I'm using the normal development server for Django and i am building a simple app.
A user should be able to log in and change his email and password.
To understand the django system better, I decided to write the views and such myself, only using the contrib.auth library.
Now to the problem:
Once a user logs in and changes his password, he cannot login again, unless he logs into the standard django admin page before.
Here is my code:
the views.py
def login(request):
print("test")
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is not None:
return HttpResponseRedirect('/accountManagement/home')
else:
form = LoginForm()
else:
HttpResponse("form is not valid")
else:
form = LoginForm()
return render(request, 'accountManagement/login.html', {'form': form})
def home(request):
print(request.user.username)
if request.user.is_authenticated:
passwordForm = ChangePasswordForm()
emailForm = ChangeEmailForm()
return render(request, 'accountManagement/home.html', {'passwordForm': passwordForm, 'emailForm': emailForm})
else:
return HttpResponseRedirect("/accountManagement/")
def change_password(request):
if request.user.is_authenticated:
if request.method == 'POST':
passwordForm = ChangePasswordForm(request.POST)
if passwordForm.is_valid():
oldPassword = passwordForm.cleaned_data['oldPassword']
newPassword = passwordForm.cleaned_data['newPassword']
newPasswordConfirmation = passwordForm.cleaned_data['newPasswordConfirmation']
if (newPassword == newPasswordConfirmation) and (request.user.check_password(oldPassword)):
request.user.set_password(newPassword)
request.user.save()
return HttpResponseRedirect("/accountManagement/logout")
else:
return HttpResponse("password change failed")
else:
return HttpResponse("password form not valid")
else:
return HttpResponse("request != POST")
else:
return HttpResponse("user ist not authenticated")
url.py:
urlpatterns = [
url(r'^$', views.login, name='login'),
url(r'^home', views.home, name='home'),
url(r'^changeEmail', views.change_email, name='changeEmail'),
url(r'^changePassword', views.change_password, name='changePassword'),
url(r'^logout', views.logout_view, name='logout'),
]
the forms:
class LoginForm(forms.Form):
username = forms.CharField(label='Username', max_length=20)
password = forms.CharField(label='Password', max_length=20)
class ChangeEmailForm(forms.Form):
newEmail = forms.CharField(label='New Email', max_length=50)
class ChangePasswordForm(forms.Form):
oldPassword = forms.CharField(label='Old Password', max_length=20)
newPassword = forms.CharField(label='New Password', max_length=20)
newPasswordConfirmation = forms.CharField(label='Confirm new Password', max_length=20)
Thanks for the help, really can't figure this one out.
Changing password destroy user authentication status, so you need re-authenticate him with new password again:
from django.contrib.auth import login
def change_password(request):
if request.user.is_authenticated:
if request.method == 'POST':
passwordForm = ChangePasswordForm(request.POST)
if passwordForm.is_valid():
oldPassword = passwordForm.cleaned_data['oldPassword']
newPassword = passwordForm.cleaned_data['newPassword']
newPasswordConfirmation =
passwordForm.cleaned_data['newPasswordConfirmation']
if (newPassword == newPasswordConfirmation)\
and (request.user.check_password(oldPassword)):
request.user.set_password(newPassword)
request.user.save()
# Re-authentication ===============================
# =================================================
user = authenticate(username=request.user.username,
password=NewPassword)
login(request, user)
# Why redirect to logout?!
return HttpResponseRedirect("/accountManagement/logout")
else:
return HttpResponse("password change failed")
else:
return HttpResponse("password form not valid")
else:
return HttpResponse("request != POST")
else:
return HttpResponse("user ist not authenticated")
Also I suggest you use CBV (Class based views) instead FBV (Function based views).
Any case you can use decorators #login_required and #require_http_methods in your view to remove is_authenticated and method != 'POST' logic.
from django.views.decorators.http import require_http_methods
from django.contrib.auth.decorators import login_required
#require_http_methods(["POST", ])
#login_required(redirect_field_name='my_redirect_field')
def change_password(request):
passwordForm = ChangePasswordForm(request.POST)
if passwordForm.is_valid():
oldPassword = passwordForm.cleaned_data['oldPassword']
newPassword = passwordForm.cleaned_data['newPassword']
newPasswordConfirmation =
passwordForm.cleaned_data['newPasswordConfirmation']
if (newPassword == newPasswordConfirmation)\
and (request.user.check_password(oldPassword)):
request.user.set_password(newPassword)
request.user.save()
# Re-authentication ===============================
# =================================================
user = authenticate(username=request.user.username,
password=NewPassword)
login(request, user)
# Why redirect to logout?!
return HttpResponseRedirect("/accountManagement/logout")
else:
return HttpResponse("password change failed")
else:
return HttpResponse("password form not valid")

Categories

Resources