I am quite new in django.I would like to authenticate a user. But I am unable to do it using authenticate function. I have looked over authenticate function in django. and there it's always showing TypeError. I have used both unicode and string in separate time but always it's showing the TypeError.
Please any help will be appreciated.
I am attching my code below:
def loginTest(request):
if request.method == 'POST':
user = authenticate(username=request.POST['username'], password=request.POST['password'])
if user is not None:
login(request,user)
return HomePage(request)
else:
return HttpResponseRedirect('/login/')
def login(request):
return render_to_response('login.html', {}, context_instance=RequestContext(request))
#login_required(login_url='/login/')
def HomePage(req):
templ = get_template('HomePage.html')
variables = Context({})
output = templ.render(variables)
return HttpResponse(output)
First off, you're defining a "login" view yourself, so when you try to call login(request, user) (what I assume is Django's built in "login" function which sets the user session), it is instead calling your function:
def login(request):
return render_to_response('login.html',{},context_instance=RequestContext(request))
Second, where did the TypeError occur? I assume since you know the nature of the error you've gotten to the Django traceback error page, if you could post the "copy-and-paste view" of the traceback itself, that would be enormously helpful.
You're also doing some funky things with your views that can be easily cleaned up by some shortcut functions. :)
However, since the nature of your question is how to do authentication in Django, here is the base you need to implement a manual login process, mostly just taken from the relevant documentation:
views.py
from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
def loginTest(request):
username = request.POST["username"]
password = request.POST["password"]
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
HttpResponseRedirect("/")
else:
HttpResponseRedirect("/login/")
#login_required(login_url="/login/")
def HomePage(request):
return render(request, "HomePage.html")
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'authtest.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^login/', 'django.contrib.auth.views.login'),
url(r'^', 'custom.views.HomePage'),
)
Also, for future reference, it would be helpful for you to post your entire script so we can see what you have imported at the top.
Related
So I have a django project and there is one view(home view) which displays the posts of the followed users and that requires a user to be authenticated, if there is no user loged in, then the code returns a 'AnonimousUser' is not iterable error and I will like my code to redirect the anonymous user to the login page if the person is on the home view. After some investigation I realized that this can be done with a custom middleware but I dont know how to do it so currently that middleware just prints if a user is logged in or if it is anonymous. What can I do to Complete this middleware and get rid of that Anoniomus User error?
middleware.py
class LoginRequiredMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
def process_view(self, request, view_func, view_args, view_kwargs):
if(request.user.is_authenticated):
print(Authenticated")
else:
print("Anonimous user")
views.py
def home(request):
user = Following.objects.get(user=request.user)
followed_users = [i for i in user.followed.all()]
followed_users.append(request.user)
contents = Post.objects.filter(user__in = followed_users)
context = {
"contents": contents,
}
print("nice")
return render(request, 'home.html', context)
urls.py
urlpatterns = [
path('', views.home, name='home'),
path('login', views.login, name='login'),
path('register', views.register, name='register'),
path('logout', views.logout, name='logout'),
path('<username>/', views.profile, name='profile'),
]
If you have any questions or need to see more code please let me know;)
There is no required to writing a custom middleware.
You can restrict the anonymous user in your view like this
def home(request):
if not request.user.is_authenticated:
return redirect ('your_login_url')
user = Following.objects.get(user=request.user)
followed_users = [i for i in user.followed.all()]
followed_users.append(request.user)
OR you can user login_required decorator
from django.contrib.auth.decorators import login_required
#login_required(login_url='your_login_url')
def home(request):
user = Following.objects.get(user=request.user)
followed_users = [i for i in user.followed.all()]
followed_users.append(request.user)
Well, the above answer contains the two solutions to your problem, you could also use django.contrib.auth.mixins, they are used for Class-based view. The links for documentation are
1.https://docs.djangoproject.com/en/3.0/topics/class-based-views/mixins/
2.https://docs.djangoproject.com/en/3.0/topics/auth/default/
One of the possible issue might be that you have set the action of login template form to redirect to some page e.g.
So, it never validates the login VIEW to proceed the authentication. If so, try to set action="" of login form and write the login view which renders the login.html template.
I hope someone could maybe help me, please :
I am quite new to Django and currently trying to implement a simple login/logout for a test page.
However, for some reasons, the Django does not generate the name of application in the href (so where it should be xxxx/main/register, it is only xxx/register).
But when I put the app name manually in the href in Pycharm, it generates it two times (so it becomes xxx/main/main/register).
So for this:
Logout
I got this url:
http://127.0.0.1:8000/logout/
If I write this:
Logout
I got this url:
http://127.0.0.1:8000/main/main/logout/
But I need to get this:
http://127.0.0.1:8000/main/logout/
It worked before, but from one minute to another, it suddenly stopped directing to the good path. And django does the same thing with every links in my site.
main/urls.py:
from django.urls import path
from . import views
app_name = 'main' # here for namespacing of urls.
urlpatterns = [
path("", views.homepage, name="homepage"),
path("register/", views.register, name="register" ),
path("logout/", views.logout_request, name="logout"),
]
main/views.py:
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .models import Tutorial
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth import logout, authenticate, login
from django.contrib import messages
def homepage(request):
return render(request = request,
template_name='main/home.html',
context = {"tutorials":Tutorial.objects.all})
def register(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
username = form.cleaned_data.get('username')
messages.success(request, f"New account created: {username}")
login(request, user)
return redirect("main:homepage")
else:
for msg in form.error_messages:
messages.error(request, f"{msg}: {form.error_messages[msg]}")
else:
form = UserCreationForm
return render(request = request,
template_name='main/register.html',
context={"form":form})
def logout_request(request):
logout(request)
messages.info(request, "Logged out successfully!")
return redirect("main:homepage")
mysite/urls.py:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('main/', include('main.urls')),
path('admin/', admin.site.urls),
path('tinymce/', include('tinymce.urls')),
]
The behaviour you observe has nothing to do with Django, it's a basic html feature: in the first case you're using an absolute path (=> starting with a slash) for your href, in the second one you're using a relative path (NOT starting with a slash) so it's resolved relatively to the current url path whatever it is. You'd have the very same issue with plain static HTML.
This being said, in Django, you should never hardcode urls, but use the {% url <name> %} template tag (or the django.utils.reverse() function in Python code) instead, so you can change your urls in the urls.py files without breaking anything.
<a href="{% url 'logout' %}">
Use the name in href tag that will work.
You should use the url name in the template. It should solve the problem. Like this:
Logout
Or with namespacing:
Logout
I am a new Django user and I just created a registration and login system for my website in Django 1.11. I am struck when I go to login section of my website. I get the error as mentioned "login() missing 1 required positional argument: 'user'" and I can't figure out what's wrong with the login function and the variable 'user'. Kindly help me. Thanks in advance. Here is my code:
urls.py:
from django.conf.urls import url
from . import views
from django.contrib.auth import login
app_name='one'
urlpatterns = [
url(r'^games$',views.games,name='games'),
url(r'^others$',views.others,name='others'),
url(r'^about$',views.about,name='about'),
url(r'^upload$',views.UploadFile.as_view(),name='upload'),
url(r'^register$',views.UserFormView.as_view(),name='register'),
url(r'^login/$', login, name='login'),
]
views.py:
from django.shortcuts import render,redirect
from django.contrib.auth import authenticate, login
from django.views.generic.edit import CreateView
from .models import file
from django.views.generic import View
from .forms import user_form
class UserFormView(View):
form_class = user_form
template_name = 'one/register_form.html'
def get (self,request):
form = self.form_class(None)
return render(request,self.template_name,{'form':form})
def post (self,request):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit = False)
username= form.cleaned_data['username']
password= form.cleaned_data['password']
user.set_password(password)
user.save()
user= authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
redirect('one:profile')
return render(request,self.template_name,{'form':form})
You’ve got the import wrong. You need to import the login view:
from django.contrib.auth.views import login
At the moment you have imported the login function that actually logs the user in.
The login view you are using is deprecated in Django 1.11. You can switch to the new class-based LoginView:
from django.contrib.auth.views import LoginView
url(r'^login/$', LoginView.as_view(), name='login'),
I'm using django's auth module to handle the user login, logout and registration in my website.
The problem is that when I register a new user, I new to redirect to another url, and then, since the model is created but doesn't automatically log in, I need to navigate to /login/ and log in manually.
I would like my site to do this automatically. By that I mean that:
You click on the register button in home.html. You fill in the form and submit it.
The website AUTOMATICALLY creates the new user model, logs you in and redirects you to home.html with the user logged in.
Urls.py looks like this:
from django.conf.urls import include, url, patterns
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.auth import views as auth_views
from django.contrib.auth.forms import UserCreationForm
from browse.views import UserCreate
urlpatterns = patterns('',
url(r'',include('browse.urls')),
url(r'^$', 'browse.views.home_page', name='home'),
url(r'^admin/', include(admin.site.urls)),
url(r'^login/$', auth_views.login, {'template_name': 'browse/login.html'}),
url(r'^register/$', UserCreate.as_view(
template_name='browse/register.html',
form_class=UserCreationForm,
success_url='/register/'
)),
url(r'^logout/$', 'browse.views.logout_view', name='logout'),
url(r'^', include('django.contrib.auth.urls')),
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
and views.py looks like this:
from django.shortcuts import render, redirect
from django.views.generic.edit import CreateView
from browse.models import Pattern
from django.contrib.auth.models import User
from django.contrib.auth import logout, login
class PatternCreate(CreateView):
model = Pattern
fields = ['name','description','license', 'xcheme', 'pictures', 'video']
class UserCreate(CreateView):
model = User
def post(self, request):
return login(request, User.objects.get(username=request.POST['username']))
def home_page(request):
return render(request, 'browse/home.html')
def pattern_detail(request, pk):
pattern = Pattern.objects.get(pk=pk)
return render(request, 'browse/pattern_detail.html', {'pattern': pattern})
def logout_view(request):
logout(request)
return redirect('/')
As you can see, when you GET /register/ the register form is rendered. When I POST to /register/, I want to execute the view as normally AND then add:
def post(self, request):
return login(request, User.objects.get(username=request.POST['username']))
But It looks like I'm overriding the default view instead of adding to it, because the model doesn't get saved, since I get this error:
Exception Value:
User matching query does not exist.
How can I fix it?
Thank you so much beforehand.
Okay, it was a really dumb question. Luckily, I could figure it out:
def post(self, request):
super(UserCreate, self).post(request)
login_username = request.POST['username']
login_password = request.POST['password1']
created_user = authenticate(username=login_username, password=login_password)
login(request, created_user)
return redirect('/')
All I had to do is call super() and the parent function is executed. Then, my code executes.
I'm following this tutorial and finished it: http://tutorial.djangogirls.org/en/django_forms/README.html
I want to continue and add a register button next to the login button which I did, but I couldn't get it to work. I tried doing action = "{% url blog.views.register %}" but I kept getting the error about no arguments found. I would post all my code but I'm almost sure it's way off base. I followed this idea: http://tea.cesaroliveira.net/archives/460 but I couldn't get it to work right. What is the best way to implement a registration form? Can someone give me an example or a guide, even just a short one written out to the approach I should take to add registration features. I had added a second form in login.html template with method=post and action = "{% url blog.views.register %}" with another template for registration, register.html
in blog/views.py
def register(request):
if request.method == "POST":
form = UserCreateForm(request.POST, instance=post)
return render(request, 'blog/register.html)
and in forms.py
from django import forms
from .models import Post
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class UserCreateForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ( "username", "email" )\
and in blog/urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from blog import views
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^accounts/login/$', 'django.contrib.auth.views.login'),
url(r'^accounts/logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'}),
url(r'', include('blog.urls')),
url(r'^accounts/register/$', views.register , {'next_page': '/'}),
)
As far as validation I can worry about that later, I just want to get it to work so that they can click register and bring up a registration template with a form to fill out. I'm not sure if this requires a new model or not as django has user capabilities built in already.
Any help/advice would be much appreciated. I just want to see what is wrong with my approach and what a better approach would be.
Alright, starting from the top and this is most likely the first reason why your code is probably falling apart, this {% url blog.views.register %} is wrong. Per the Django docs on reverse urls:
In order to perform URL reversing, you’ll need to use named URL patterns.
So, to create a reverse url for the registration view, your urlpattern should look like this:
urlpatterns = patterns('',
url(r'^accounts/register/$', views.register , name="register"),
)
I took out the 'next' item because you can redirect from the view. And in the template, you put:
{% url 'blog:register' %}, the left hand argument being the app name and the right-hand arg being the name of the url pattern.
Second, I'm not sure how you're handling the login form, but the register view is expecting an instance that doesn't exist. Instance is used when you're UPDATING an existing object. For your registration, that's not what's happening, so it doesn't need to be there.
def register(request):
if request.method == "POST":
form = UserCreateForm(request.POST) # filled form/i'm skipping validation for this example
return HttpResponseRedirect('/') # go to some other page if successfully saved
else:
form = UserCreateForm # if the user accessed the register url directly, just display the empty form
return render(request, 'blog/register.html', {'form': form})
But ultimately, I highly recommend django-allauth for user registration/profile stuff.
UPDATE: Fixed the reverse url for register.