2016-01-08 4 views
6

मेरे पास कुछ ऐसे उपयोगकर्ता हैं जिन्हें एक निश्चित दृश्य देखने की अनुमति है।अनुमति अनुमति दे सकता है Mixin और LoginRequiredMixin संयुक्त हो सकता है?

उपयोगकर्ताओं के लिए प्रवेश और उन उपयोगकर्ताओं है कि उस लॉगिन नहीं देख सकते हैं, मैं उपयोग कर सकते हैं के लिए एक 403 Forbidden साथ शिकायत करने के लिए अनुमति देने के लिए निम्नलिखित (के रूप में समझाया here):

@permission_required('polls.can_vote', raise_exception=True) 
@login_required 
def my_view(request): 
    ... 

अपेक्षा के अनुरूप यह वास्तव में काम करता है। लेकिन मेरे सभी विचार वर्ग आधारित विचार हैं। चूंकि Django 1.9 (अंत में!) सुंदर चीजें बनाने के लिए सुंदर मिश्रणों का एक समूह है जो सजावटी के माध्यम से केवल संभव था। हालांकि ...

class MyClassView(LoginRequiredMixin, PermissionRequiredMixin, TemplateView): 
    raise_exception = <???> 
    permission_required = 'polls.can_vote' 
    template_name = 'poll_vote.html' 

यह काम नहीं करता है। क्योंकि raise_exception ध्वज का उपयोग LoginRequiredMixin और PermissionRequiredMixin दोनों द्वारा किया जाता है, इसलिए मैं इसे किसी भी चीज़ पर सेट नहीं कर सकता।

  • अगर raise_exceptionTrue है, जब कोई उपयोगकर्ता में लॉग इन नहीं कर रहा है एक 403 Forbidden (है जो मैं नहीं चाहता) प्राप्त करता है।
  • अगर raise_exceptionFalse है, वह यह है कि नहीं दृश्य देखने की अनुमति, प्रवेश पृष्ठ जो है, क्योंकि उपयोगकर्ता के प्रवेश, पृष्ठ के लिए फिर से रीडायरेक्ट करेगा पुनः निर्देशित किया जाएगा एक उपयोगकर्ता। एक बिल्कुल फैंसी रीडायरेक्ट लूप बनाना।

बेशक मैं अपने स्वयं के मिश्रण को लागू कर सकता हूं जो मुझे अपेक्षित व्यवहार करता है, लेकिन क्या यह देखने में कोई Django-तरीका है? (urls.py में नहीं)

उत्तर

5

कई मामलों के लिए अनधिकृत उपयोगकर्ताओं के लिए 403 बढ़ाने के लिए अपेक्षित व्यवहार है। तो हाँ, आप एक कस्टम mixin की जरूरत है:

class LoggedInPermissionsMixin(PermissionRequiredMixin): 
    def dispatch(self, request, *args, **kwargs): 
     if not self.request.user.is_authenticated(): 
      return redirect_to_login(self.request.get_full_path(), 
            self.get_login_url(), self.get_redirect_field_name()) 
     if not self.has_permission(): 
      # We could also use "return self.handle_no_permission()" here 
      raise PermissionDenied(self.get_permission_denied_message()) 
     return super(LoggedInPermissionsMixin, self).dispatch(request, *args, **kwargs) 
+0

ठीक है, मैं देखता हूं। धन्यवाद, सिर्फ एक प्रश्न: 'LoginRequiredMixin' की आवश्यकता नहीं है, है ना? क्या वहां कोई कारण है कि आप इसे वहां रखते हैं? – MariusSiuram

+0

@ मारियससिअराम, आप बिल्कुल सही हैं। इसके अलावा, कोड में एक तार्किक दोष था, जो अब (उम्मीद है) हल हो गया है। –

+0

मुझे लगता है, मुझे ऐसी परिस्थितियों का एहसास नहीं हुआ जिसमें उपयोगकर्ता में एक गैर-लॉग इन की कुछ अनुमति थी (क्या यह तार्किक दोष था?), लेकिन मुझे लगता है कि मैं मिक्सिन को पूरी तरह समझता हूं। धन्यवाद। – MariusSiuram

2

मैं एक टिप्पणी जोड़ना चाहते थे, लेकिन मेरी प्रतिष्ठा की अनुमति नहीं है। निम्नलिखित के बारे में कैसे? मुझे लगता है कि नीचे और अधिक पठनीय है?

टिप्पणियों के बाद अपडेट किया गया

मेरे तर्क है: आप मूल रूप से लिखने LoginRequiredMixin से dispatch संशोधित और बस raise_exception = True निर्धारित किया है। PermissionRequiredMixin होगा raise PermissionDenied जब सही अनुमतियां

class LoggedInPermissionsMixin(PermissionRequiredMixin): 
    raise_exception = True 

    def dispatch(self, request, *args, **kwargs): 
     if not self.request.user.is_authenticated(): 
      return redirect_to_login(self.request.get_full_path(), 
            self.get_login_url(), 
            self.get_redirect_field_name()) 
     return super(LoggedInPermissionsMixin, self).dispatch(request, *args, **kwargs) 
+0

मुझे यह मोड़ पसंद है। 'Handle_no_permission' विधि का उपयोग करके, अधिक पाइथोनिक और प्राकृतिक लगता है। पूर्वदर्शी में, यह विधि की एक स्पष्ट पसंद प्रतीत होता है। – MariusSiuram

+1

रुको ... क्या 'raise_exception = True' डालने के बराबर नहीं है? – MariusSiuram

+0

:) अच्छा बिंदु। सामुदायिक रिफैक्टरिंग यहां जा रहा है, मुझे यह पसंद है! –

0

सरल समाधान पूरी नहीं होती एक कस्टम दृश्य mixin हो रहा है। कुछ इस तरह:

class PermissionsMixin(PermissionRequiredMixin): 
    def handle_no_permission(self): 
     self.raise_exception = self.request.user.is_authenticated() 
     return super(PermissionsMixin, self).handle_no_permission() 

या, बस PermissionRequiredMixin हमेशा की तरह इस्तेमाल करते हैं और हर CBV को यह handle_no_premission डाल दिया।

संबंधित मुद्दे