1

In my web, user and admin user both login from frontend. Now I want to do that some of URLs are accessed by public user only. Is_staff user not access that URL. How do I do that?

Updated:
Can I use any decorator for this?

Matheus Lacerda
  • 5,983
  • 11
  • 29
  • 45
SuReSh
  • 1,503
  • 1
  • 22
  • 47

2 Answers2

3

If you want to use a decorator, you can use the user_passes_test. First define a test function that checks that the user is not a staff member.

def is_not_staff(user):
    return not user.is_staff

You can change the function to check user.is_authenticated (user.is_authenticated() in Django <=1.9) as well, if you don't want anonymous users to be able to access the view.

Then use user_passes_test with your test function to decorate the view you wish to protect.

@user_passes_test(is_not_staff)
def non_staff_view(request):
    ... 
Alasdair
  • 298,606
  • 55
  • 578
  • 516
1

You can simply inherit LoginRequiredMixin and create your own custom access mixin as below:

class AccessMixin(LoginRequiredMixin):
    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated or request.user.is_staff:
            return self.handle_no_permission()
        return super().dispatch(request, *args, **kwargs)

Now you just need to inherit AccessMixin in your view as below:

class HomePageView(AccessMixin, TemplateView):
    login_url = <login-url>
    ...
    ...

So anonymous user and staff user won't be able to access the content of the page.


You can also mention the same in your base template html

Consider you have created a base.html which extends content block and you can add permission as below: Ex. base.html

{% if user.is_authenticated %}
    {% if user.is_staff %}
         <h3>Not allowed to access this page</h3>
    {% else %}
         {% block content %} {% endblock %}
    {% endif %}
{% endif %}

this way when you extend base.html in your template all the content you write within {% block content %} {% endblock %} will only be rendered for non-staff logged in user.

Gahan
  • 4,075
  • 4
  • 24
  • 44
  • 1
    Instead of subclassing `LoginRequiredMixin`, another option would be [`UserPassesTestMixin`](https://docs.djangoproject.com/en/2.0/topics/auth/default/#django.contrib.auth.mixins.UserPassesTestMixin) – Alasdair Apr 25 '18 at 11:20
  • @Alasdair agreed!, but I believe you need to write test function too in child class hence need to create custom mixin for it too to avoid writing the same function multiple times. – Gahan Apr 25 '18 at 11:23