Django Generic Views using decorator login_required - django

I'm new with django and I finished the 4 part tutorial on djangoproject.com
My problem is I want to put a login authentication on my polls app. I've use the decorator #login_required and it works properly but under my views.py I have only vote() method.
my views.py under "polls folder"
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth.decorators import login_required
from django.views.decorators.cache import never_cache
from django.core.urlresolvers import reverse
from django.template import RequestContext
from polls.models import Poll, Choice
#login_required
#never_cache
def vote(request, poll_id):
p = get_object_or_404(Poll, pk=poll_id)
try:
selected_choice = p.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render_to_response('polls/detail.html', {
'poll': p,
'error_message': "You didn't select a choice.",
}, context_instance=RequestContext(request))
else:
selected_choice.votes += 1
selected_choice.save()
return HttpResponseRedirect(reverse('poll_results', args=(p.id,)))
return HttpResponse("You're voting on poll %s." % poll_id)
my urls.py under "polls folder"
from django.conf.urls.defaults import patterns, include, url
from django.views.generic import DetailView, ListView
from polls.models import Poll
urlpatterns = patterns('',
url(r'^$',
ListView.as_view(
queryset = Poll.objects.order_by('-pub_date')[:5],
context_object_name = 'latest_poll_list',
template_name = 'polls/index.html'), name='poll_lists'),
url(r'^(?P<pk>\d+)/$',
DetailView.as_view(
model = Poll,
template_name = 'polls/detail.html'), name='poll_details'),
url(r'^(?P<pk>\d+)/results/$',
DetailView.as_view(
model = Poll,
template_name = 'polls/results.html'), name = 'poll_results'),
url(r'^(?P<poll_id>\d+)/vote/$', 'polls.views.vote'),
)
under my urls.py I have use generic views.
Problem is: how will I put login required under the "index" of the polls app. So that the user will login first before he/she can view the available polls.
Current is: I have used login required under my views.py and method vote(), It will require login after voting.
anyone can help me out?
Thanks,
Justin

1nd approach
In urls.py:
urlpatterns = patterns('',
url(r'^$',
login_required(ListView.as_view(
queryset = Poll.objects.order_by('-pub_date')[:5],
context_object_name = 'latest_poll_list',
template_name = 'polls/index.html'), name='poll_lists')),
)
2nd approach
In views.py:
class IndexView(ListView):
queryset = Poll.objects.order_by('-pub_date')[:5]
context_object_name = 'latest_poll_list'
template_name = 'polls/index.html'
#method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(IndexView, self).dispatch(request, *args, **kwargs)
then in urls.py
urlpatterns = patterns('',
url(r'^$',
IndexView.as_view(), name='poll_lists'),
)

Just providing a potentially more up-to-date answer,
I would move them to a views file and use the LoginRequiredMixin,
from django.views.generic import (
ListView,
DetailView
)
from django.contrib.auth.mixins import LoginRequiredMixin
class PollsListView(LoginRequiredMixin, ListView):
model = Poll
template_name = 'polls/index.html'

Related

Not redirecting to home page in Django. While putting http://127.0.0.1:8000/home/connect/jhvjhb/3 in url

Image Showing Error and Request
When entering http://127.0.0.1:8000/home/connect/jhvjhb/3 in url as url is defined to take some random letters and at last primary key. It should redirect to home but its not working. I do not have idea about regular expressions.
urls.py
from django.urls import path
from home.views import HomeView
from . import views
app_name = 'home'
urlpatterns = [
path('', HomeView.as_view(), name="home"),
path('connect/(?P<operation>.+)/(?P<pk>\d+)/', views.change_friends, name='change_friends')
]
moddels.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Post(models.Model):
post = models.CharField(max_length=500)
user = models.ForeignKey(User, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Friend(models.Model):
users = models.ManyToManyField(User)
current_user = models.ForeignKey(User, related_name='owner', null=True,on_delete=models.CASCADE)
#classmethod
def make_friend(cls, current_user, new_friend):
friend, created = cls.objects.get_or_create(
current_user=current_user
)
friend.users.add(new_friend)
#classmethod
def lose_friend(cls, current_user, new_friend):
friend, created = cls.objects.get_or_create(
current_user=current_user
)
friend.users.remove(new_friend)
views.py
from django.views.generic import TemplateView
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from .forms import HomeForm
from .models import Post
class HomeView(TemplateView):
template_name = 'home/home.html'
def get(self, request):
form = HomeForm()
posts = Post.objects.all().order_by('-created')
users = User.objects.exclude(id=request.user.id)
args = {'form':form, 'posts':posts, 'users':users}
return render(request, self.template_name, args)
def post(self, request):
form = HomeForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.user = request.user
post.save()
form = HomeForm()
return redirect('home:home')
args = {'form':form, 'text':text}
return render(request, self.template_name, args)
def change_friends(request, operation, pk):
return redirect('home:home')

Getting an error : Reverse for 'college' not found. 'college' is not a valid view function or pattern name

urls.py:
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views
app_name = 'accounts'
urlpatterns = [
path('login/', auth_views.LoginView.as_view(template_name="accounts/login.html"),name='login'),
path('logout/', auth_views.LogoutView.as_view(), name="logout"),
path('college/', views.CollegeView.as_view(), name="college"),
path('signup/', views.SignUp.as_view(), name="signup"),
]
views.py
from django.contrib.auth import login, logout
from django.urls import reverse_lazy
from django.views.generic import CreateView
from . import forms
from accounts.models import College
# Create your views here.
class CollegeView(CreateView):
form_class = College
fields = ['college']
success_url = reverse_lazy("login")
template_name = "accounts/college.html"
class SignUp(CreateView):
form_class = forms.UserCreateForm
success_url = reverse_lazy("college")
template_name = "accounts/signup.html"
forms.py
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm
from django import forms
class UserCreateForm(UserCreationForm):
class Meta:
model = get_user_model()
fields = ("username", "email", "password1", "password2")
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["username"].label = "Display name"
self.fields["email"].label = "Email address"
class CollegeForm(forms.Form):
fields = ("college")
If i try to redirect the success url to login or logout then it works but for college it is not working
It seems you're using namespaces for urls.
Try to set success_url according to app_name like this:
success_url = reverse_lazy("accounts:college")
Or remove namespace from the root urls.py file in include method

redirect() not directing to proper view

I am trying to use the redirect() method redirect to my index view upon successful submission of the form found in my register view.
I have the following urls.py:
from django.contrib import admin
from django.urls import path
from users import views as usersViews
urlpatterns = [
path('admin/', admin.site.urls),
path('', usersViews.index, name = 'index'),
path('register/', usersViews.register, name = 'regsister'),
]
and the following views.py:
from django.shortcuts import render, redirect
from .forms import RegistrationForm
from django.http import HttpResponse
# Create your views here.
def index(request):
return HttpResponse('signed up')
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save() # save form? to db?
username = form.cleaned_data.get('username')
email = form.cleaned_data.get('email')
return redirect("index") #this statement is not working
else:
form = RegistrationForm()
return render(request, 'users/registration.html', {'registrationForm':form})
Upon submission of the form I am being redirected to "/register/index.html" and not "/" (index page). Can anyone help with this?
Try it with reverse:
from django.urls import reverse
return redirect(reverse('app_name:view_name'), {'registrationForm':form})

DoesNotExist at /admin/login/ , django admin not working, django registration redux

iam new to django and i started a blog app. after a while when i want to login
into the admin 0.0.0.1:8000/admin I get an error
DoesNotExist at /admin/login/
Site matching query does not exist.
I have no idea why. Maybe it has something to do, that I installed django-registration-redux or with my urlpatterns in main and in the blog app.
Maybe somebody can give me advice also about better urlpatterns?
My main aim is to do a create view with login required mixin. This doesnt work too when i put the loginrequiredmixin in the class blog_postCreateView.
I appreciate every help. Iam new (noob). Looking forward for your answer.
IF there is anything what i can improve just tell me , thanks
Thanks a lot
main url
from django.conf.urls import url, include
from django.contrib import admin
from blog.views import AboutPageView, ContactPageView, blog_postCreateView
urlpatterns = [
url(r'', include('blog.urls')),
url(r'^blog/', include('blog.urls')),
url(r'^about/$', AboutPageView.as_view(), name='about'),
url(r'^contact/$', ContactPageView.as_view(), name='contact'),
url(r'^create/$', blog_postCreateView.as_view(), name='blog_post_create'),
#admin and login
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include('registration.backends.default.urls')),
]
blog urls
from django.conf.urls import url
from .views import blog_postListView, blog_postDetailView, blog_postCreateView
urlpatterns = [
url(r'^$', blog_postListView.as_view(), name='blog_post_list'),
url(r'^(?P<slug>[-\w]+)$', blog_postDetailView.as_view(), name='blog_post_detail'),
]
views
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from django.http import HttpResponse
from django.views.generic import View
from django.views.generic.base import TemplateView, TemplateResponseMixin, ContextMixin
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.shortcuts import render
from django.utils.decorators import method_decorator
from .models import blog_post
from .forms import blog_postForm
# Create your views here.
class LoginRequiredMixin(object):
#classmethod
def as_view(cls, **kwargs):
view = super(LoginRequiredMixin, cls).as_view(**kwargs)
return login_required(view)
##method_decorator(login_required)
#def dispatch(self, request, *args, **kwargs):
# return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
class blog_postCreateView(CreateView):
#model = blog_post
form_class = blog_postForm
template_name = "form.html"
#fields = ["title", "content"]
def get_success_url(self):
return reverse("blog_post_list")
# #method_decorator(login_required)
# def dispatch(self, request, *args, **kwargs):
# return super(MyView, self).dispatch(request, *args, **kwargs)
class blog_postListView(ListView):
model = blog_post
def get_queryset(self, *args, **kwargs):
qs = super(blog_postListView, self).get_queryset(*args, **kwargs).order_by("-timestamp")
return qs
class blog_postDetailView(DetailView):
model = blog_post
class AboutPageView(TemplateView):
template_name = "about.html"
class ContactPageView(TemplateView):
template_name = "contact.html"
models
from __future__ import unicode_literals
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models.signals import pre_save, post_save
from django.utils.text import slugify
# Create your models here.
class blog_post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
title = models.CharField(max_length=120)
slug = models.SlugField(unique=True)
content = models.TextField()
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
def __unicode__(self):
return self.title
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("blog_post_detail", kwargs={"slug": self.slug})
def create_slug(instance, new_slug=None):
slug = slugify(instance.title)
if new_slug is not None:
slug = new_slug
qs = blog_post.objects.filter(slug=slug).order_by("-id")
exists = qs.exists()
if exists:
new_slug = "%s-%s" %(slug, qs.first().id)
return create_slug(instance, new_slug=new_slug)
return slug
def pre_save_post_receiver(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = create_slug(instance)
pre_save.connect(pre_save_post_receiver, sender=blog_post)
forms
from django import forms
from .models import blog_post
class blog_postForm(forms.ModelForm):
class Meta:
model = blog_post
fields = [
'title',
'content',
]

how to login a user using forms?

forms.py:
from django import forms
from django.contrib.auth import authenticate, get_user_model
from django.contrib.auth.models import User
from django.forms import ModelForm
from django.utils.text import capfirst
from .models import Classname, Sectionname, Teachername, Attendancename
class AuthenticationForm(forms.Form):
username = forms.CharField(max_length=20)
password = forms.CharField(widget=forms.PasswordInput)
error_messages = {
'invalid_login': ("Please enter a correct %(username)s and password."
"Note that both fields may be case-sensitive."),
'inactive': ("This account is inactive"),
}
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
if username and password:
self.user_cache = authenticate(username=username, password=password)
if self.user_cache is None:
raise forms.ValidationError(
self.error_messages['invalid_login'],
code='invalid_login',
)
else:
self.confirm_login_allowed(self.user_cache)
return self.cleaned_data
def confirm_login_allowed(self, user):
if user.is_active:
login(self.user) /** It raises error here... **/
else:
raise forms.ValidationError(
self.error_messages['inactive'],
code='inactive',
)
def get_user_id(self):
if self.user_cache:
return self.user_cache.id
return None
def get_user(self):
return self.user_cache
views.py:
from django.shortcuts import render, get_object_or_404
from django.core.urlresolvers import reverse
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.http import Http404, HttpResponseRedirect, HttpResponse
from django.template.response import TemplateResponse
from django.views.generic import DeleteView, ListView
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.cache import never_cache
from .models import Classname, Sectionname, Teachername, Attendancename
from .forms import ClassnameForm, SectionnameForm, TeachernameForm, AttendancenameForm, UserForm, PasswordChangeForm, AuthenticationForm
def user_login(request):
if request.method == 'POST':
form = AuthenticationForm(request.POST)
if form.is_valid():
return HttpResponseRedirect(reverse('student:mains'))
else:
print(form.errors)
else:
form = AuthenticationForm()
return render(request, 'login.html', {'form': form},)
urls.py:
from django.conf.urls import url, patterns
from django.contrib.auth import views as auth_views
from . import views
urlpatterns = [
url(r'^register/$', views.register, name='register'),
url(r'^login/$', views.user_login, name='login'),
url(r'^logout/$', views.user_logout, name='logout'),
url(r'^password_change/$', auth_views.password_change, {'template_name': 'password_change_form.html', 'post_change_redirect': '/stu/password_change/done/'}, name="password_change"),
url(r'^password_change/done/$', auth_views.password_change_done, {'template_name': 'password_change_done.html'}, name="password_change_done"),
url(r'^restricted/', views.restricted, name='restricted'),
url(r'^mains/', views.mains, name = 'mains'),
]
I'm new to django authentication. I'm trying to make things as per the docs I have read. As your see above I've a 'user_login' view and 'AuthenticationForm' form.
I'm tring to login the user, but don't know the way how to do it? As I tried it in my view but didn't worked.
Then I tried it in my 'can_login_allowed' form's method but doesn't work.
Is there any other method to implement it?
Please! Can Anybody help me to fix it?
Thanks in Advance....
The login function takes request as first parameter. So you have write confirm_login_allowed like this:
def confirm_login_allowed(self, request):
if self.user_cache.is_active:
login(request,self.user_cache)
else:
raise forms.ValidationError(
self.error_messages['inactive'],
code='inactive',
)
And call it in the view like this
def user_login(request):
if request.method == 'POST':
form = AuthenticationForm(request.POST)
if form.is_valid():
form.confirm_login_allowed(request)
return HttpResponseRedirect(reverse('student:mains'))
else:
....
Also don't call the confirm_login_allowed method from clean method because it does't have the request.