2

At the moment, I plan to write a website where users can write blog posts. I haven't started with the implementation yet because I am new to Django and want to get an overview in how I should solve problems and structure the overall project.

My problem: The users aren't allowed to use Django's admin page (/admin). The users should only interact with the website that I write.

The users at my website will be able to create blog posts. Now, I have to ensure that only the creator of the blog post should be able to edit/delete his own post. All the other users should only be able to read this post.

So, I need permissions per user/instance. I know that there are some full-blown permission-systems like django-guardian, but I would like to prefer to solve it on my own. Also to better understand the Django framework.

I`ve already read the Django docs, but I am overwhelmed.

I guess this is such a common problem that I there is also a common solution to this problem. Can someone help me where I should look at, where to start?

My idea so far (please comment):

In create a page like blog/5/edit that is only accessible for the user that created the blog post number 5. This should be easily within the view function, right? On this page there is a Form to edit the blog post.

Something like this for the view (pseudo-code!)

if request.user != blogpost.user:
    redirect/error page
else:
    show Form/process Form

Is this secure? I haven't found such a solution so far while searching the internet. However, spontaneously and as a Django beginner, I think this could already by enough.

Aliquis
  • 2,091
  • 4
  • 21
  • 40
  • Yes, that's perfectly fine. – Daniel Roseman Mar 05 '18 at 11:30
  • You can use decorator for "your idea" and then you can apply the decorator to the view functions where you need the permission. You can see the existing decorator implementation for the same https://docs.djangoproject.com/en/2.0/_modules/django/contrib/auth/decorators/#login_required – Sachin G. Mar 05 '18 at 11:31

1 Answers1

1

Yes, you can do that. For that purpose I recommend to create an custom decorator like so:

decorators.py:

from django.core.exceptions import PermissionDenied
from .models import YourBlogPostModel

def user_is_blog_post_user(function):
    def wrap(request, *args, **kwargs):
        post = YourBlogPostModel.objects.get(pk=kwargs['blog_post_id'])
        if post.user == request.user:
            return function(request, *args, **kwargs)
        else:
            raise PermissionDenied
    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap

You can then use it in conjunction with other decorators.

views.py:

@login_required
@user_is_blog_post_user
def function_based_view(request, blog_post_id):
    # ...

Take a look here for a more detailed explanation.


If you are using CVB you can either create an own Mixin or decorate the class.

class UserIsBlogPostAdmin(object):
     """Verify that the current user is the user of the blog post."""
     def dispatch(self, request, *args, **kwargs):
         blog_post = get_object_or_404(YourBlogPostModel, pk=args[0])
         if blog_post.user != request.user
             raise Http404
         return super().dispatch(request, *args, **kwargs)
Yannic Hamann
  • 4,655
  • 32
  • 50