我想根据成员包检查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)
尝试另一种方式
#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()
的方式?
答案 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):
... ^