[Fixed]-Filtering content based on users in django

1👍

This is a common requirement – I’ve written a blog post about that: http://spapas.github.io/2013/11/05/django-authoritiy-data/ but instead of users having access to their objects, users have access to the objects of their “authority” (i.e group of users belonging to same department, company etc).

In any case, for all your models that you need to be visible/editable only by the users that created them, you need to add a foreign key field named created_by with the user that created the object to that model, something like:
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True)

After that, when creating the object you’ll have to update that field with the current user. For instance, if you use CBVs you can use the following mixin to fill the created_by field (taken from another blog post I’ve written about auditing for models @ http://spapas.github.io/2015/01/21/django-model-auditing/):

  class AuditableMixin(object,):
    def form_valid(self, form, ):
        if not form.instance.created_by:
            form.instance.created_by = self.request.user

        return super(AuditableMixin, self).form_valid(form)

After that, when displaying/updating a list of othese objects (through ListView, UpdateView, DetailView) you can override the get_queryset method so that it will filter only on the results having a created by similar to the current user. Something like this:

  class OnlyMineMixin(object, ):
    def get_queryset(self):
        qs = super(OnlyMineMixin, self).get_queryset()
        return qs.filter(created_by=self.request.user)

Now all CBVs that use this mixin will only have access to objects belonging to the current user.

0👍

If you want to allow the users to see only the items they created, here is an simple example that can achieve this behaviour:

views.py

from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404, redirect, render

def show_items(request, username):
    user = get_object_or_404(User, username=username)
    if request.user == user:
        # get the items for the user, assuming there is a model item
        items = user.items.all()
    else:
        # redirect the user to the login page or whatever you want
        return redirect('login.html')
    return render(request, 'items.html', {items: items})

As I wrote, this is just a very simple example to give you an idea how to start. You have to adapt and further extend it.

👤cezar

Leave a comment