Andrew Bregman
Andrew Bregman

Reputation: 170

user_passes_test for models other than User in Django

I want to allow a user to edit a project page if ifAdmin (an object in uProject model) == True. I am currently trying to use @user_passes_test to render a view to update the project, but am having difficulties. I am getting uProjects from main.models, and I am working in projects.views. Here's my code.

def admin_check(uProjects):
    return uProjects.ifAdmin = True

@user_passes_test(admin_check)
def update(request): etc, etc, etc

models.py

class uProjects(models.Model):
   
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    ifAccepted = models.BooleanField(null = True, blank=False, default=False)
    #ifLeader = models.BooleanField(null = False, blank=False)
    ifAdmin = models.BooleanField(null = True, blank=False, default=False)
    title = models.CharField(max_length=100, null=False, blank=False)
    def __str__(self):
        return self.user.username + ',' + self.project.name

The difficulty is I'm trying to have admin_check work with uProjects, not the User model. I'm also trying to see if ifAdmin == True, but the way I did above renders an error. The error is that the "User object has no attribute ifAdmin"

Upvotes: 0

Views: 552

Answers (1)

ruddra
ruddra

Reputation: 51988

You can use something like this:

def admin_check(user):
    return user.uprojects_set.filter(ifAdmin=True).exists()

@user_passes_test(admin_check)
def update(request): etc, etc, etc

But this will work for any user which has ifAdmin permission in atleast one uProject instance. It can't distinguish by uProject information.

To do that, you can write a custom dectorator like this:

from functools import wraps
from django.http import HttpResponseRedirect

def admin_check(function):
  @wraps(function)
  def wrap(request, *args, **kwargs):
        user = request.user
        name = kwargs.get('name')  # assuming you are getting the project id here via url: "/<project_id:int>"
        if uProjects.objects.filter(title=name, user=user, ifAdmin=True).exists():
             return function(request, *args, **kwargs)
        else:
            return HttpResponseRedirect('/')

  return wrap

Upvotes: 2

Related Questions