I am trying to check if account settings view, and username is a superuser then render the html. if not goes to error 403 , but how can I do this using templateview
class AccountSettingsView(LoginRequiredMixin, TemplateView):
template_name = 'profile/account-settings.html'
if request.user.is_superuser:
# error 403
else:
template_name
You can use the UserPassesTestMixin mixin [Django-doc] for that, and then override the test_func(..) method [Django-doc]:
from django.contrib.auth.mixins import UserPassesTestMixin
class AccountSettingsView(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
template_name = 'profile/account-settings.html'
def test_func(self):
return self.request.user.is_superuser
You can override the dispatch method and check that condition there:
class AccountSettingsView(LoginRequiredMixin, TemplateView):
template_name = 'profile/account-settings.html'
def dispatch(self, request, *args, **kwargs):
if self.request.user.is_superuser:
# raise 403
return super().dispatch(request, *args, **kwargs)
Related
I am trying to perform an action from superuser accept/reject the task, but after login from superuser it show the error. even if i logged in from non superuser if show the same error
403 Forbidden
i am trying first time perform action from superuser i don't know how can i fix this issue
View.py
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
class Approval(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
def test_func(self):
if self.request.user == User.is_superuser:
return True
else:
return False
template_name = 'approve.html'
def get(self, request, *args, **kwargs):
return render(request, self.template_name)
def post(self, request):
Urls.py
urlpatterns = [
path('approve',Approval.as_view(), name='approve')
]
You check if the user is a superuser with:
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
class Approval(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
template_name = 'approve.html'
def test_func(self):
return self.request.user.is_superuser
def get(self, request, *args, **kwargs):
return render(request, self.template_name, {'all_saloon': all_saloon})
The all_saloon is however strange: it means that if it is a list or QuerySet it will each time work with the same data, and thus if later a new Saloon is constructed, it will not take that into account.
You can alter the handle_no_permission function to determine what to do in case the test fails:
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.shortcuts import redirect
class Approval(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
template_name = 'approve.html'
def test_func(self):
return self.request.user.is_superuser
def handle_no_permission(self):
return redirect('name-of-some-view')
def get(self, request, *args, **kwargs):
return render(request, self.template_name, {'all_saloon': all_saloon})
Likely you want to work with a ListView [Django-doc] instead.
I want to check if user in true editUser before open url and create post,
urls.py", line 13, in
path('new/', PostCreateView.as_view(), name='new_post'),
AttributeError: 'NoneType' object has no attribute 'as_view'
def notLoggedUsers(view_func):
def wrapper_func(request,*args,**kwargs):
if not request.user.profile.editUser:
return redirect('index')
else:
return view_func(request,*args,**kwargs)
return wrapper_func
#notLoggedUsers
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
template_name = 'crud/new_post.html'
form_class = PostForm
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
Firstly your decorator has a small mistake, the indentation for return wrapper_func is wrong. Next to decorate class based views you should use method_decorator [Django docs] and specify the method of the class that should be decorated (Decorate the dispatch method if it needs to decorate the complete view):
from django.utils.decorators import method_decorator
def notLoggedUsers(view_func):
def wrapper_func(request, *args, **kwargs):
if not request.user.profile.editUser:
return redirect('index')
else:
return view_func(request, *args, **kwargs)
return wrapper_func
#method_decorator(notLoggedUsers, name='dispatch')
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
template_name = 'crud/new_post.html'
form_class = PostForm
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
You should not decorate your class-based view with a decorator that returns a function, since then that function has no .as_view attribute.
Django has some tooling to apply a decorator to a function of the class-based view, we can however also implement a mixin and work with that mixin:
from django.contrib.auth.mixins import UserPassesTestMixin
from django.shortcuts import redirect
class EditUserPermissionPlugin(LoginRequiredMixin, UserPassesTestMixin):
def test_func(self):
try:
return self.user.profile.editUser
except Profile.DoesNotExist:
return False
def handle_no_permission(self):
return redirect('index')
Then we can use this for our view:
class SomeCreateView(EditUserPermissionPlugin, CreateView):
# …
I am currently using Django-registration-redux for my authentication system.
Already logged in user can visit the login and registration page again; which is not good enough. How can I prevent them from this since the views.py comes by default in Django-registration-redux
I think that should be done in the views.py that come with Django-registration-redux
Here is the views.py
"""
Views which allow users to create and activate accounts.
"""
from django.shortcuts import redirect
from django.views.generic.base import TemplateView
from django.views.generic.edit import FormView
from django.conf import settings
from django.utils.decorators import method_decorator
from django.views.decorators.debug import sensitive_post_parameters
try:
from django.utils.module_loading import import_string
except ImportError:
from registration.utils import import_string
from registration import signals
# from registration.forms import RegistrationForm
REGISTRATION_FORM_PATH = getattr(settings, 'REGISTRATION_FORM', 'registration.forms.RegistrationFormUniqueEmail')
REGISTRATION_FORM = import_string( REGISTRATION_FORM_PATH )
class _RequestPassingFormView(FormView):
"""
A version of FormView which passes extra arguments to certain
methods, notably passing the HTTP request nearly everywhere, to
enable finer-grained processing.
"""
def get(self, request, *args, **kwargs):
# Pass request to get_form_class and get_form for per-request
# form control.
form_class = self.get_form_class(request)
form = self.get_form(form_class)
return self.render_to_response(self.get_context_data(form=form))
def post(self, request, *args, **kwargs):
# Pass request to get_form_class and get_form for per-request
# form control.
form_class = self.get_form_class(request)
form = self.get_form(form_class)
if form.is_valid():
# Pass request to form_valid.
return self.form_valid(request, form)
else:
return self.form_invalid(form)
def get_form_class(self, request=None):
return super(_RequestPassingFormView, self).get_form_class()
def get_form_kwargs(self, request=None, form_class=None):
return super(_RequestPassingFormView, self).get_form_kwargs()
def get_initial(self, request=None):
return super(_RequestPassingFormView, self).get_initial()
def get_success_url(self, request=None, user=None):
# We need to be able to use the request and the new user when
# constructing success_url.
return super(_RequestPassingFormView, self).get_success_url()
def form_valid(self, form, request=None):
return super(_RequestPassingFormView, self).form_valid(form)
def form_invalid(self, form, request=None):
return super(_RequestPassingFormView, self).form_invalid(form)
class RegistrationView(_RequestPassingFormView):
"""
Base class for user registration views.
"""
disallowed_url = 'registration_disallowed'
form_class = REGISTRATION_FORM
http_method_names = ['get', 'post', 'head', 'options', 'trace']
success_url = None
template_name = 'registration/registration_form.html'
#method_decorator(sensitive_post_parameters('password1', 'password2'))
def dispatch(self, request, *args, **kwargs):
"""
Check that user signup is allowed before even bothering to
dispatch or do other processing.
"""
if not self.registration_allowed(request):
return redirect(self.disallowed_url)
return super(RegistrationView, self).dispatch(request, *args, **kwargs)
def form_valid(self, request, form):
new_user = self.register(request, form)
success_url = self.get_success_url(request, new_user)
# success_url may be a simple string, or a tuple providing the
# full argument set for redirect(). Attempting to unpack it
# tells us which one it is.
try:
to, args, kwargs = success_url
return redirect(to, *args, **kwargs)
except ValueError:
return redirect(success_url)
def registration_allowed(self, request):
"""
Override this to enable/disable user registration, either
globally or on a per-request basis.
"""
return True
def register(self, request, form):
"""
Implement user-registration logic here. Access to both the
request and the full cleaned_data of the registration form is
available here.
"""
raise NotImplementedError
class ActivationView(TemplateView):
"""
Base class for user activation views.
"""
http_method_names = ['get']
template_name = 'registration/activate.html'
def get(self, request, *args, **kwargs):
activated_user = self.activate(request, *args, **kwargs)
if activated_user:
success_url = self.get_success_url(request, activated_user)
try:
to, args, kwargs = success_url
return redirect(to, *args, **kwargs)
except ValueError:
return redirect(success_url)
return super(ActivationView, self).get(request, *args, **kwargs)
def activate(self, request, *args, **kwargs):
"""
Implement account-activation logic here.
"""
raise NotImplementedError
def get_success_url(self, request, user):
raise NotImplementedError
Here is my main/project urls.py
urlpatterns = [
url( 'admin/', admin.site.urls),
url(r'^$', views.home, name='homepage'),
url(r'^user/', include('User.urls')),
#url(r'^accounts/register/$', MyRegistrationView.as_view(),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Thanks, any help will be appreciated
Below are the file showing identation error
indentaion error
views file
In the dispatch method of your views you can check if the user is authenticated and redirect them to another page, for example:
class RegistrationView(_RequestPassingFormView):
...
#method_decorator(sensitive_post_parameters('password1', 'password2'))
def dispatch(self, request, *args, **kwargs):
"""
Check that user signup is allowed before even bothering to
dispatch or do other processing.
"""
if request.user.is_authenticated:
return redirect('some_url')
if not self.registration_allowed(request):
return redirect(self.disallowed_url)
return super(RegistrationView, self).dispatch(request, *args, **kwargs)
The if user.is_authenticated prevents both logged-in and not-logged-in user from accessing the registration page.
class RegistrationView(_RequestPassingFormView):
"""
Base class for user registration views.
"""
disallowed_url = 'registration_disallowed'
form_class = REGISTRATION_FORM
http_method_names = ['get', 'post', 'head', 'options', 'trace']
success_url = None
template_name = 'registration/registration_form.html'
#method_decorator(sensitive_post_parameters('password1', 'password2'))
def dispatch(self, request, *args, **kwargs):
"""
Check that user signup is allowed before even bothering to
dispatch or do other processing.
"""
if self.request.user.is_authenticated:
return redirect('/')
if not self.registration_allowed(request):
return redirect(self.disallowed_url)
return super(RegistrationView, self).dispatch(request, *args, **kwargs)
def form_valid(self, request, form):
new_user = self.register(request, form)
success_url = self.get_success_url(request, new_user)
# success_url may be a simple string, or a tuple providing the
# full argument set for redirect(). Attempting to unpack it
# tells us which one it is.
try:
to, args, kwargs = success_url
return redirect(to, *args, **kwargs)
except ValueError:
return redirect(success_url)
def registration_allowed(self, request):
"""
Override this to enable/disable user registration, either
globally or on a per-request basis.
"""
return True
def register(self, request, form):
"""
Implement user-registration logic here. Access to both the
request and the full cleaned_data of the registration form is
available here.
"""
raise NotImplementedError
Suppose you want to give out
{field1, field2, field3} on detail request.
{field1, field2} on list request.
{field1} on some other simpler list request.
I have seen examples using get_serializer_class with self.action which can handle detail vs list scenario. (https://stackoverflow.com/a/22755648/433570)
Should I define two viewsets and two url endpoints?
Or is there a better approach here?
I guess this could be applied to tastypie as well. (two resources?)
I haven't tested it myself but I think you can do it overriding the methods you need.
According to the documentation (Marking extra actions for routing) you could do:
class UserViewSet(viewsets.ViewSet):
"""
Example empty viewset demonstrating the standard
actions that will be handled by a router class.
If you're using format suffixes, make sure to also include
the `format=None` keyword argument for each action.
"""
def list(self, request):
pass
def create(self, request):
pass
def retrieve(self, request, pk=None):
pass
def update(self, request, pk=None):
pass
def partial_update(self, request, pk=None):
pass
def destroy(self, request, pk=None):
pass
Or if you need custom methods:
from django.contrib.auth.models import User
from rest_framework import status
from rest_framework import viewsets
from rest_framework.decorators import detail_route, list_route
from rest_framework.response import Response
from myapp.serializers import UserSerializer, PasswordSerializer
class UserViewSet(viewsets.ModelViewSet):
"""
A viewset that provides the standard actions
"""
queryset = User.objects.all()
serializer_class = UserSerializer
#detail_route(methods=['post'])
def set_password(self, request, pk=None):
user = self.get_object()
serializer = PasswordSerializer(data=request.DATA)
if serializer.is_valid():
user.set_password(serializer.data['password'])
user.save()
return Response({'status': 'password set'})
else:
return Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
#list_route()
def recent_users(self, request):
recent_users = User.objects.all().order('-last_login')
page = self.paginate_queryset(recent_users)
serializer = self.get_pagination_serializer(page)
return Response(serializer.data)
Is it possible to have a class based view delegate to a particular class-based view? Specifically what I'd like to do is have / point to a view called 'home' and the home view with delegate to View A if the user is logged in, or View B if no user is logged in. Alternatively I could do a redirect to a different URL. I'm not sure what would be the best practice here.
You can call another view from within a view in the same manner used in urls
class HomeView( TemplateView ):
template_name="index.html"
def dispatch( self, request, *args, **kwargs ):
if request.user.is_authenticated():
view=UserHomeView.as_view()
return view( request, *args, **kwargs )
return super( HomeView, self ).dispatch( request, *args, **kwargs )
class UserHomeView( TemplateView ):
template_name="user.html"
You can just redirect to a different url and that url is also served by a class based view.
urls.py
url(r'^$', HomeView.as_view(), name='home'),
url(r'^login/', LoginView.as_view(), name='login'),
url(r'^welcome/$', WelcomeView.as_view(), name='welcome')
views.py
class HomeView(TemplateView):
def get(self, request, *args, **kwargs):
if request.user.is_authenticated():
return HttpResponseRedirect(reverse('welcome'))
else:
return HttpResponseRedirect(reverse('login'))
class WelcomeView(TemplateView):
def get(self, request, *args, **kwargs):
#do something
class LoginView(TemplateView):
def get(self, request, *args, **kwargs):
#show login page
Best practice to ensure that user must be authenticated is use Mixin:
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView
class LoginRequiredMixin(object):
u"""Ensures that user must be authenticated in order to access view."""
#method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(LoginRequiredMixin, self).dispatch(*args, **kwargs)
class MyView(LoginRequiredMixin, TemplateView):
def get(self, request, *args, **kwargs):
#do something