检查用户是否有权访问对象

时间:2014-03-05 12:09:49

标签: django django-templates

我想根据成员包检查user.profile是否允许查看所有的好处对象。 (如果用户没有访问权限,他应该能够看到对象的某些字段(名称和包)

如果用户拥有memberpackage Package1并且正在查看Package1中的权益,那么他应该能够看到body字段。如果用户具有memberpackage Package2,则他应该无法看到body字段。

这可能吗?也许这可以用templatetag完成? {% if user_has_access_to_benfit %}它会返回真或假。

这样的事情:

{{ object.name }}

{% if user_has_access_to_benfit %}
    {{ object.body }}
{% else %}
    <p>Sorry! You don't have access to this object.</p>
{% endif %}

-

以下是我根据答案尝试的内容:

class Profile(models.Model):
    user = models.OneToOneField(User)
    memberpackage = models.ForeignKey(Package, blank=True, null=True)



class Package(models.Model):
    name = models.CharField(max_length=200)    

class Benefit(models.Model):
    PUBLISHED = 'P'
    DRAFT = 'U'
    PULLED = 'X'
    name = models.CharField(max_length=200)
    body = models.TextField(blank=True, null=True, help_text="Only visible to those members in the same memberpackage")    
    package = models.ManyToManyField(Package, blank=True, null=True, related_name="in_package")
    status = models.CharField(max_length=1, choices=STATUS_CHOICES, default=DRAFT)    



    def is_viewable_by(self, user):
        return self.package.filter(id=user.profile.memberpackage_id).exists()                

编辑:

如果我这样做(福利中的资本B)

#View for listing one benefit
class BenefitDetailView(DetailView):

    template_name_field = 'template_name'

    model = Benefit        

    queryset = Benefit.objects.exclude(status="X")


    def get(self, request, *args, **kwargs):
        if request.user.is_authenticated():
            context['user_has_access_to_benfit'] = Benefit.is_viewable_by(request.user)

我收到此错误:

unbound method is_viewable_by() must be called with Benefit instance as first argument (got User instance instead)

编辑2:

尝试另一种方式

#View for listing one benefit
class BenefitDetailView(DetailView):

    template_name_field = 'template_name'

    model = Benefit

    queryset = Benefit.objects.exclude(status="X")


    def get(self, request, *args, **kwargs):
        if request.user.is_authenticated():
            user_has_access_to_benfit = Benefit.objects.filter(package = request.user.profile.memberpackage).exists() #Hoping this function returns true or false
        #The user is not logged in, user_has_access_to_benfit should be set to False
        else:
            user_has_access_to_benfit = False

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super(BenefitDetailView, self).get_context_data(**kwargs)
        # Add in a extra context
        context['user_has_access_to_benfit'] = user_has_access_to_benfit
        return context

但我收到错误:The view app.views.BenefitDetailView didn't return an HttpResponse object.

不确定在DetailView中是否有另一种获取request.user.is_authenticated()的方式?

4 个答案:

答案 0 :(得分:2)

Benefit课程中:

Benefit(models.Model):
  ...
  def is_viewable_by(self, user):
      return self.package.filter(id=user.profile.memberpackage_id).exists()

BenefitDetailView课程中:

BenefitDetailView(DetailView):
  def get_context_data(self, **kwargs):
    context = super(BenefitDetailView, self).get_context_data(**kwargs)
    if self.object and self.request.user.is_authenticated():
      context.update({ 'has_benefit_access': self.object.is_viewable_by(self.request.user)})
    return context

由于is_viewable_by是实例方法,而不是类方法,因此需要在Benefit的实例上调用它。 self.object是您要使用的实例。 request对象在View的每个子类中都可用self.request

如果不是每个经过身份验证的用户都有关联的配置文件,请记住is_viewable_by会抛出需要捕获的ObjectDoesNotExist异常。

在这种情况下,绝对不需要覆盖get方法,但如果这样做,则需要返回HttpResponse个对象。确保这一点的最简单方法是返回超类“get方法的值:

class BenefitDetailView(DetailView):
  def get(self, request, *args, **kwargs):
    # ***do stuff***
    return super(BenefitDetailView, self).get(request, *args, **kwargs)

答案 1 :(得分:0)

假设benefit是您要在您的视图中测试的福利对象:

user_has_access_to_benfit = request.user.profile.memberpackage in benefit.package.all()

然后将user_has_access_to_benfit放在您的上下文中。

答案 2 :(得分:0)

class Benefit(models.Model):
    ...
    def is_viewable_by(self, user):
        return self.package.filter(id=user.profile.memberpackage_id).exists()

然后在视图中:

context['user_has_access_to_benfit'] = benefit.is_viewable_by(request.user)

在您的问题更新后,您需要查看我的另一个答案https://stackoverflow.com/a/22183068/1420159

答案 3 :(得分:0)

@Audrey:您忘记了方法定义中的self参数:

def is_viewable_by(self, user):
    ...              ^