Django Creating custom URL for user profile - django

I have an app which allows users to create a profile and log in.
When a user login , he is redirected to 127.0.0.1:8000/profile/
The problem is , I want to customize the URL by adding the user's username to the end of URL e.g example 127.0.0.1:8000/profile/michael
This is a similar question to mine
Django - after login, redirect user to his custom page --> mysite.com/username
"get the username and then do a HttpResponseRedirect to the custom URL."
I just can't seem to figure out how could I pass a username as an argument for HttpResponseRedirect to process into a the custom URL properly.
return HttpResponseRedirect('/profile/?username=%s' % (username, request.path))
def Profile(request):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('world:LoginRequest'))
person = Person.objects.get(user=request.user)
return render(request,'profile.html',{'person':person})
my URL
url(
r'^profile/$',
'pet.views.Profile',
name = 'Profile'
),
NEW
my views.py
def LoginRequest(request):
if request.user.is_authenticated():
username = User.objects.get(username=request.user)
url = reverse('Profile', kwargs = {'username': username.username})
return HttpResponseRedirect(url)
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
Person = authenticate(username=username, password=password)
if Person is not None:
login(request, Person)
username= User.objects.get(username=request.user)
url = reverse('Profile', kwargs = {'username': username.username})
return HttpResponseRedirect(url)
return render(request, 'login.html',{'form': LoginForm()})
url(
r'^login/$',
'pet.views.LoginRequest',
name = 'LoginRequest'
),
url(
r'^profile/(?P<username>\w+)/$',
'pet.views.Profile',
name = 'Profile'
),
def Profile(request,username):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('world:LoginRequest'))
board = Board.objects.filter(user=request.user)
person = Person.objects.get(user__username=username)
return render(request,'profile.html',{'board':board ,'person':person})

This would be the proper regex for your redirect URL, ie. don't modify the one you have.
url(r'^profile/(?P<username>\w+)/$', 'pet.views.myprofileview', name="detail_profile")
And then to pass an argument to the redirect:
url = reverse('detail_profile', kwargs={'username': profile.firstname})
return HttpResponseRedirect(url)
This leads to also having to define a new view:
def myprofileview(request, username):
person = Person.objects.get(user = request.user)
return render(request,'profile.html',{'person':person})
This would eliminate two behaviours in one view, which I find to be very nice!
We do it this way because it's a string that HttpResponseRedirect accepts so we have to build it accordingly.
This will make a redirect to the myprofileview view and "style", if you could call it that, your url /profile/michael/.

def LoginRequest(request):
if request.user.is_authenticated():
return HttpResponseRedirect(reverse('world:Profile',
kwargs={'username': request.user.username}))
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
Person = authenticate(username=username, password=password)
if Person is not None:
login(request, Person)
return HttpResponseRedirect(reverse('world:Profile',
kwargs={'username': username}))
return render(request, 'login.html',{'form': LoginForm()})

Related

Django - How to allow registration only for predefined list of e-mails/usernames

I have a following simple view in my views.py for registration on my django site:
def register_user(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
user = authenticate(username=username, password=password)
login(request, user)
messages.succes(request, ('You have registered'))
return redirect('home')
else:
form = UserCreationForm()
context = {'form': form}
return render(request, 'register.html', context)
That approach would allow anyone to register but I want to allow only selected people to be able to register. I have a simple model for my database
class EmailList(models.Model):
email_addres = models.CharField(max_length=300, blank=True)
def __str__(self):
return self.email_addres
with some e-mail addreses (my site doesn't have usernames, your username is an email addres) and I want to allow registration only for email addresses that are in that database. How would I perform such check?
There is a functionality in Django that limits an access to users that pass a certain test: https://docs.djangoproject.com/en/3.2/topics/auth/default/#limiting-access-to-logged-in-users-that-pass-a-test
You need to create a test function (verifying that the user is in allowed users list), and then use user_passes_test decorator on the view. In case you are using class based views, you need to use a UserPassesTestMixin.
Assuming your code works properly, just grab the contents of the AllowedUsers model and check whether the username is in the queryset.
models.py
class AllowedUsers(models.Model):
allowed_email = models.EmailField(max_length=256)
def __str__(self):
return self.allowed_email
views.py
def register_user(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
object = form.save(commit=False)
allowed_emails = [user.allowed_email for user in AllowedUsers.objects.all()]
if object['username'] in allowed_emails:
form.save()
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
user = authenticate(username=username, password=password)
login(request, user)
messages.success(request, ('You have registered'))
return redirect('home')
else:
return redirect('/login/?next=%s' % request.path)
I should say that if it were me, I'd be doing this while overriding the form_valid method of the default LoginView
Alternative views.py
from django.contrib.auth import views as auth_views
from django.forms import ValidationError
class LoginView(auth_views.LoginView):
def form_valid(self, form):
allowed_emails = [user.allowed_email for user in AllowedUsers.objects.all()]
if form.cleaned_data['username'] in allowed_emails:
return super().form_valid(form)
else:
self.add_error('username', ValidationError("The provided username is not allowed"))

Redirect to the page from where user clicked signin after login in django3.0

i want to redirect the user to the page from where he clicked the login instead of home.
login view:
def login_view(request):
context = {}
user = request.user
if user.is_authenticated:
return redirect('home')
if request.POST:
form = AccountAuthenticationForm(request.POST)
if form.is_valid():
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user:
login(request, user)
return redirect('home')
else:
form = AccountAuthenticationForm()
context['login_form'] = form
return render(request, "account/login.html", context)
You can preserve the the current url & redirect to it by using HTTP_REFERER. You can pass the url name as second parameter where you want to redirect if HTTP_REFERER fails.
from django.shortcuts import redirect
return redirect(request.META.get('HTTP_REFERER', 'secondary_url_name'))

How can i create a login view after registration?

I create models,forms and views for registrarion and i want to create a login view so that after registration user can login.
models.py
from django.contrib.auth.models import AbstractUser
from django_countries.fields import CountryField
g_CHOICES = (('male','male'),('female','female'))
class User(AbstractUser):
gender = models.CharField(max_length=100,choices=g_CHOICES,default="male")
country = CountryField()
location = models.CharField(max_length=30, blank=True)
forms.py
g_CHOICES = (('male','male'),('female','female'))
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
gender = forms.ChoiceField(choices=g_CHOICES)
country = CountryField().formfield()
location = forms.CharField(max_length=30,)
class Meta:
model = User
fields = ['first_name','last_name','username','email',
'password1','password2','gender',
'country','location']
views.py
def register(request):
if request.method == 'POST':
rform = UserRegisterForm(request.POST)
if rform.is_valid():
rform.save()
username = rform.cleaned_data.get('username')
messages.success(request,('Account created for '+str(username)))
return redirect('/')
else:
rform = UserRegisterForm()
return render(request,'reg.html',{'rform':rform})
Now i want to create a view for login please someone help
You need a view that takes the user's username and password from the POST request, then authenticates them and logs them in using 'authenticate' and 'login' from django.contrib.auth package.
from django.contrib.auth import login, authenticate
from django.views import View
class HandleLogin(View):
def get(self, request):
return render(request, "login.html", {})
def post(self, request):
username= request.POST.get("username")
password = request.POST.get("password")
user = authenticate(username, password)
if user is not None:
if user.is_active:
login(request, user)
# Do something for succesfull logged in
else:
# Do something else because user is not active
else:
# Do something about user not existing
For more information: https://docs.djangoproject.com/en/2.2/topics/auth/default/
You can use something like below one:
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)
messages.success(request, 'You are now logged in')
return redirect('dashboard')
else:
messages.error(request, 'Invalid credentials')
return redirect('login')
else:
return render(request, 'accounts/login.html')
Or if you are using a django form you can do this way too and this is more preferred way:
def user_login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(request,
username=cd['username'],
password=cd['password'])
if user is not None:
login(request, user)
return HttpResponse('Authenticated '\
'successfully')
else:
return HttpResponse('Invalid login')
else:
form = LoginForm()
return render(request, 'account/login.html', {'form': form})

Django.contrib.auth.login is not working after i redirect to a different url

The login function is not working , after i call login , authenticated is set 'true' but after i redirect to 'main' view authenticated is set 'false'. How to keep the user logged in even after redirection?
class LoginForm(forms.Form):
user = forms.CharField()
password = forms.CharField()
def login(self):
try:
cred = users.objects.get(username = user)
if password==cred.password):
return (True, cred)
return (False, 'Invalid Password.')
except:
return (False, 'Not exist')
from django.contrib.auth import login as auth_login
def login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
valid, message = form.login()
if valid:
auth_login(request, message)
print(request.user.is_authenticated)
# this is not working
return redirect(main)
else:
return redirect(login)
form = LoginForm()
args = {'form': form}
return render(request, 'accounts/login.html', args)
def main(request):
print(request.user.is_authenticated)
You shouldn't write check your user credentials in form class. Do it in your login view. Example:
# views.py
from django.contrib.auth import authenticate, login
from django.urls import reverse
from django.shortcuts import redirect, render
def login_view(request): #changed_the name shouldn't be login
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, password)
if user:
login(user)
return redirect(reverse("main"))
else:
return redirect(reverse("login"))
form = LoginForm()
args = {"form": form}
return render(request, 'accounts/login.html', args)
# urls.py
urlpatterns = [
path("login/", views.login_view, name="login"), # <-- really important
path("main/", views.main_view, name="main")
]
To summarize - to redirect to another page use redirect function. If you set name parameter in url of you view, you can reffer to this view using reverse. Also don't reinvent the wheel and write your own authentication function. Django provides: authenticate(username, password) and login(user) function.

django - how to reach username which is in url

i have blog system which is every user have their own main page like ;
127.0.0.1/username
and every user's login screen located at : 127.0.0.1/username/panel
and again here is their admin panel : 127.0.0.1/username/admin
in login page ; when i submit ; it must redirect the user to admin panel.
but i need to reach the username which is in url at the moment. i think i shoud use regexp. but how? i am bad about regexp.
here is my urls.py:
urlpatterns = patterns('blog.views',
url(r'^blog/(?P<username>[-\w]+)/$',view='index', name='index'),
url(r'^blog/(?P<username>[-\w]+)/post/(?P<postslug>[-\w]+)',view='singlePost', name='view_blog_post'),
url(r'^blog/(?P<username>[-\w]+)/panel/$', view='loguserin'),
url(r'^blog/(?P<username>[-\w]+)/admin/$', view='adminView', name='admin'),
url(r'^blog/(?P<username>[-\w]+)/admin/loggedout/$', view='logout', name='logout'),
url(r'^blog/(?P<username>[-\w]+)/admin/addpost/$', view='addpost',name='addpost'),
url(r'^blog/(?P<username>[-\w]+)/admin/editpost/(?P<post_id>\d+)', view='editPost', name='editpost'),
url(r'^blog/(?P<username>[-\w]+)/admin/delete/(?P<post_id>\d+)', view='delete_post', name='deletePost'),
)
and here is my views.py [login part]:
def loguserin(request,username):
if request.method=='POST':
uname = request.POST['username']
password = request.POST['password']
user = authenticate(username=uname, password=password)
form = LoginForm(request.POST)
if form.is_valid():
if user is not None:
request.session['loggedin']="djangoo"
login(request, user)
return HttpResponseRedirect('/admin/') #--> ????
else:
form = LoginForm()
return render_to_response('login.html',{'form':form,},context_instance=RequestContext(request))
Actually, you already have the username:
from django.core.urlresolvers import reverse
return HttpResponseRedirect(reverse('admin', args=[uname]))
What you need is reverse with parameters:
from django.core.urlresolvers import reverse
def loguserin(request,username):
if request.method=='POST':
uname = request.POST['username']
password = request.POST['password']
user = authenticate(username=uname, password=password)
form = LoginForm(request.POST)
if form.is_valid():
if user is not None:
request.session['loggedin']="djangoo"
login(request, user)
return HttpResponseRedirect(reverse('admin', args=[uname])) #--> ????
else:
form = LoginForm()
return render_to_response('login.html',{'form':form,},context_instance=RequestContext(request))