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/
Related
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")
]
I can get a correct token when calling the URL /token/ but I wish to create a token manually for the user when /login/ is called.
urls.py:
from django.urls import path
from . import views
from .views import MyTokenObtainPairView
from rest_framework_simplejwt.views import (
TokenRefreshView,
TokenVerifyView
)
urlpatterns = [
path('', views.api_root),
path('register/', views.register),
path('login/', views.login),
path('token/', MyTokenObtainPairView.as_view(), name='token_obtain_pair'),
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('token/verify/', TokenVerifyView.as_view(), name='token_verify'),
]
views.py:
#api_view(['POST'])
def login(request):
email = request.data.get('email')
password = request.data.get('password')
user = get_object_or_404(User, email=email)
if make_password(password) == user.password:
if not user.is_active:
return Response({"error": "User is not active"}, status=400)
tokens = MyTokenObtainPairView.get_token(user)
parse_token = {
'refresh': str(tokens),
'access': str(tokens.access_token),
}
return Response(status=200, data=parse_token)
else:
return Response(status=401)
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
data = super().validate(attrs)
refresh = self.get_token(self.user)
data['refresh'] = str(refresh)
data['access'] = str(refresh.access_token)
# Add extra responses here
data['username'] = self.user.username
data['groups'] = self.user.groups.values_list('name', flat=True)
data['test'] = '1234'
return data
class MyTokenObtainPairView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
How do I modify this line to get my token for a specific user? tokens = MyTokenObtainPairView.get_token(user)
I have read the doc about manually create token by importing this:
from rest_framework_simplejwt.tokens import RefreshToken
but it is not adding the payload into the token...
Actually after Googling for an hour I finally got a solution from another post...
Proper way to do this:
refresh = RefreshToken.for_user(user)
refresh['user_name'] = user.username
refresh['first_name'] = user.first_name
refresh['last_name'] = user.last_name
refresh['full_name'] = user.get_full_name()
return {
'refresh': str(refresh),
'access': str(refresh.access_token),
}
In case someone would need this...
I need help with a project in Django. In views.py I have created a login to the site including registration, but I need to somehow use models.py to edit and add more user parameters, which I don't think is possible in views. Can someone please help me with this. I am attaching the code below.
views.py
from django.http import HttpResponse
from django.contrib.auth.models import User
from django.contrib import messages
from django.shortcuts import redirect, render
from django.contrib.auth import authenticate, login, logout
from rocnikovka import settings
from django.core.mail import EmailMessage, send_mail
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string
from django.utils.http import urlsafe_base64_encode,urlsafe_base64_decode
from django.utils.encoding import force_bytes, force_str
from . tokens import generate_token
def home(request):
return render(request, "authentication/home.html")
def signup(request):
if request.method == "POST":
# username = request.POST.get("username")
username = request.POST["username"]
fname = request.POST["fname"]
lname = request.POST["lname"]
email = request.POST["email"]
pass1 = request.POST["pass1"]
pass2 = request.POST["pass2"]
if User.objects.filter(username=username):
messages.error(request, "Username already exist! Please try some other
username.")
return redirect("home")
if User.objects.filter(email=email).exists():
messages.error(request, "Email Address already registered! ")
return redirect("home")
if len(username)>20:
messages.error(request, "Username must be under 20 characters.")
return redirect('home')
if pass1 != pass2:
messages.error(request, "Passwords did not match")
return redirect('home')
if not username.isalnum():
messages.error(request, "Username must be Alpha-numeric!")
return redirect("home")
myuser = User.objects.create_user(username, email, pass1)
myuser.first_name = fname
myuser.last_name = lname
myuser.is_active = False
myuser.save()
messages.success(request,"Your account has been succesfully created. We have sent
you a confirmation email, please confirm your email in order to activate your
account. ")
# Welcome Email
subject = "Welcome to our games sites"
message="Hello " + myuser.first_name + "!! \n" + "Welcome to our games sites!! \n
Thank you for visiting our website \n we have also sent you a confirmation email,
please confirm your email address in order to activate your account, \n\n
Thanking you, \n Jiří Bezděkovský"
from_email = settings.EMAIL_HOST_USER
to_list = [myuser.email]
send_mail(subject, message, from_email,to_list,fail_silently=True )
# Email Address confirmation Email
current_site = get_current_site(request)
email_subject ="Confirm your email in games sites"
message2 = render_to_string('email_confirmation.html',{
'name': myuser.first_name,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(myuser.pk)),
'token': generate_token.make_token(myuser)
})
email = EmailMessage(
email_subject,
message2,
settings.EMAIL_HOST_USER,
[myuser.email],
)
email.fail_silently = True
email.send()
return redirect("signin")
return render(request, "authentication/signup.html")
def activate(request, uidb64, token):
try:
uid=force_str(urlsafe_base64_decode(uidb64))
myuser=User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
myuser=None
if myuser is not None and generate_token.check_token(myuser, token):
myuser.is_active = True
myuser.save()
login(request, myuser)
messages.success(request, "Your Account has been activated!!")
return redirect("signin")
else:
return render(request, "activation_failed.html")
def signin(request):
if request.method =="POST":
username = request.POST["username"]
pass1 = request.POST["pass1"]
user = authenticate(username=username, password=pass1)
if user is not None:
login(request, user)
fname = user.first_name
return render(request, "authentication/index.html", {"fname": fname})
else:
messages.error(request, "Bad Credentials!")
return redirect("home")
return render(request, "authentication/signin.html")
def signout(request):
logout(request)
messages.success(request, "Logged Out Successfully!")
return redirect("home")
# return render(request, "authentication/signout.html")
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')
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")