2014-03-05 38 views
0

我想檢查user.profile是否有權根據成員包查看所有利益對象。 (如果用戶沒有訪問權限,他應該能夠看到對象的某些字段(名稱和包)檢查用戶是否有權訪問對象

如果用戶有成員包Package1並且正在查看Package1中的權益,他應該能夠看到body領域。如果用戶memberpackage Package2他不應該能夠看到body領域。

這是可能的嗎?也許這可以用templatetag做?{% if user_has_access_to_benfit %},它會返回true或false。

類似這樣的:

{{ 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()的另一種方式?

回答

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) 
+0

這是完美的!謝謝。當我被允許時,我會獎賞你的賞金。 –

0

假設benefit是要測試的好處對象,在你看來:

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

然後把user_has_access_to_benfit在你的環境。

+0

我得到這個錯誤:'‘ReverseManyRelatedObjectsDescriptor’對象有沒有屬性「all'' –

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

+0

如果我這樣做'benefit.is_viewable_by(request.user)'我得到這個錯誤:'沒有定義全局名'好處'。如果我首先添加'benefit = Benefit.objects.all()',我會得到這個錯誤:'QuerySet'對象沒有屬性'is_viewable_by'' –

+0

@ Garreth00'benefit'是'Benefit'實例。像'benefit' = Benefit.objects.get(id = id) –

+0

@ Garreth00看到了您的更新。已更新回答 –

0

@Audrey:你忘了self參數在你的方法定義:

def is_viewable_by(self, user): 
    ...   ^
相關問題