Skip to content

Latest commit

 

History

History
160 lines (105 loc) · 3.7 KB

permissions.md

File metadata and controls

160 lines (105 loc) · 3.7 KB

/ Menu / Tasks / Permissions

Task: Permissions

Django comes with a powerful permission system out of the box.

Resources:



Table of contents:



Step 1: Register Permission

Django autogenerates permissions for all models in the database.
To get an overview, we can register the model Permission in the admin panel.

Solution
# blog/admin.py

from django.contrib import admin
from django.contrib.auth.models import Permission

admin.site.register(Permission)


Step 2: Assign permissions

Because you as a superuser have all permissions, create a new plain user you can use for testing.

Try to assign at least one user permission and one group permission on this user.

Solution

Browse admin panel



Step 3: Check permissions

Create a simple view where you return a json response containing the boolean result for both permissions in Step 2.

See solution: http://localhost:8002/user/`/`
(replace username with credentials from solution/.docker.env)

Hint:
The User object in Django is equipped with methods to check permissions, e.g. .has_perm(...).
A permission is identified as a string on the format <app_name>.<code_name>.

Django generates 4 basic/common permissions per model for us: create_*, change_*, view_*, delete_*.

Example:

some_user.has_perm('blog.delete_blogpost')
Solution
# blog/urls.py
from django.urls import path
from rest_framework import routers

from . import views

urlpatterns = [
    path('user/<str:username>/', views.PermissionTestView.as_view()),
]
# blog/views.py

from rest_framework.viewsets import ModelViewSet

from django.http import HttpResponse, HttpRequest, JsonResponse
from django.views import View
from django.contrib.auth.models import User


class PermissionTestView(View):

    def get(self, request: HttpRequest, username: str) -> JsonResponse:
        user = User.objects.get(username=username)
        can_delete = user.has_perm('blog.delete_blogpost')
        can_change = user.has_perm('blog.change_blogpost')
        data = {
            'can_delete': can_delete,
            'can_change': can_change,
        }
        return JsonResponse(data=data)



Bonus 1: Custom permission

Say you are in the middle of developing a new feature, why not create a custom permission to use this feature?

Imagine that each BlogPost can contain a video, use the Metaclass on BlogPost to enable feature-toggling.
Add another check to the view you created in Step 3.

Resource: https://docs.djangoproject.com/en/4.1/topics/auth/customizing/#custom-permissions

Hint:
Restart the server to let docker update permissions in the database with makemigrations and migrations.

Solution
# blog/models.py

from django.db import models

class BlogPost(models.Model):
    ...

    class Meta:
        permission = [
            ('feature_video_blogpost', 'Can use video feature on BlogPost'),
        ]


👈 Back to Tasks