Last active
September 5, 2018 20:29
-
-
Save mcihad/6a948f988de082e5a0fa932095e37e7b to your computer and use it in GitHub Desktop.
spring hasAnyRole or RolesAllowed annotation implementation for django
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.contrib.auth.decorators import user_passes_test | |
from django.contrib.auth import REDIRECT_FIELD_NAME | |
from django.core.exceptions import PermissionDenied | |
def has_any_role(roles, login_url=None, raise_exception=False): | |
def check_role(user): | |
if isinstance(roles, list): | |
perms = roles | |
if isinstance(roles, str): | |
perms = (roles, ) | |
if isinstance(roles, int): | |
perms = (roles,) | |
if user.profile.role in perms: | |
return True | |
if raise_exception: | |
raise PermissionDenied | |
return False | |
return user_passes_test(check_role, login_url=login_url) | |
#-----------------------models.py--------------------------------- | |
from django.contrib.auth.models import User | |
from django.db import models | |
from django.db.models.signals import post_save | |
from django.dispatch import receiver | |
class Profile(models.Model): | |
USER = 1 | |
SELLER = 2 | |
RESTAURANT = 3 | |
ROLE_CHOICES = ( | |
(USER, 'User'), | |
(SELLER, 'Seller'), | |
(RESTAURANT, 'Restaurant'), | |
) | |
user = models.OneToOneField(User, on_delete=models.CASCADE) | |
location = models.CharField(max_length=30, blank=True) | |
birthdate = models.DateField(null=True, blank=True) | |
role = models.PositiveSmallIntegerField( | |
choices=ROLE_CHOICES, null=True, blank=True) | |
def __str__(self): | |
return self.user.username | |
@receiver(post_save, sender=User) | |
def create_or_update_user_profile(sender, instance, created, **kwargs): | |
if created: | |
Profile.objects.create(user=instance, role=Profile.USER) | |
instance.profile.save() | |
#-----------------------admin.py--------------------------------- | |
from django.contrib import admin | |
from django.contrib.auth.admin import UserAdmin | |
from django.contrib.auth.models import User | |
from .models import Profile | |
class ProfileInline(admin.StackedInline): | |
model = Profile | |
can_delete = False | |
verbose_name_plural = 'Profile' | |
fk_name = 'user' | |
class CustomUserAdmin(UserAdmin): | |
inlines = [ProfileInline] | |
list_display = ('username', 'email', 'first_name', | |
'last_name', 'is_staff', 'get_location') | |
list_select_related = ('profile', ) | |
def get_location(self, instance): | |
return instance.profile.location | |
get_location.short_description = 'Location' | |
def get_inline_instances(self, request, obj=None): | |
if not obj: | |
return list() | |
return super(CustomUserAdmin, self).get_inline_instances(request, obj) | |
admin.site.unregister(User) | |
admin.site.register(User, CustomUserAdmin) | |
#-----------------------views.py--------------------------------- | |
from django.shortcuts import render | |
from django.http import HttpResponse | |
from .models import Profile | |
from .decorators import has_any_role | |
@has_any_role([Profile.USER, Profile.RESTAURANT]) | |
def index(req): | |
return HttpResponse("Selamlar") | |
#-----------------------urls.py--------------------------------- | |
from django.contrib import admin | |
from django.urls import path | |
from account import views | |
urlpatterns = [ | |
path('', views.index, name="home"), | |
path('admin/', admin.site.urls), | |
] | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment