6

में दिखाई नहीं दे रहे हैं I प्रति ऑर्डर अनुमति प्रबंधित करने के लिए django-guardian का उपयोग कर रहा हूं।django-guardian द्वारा आवंटित अनुमतियों वाले ऑब्जेक्ट्स व्यवस्थापक

एक भी उपयोगकर्ता के लिए मैं अनुमति एक वस्तु पर सभी की अनुमति देते हैं:

joe = User.objects.get(username="joe") 

mytask = Task.objects.get(pk=1) 

assign('add_task', joe, mytask) 
assign('change_task', joe, mytask) 
assign('delete_task', joe, mytask) 

और मैं मिलता है, के रूप में उम्मीद:

In [57]: joe.has_perm("add_task", mytask) 
Out[57]: True 

In [58]: joe.has_perm("change_task", mytask) 
Out[58]: True 

In [59]: joe.has_perm("delete_task", mytask) 
Out[59]: True 

admin.py में मैं भी TaskAdmin GuardedModelAdmin बजाय से विरासत बनाने admin.ModelAdmin

अब जब मैं अपनी साइट से जोड़ी से जुड़ता हूं, व्यवस्थापक पर मुझे मिलता है:

You don't have permission to edit anything 

क्या मैं वस्तु mytask को संपादित करने में सक्षम नहीं होना चाहिए?

क्या मुझे अंतर्निहित मॉडल-आधारित अनुमति प्रणाली का उपयोग करके कुछ अनुमतियां सेट करनी होंगी?

क्या मुझे कुछ याद आ रही है?

संपादित

मैं विकल्प user_can_access_owned_objects_only, जो मेरे मुद्दे से निपटने के माना जाता है जोड़ने की कोशिश की है, लेकिन मैं अभी भी अपने व्यवस्थापक में कुछ भी नहीं देख सकते हैं ...

class TaskAdmin(GuardedModelAdmin): 

    user_can_access_owned_objects_only = True 

    pass 

admin.site.register(Task, TaskAdmin) 

धन्यवाद आप

उत्तर

3

आदेश में केवल वर्तमान उपयोगकर्ता के स्वामित्व वाले उदाहरणों को देखने के लिए, मैं उसे सब की अनुमति दे

add_task=Permission.objects.get(codename="add_task") 
change_task=Permission.objects.get(codename="change_task") 
delete_task=Permission.objects.get(codename="delete_task") 

joe.user_permissions.add(add_task) 
joe.user_permissions.add(change_task) 
joe.user_permissions.add(delete_task) 

तो मैं guardian.shortcuts.assign का उपयोग कर कुछ उदाहरणों पर अनुमति सेट, और मैं व्यवस्थापक में क्वेरीसमूह को फ़िल्टर:

class TaskAdmin(admin.ModelAdmin): 

    def queryset(self, request): 
      if request.user.is_superuser: 
       return super(TaskAdmin, self).queryset(request) 
      return get_objects_for_user(user=request.user, perms=['add_task', 'change_task', 'delete_task'], klass=Task) 

यह सही से दूर है, लेकिन मैं किसी भी अन्य समाधान नहीं मिल सकता है ।

2

Django व्यवस्थापक, विशेष रूप से यह डब्ल्यू/change अनुमति से निपट रहा है, थोड़ा मोटा-अनाज है। आंतरिक विधि ModelAdmin.has_change_permission()view अनुमति की जांच को कवर करता है जिसमें वास्तव में कमी नहीं है।

दूसरा, GuardedModelAdmin स्वामित्व-जांच (user_can_access_owned_objects_only के माध्यम से) लाता है और पंक्ति-स्तर अनुमतियों के प्रबंधन के लिए फॉर्म बनाता है। यह Django व्यवस्थापक को कोई अन्य पंक्ति-स्तर पहुंच नीति प्रदान नहीं करता है।

class ExtendedGuardedModelAdmin(GuardedModelAdmin): 
    def queryset(self, request): 
     qs = super(ExtendedGuardedModelAdmin, self).queryset(request) 
     # Check global permission 
     if super(ExtendedGuardedModelAdmin, self).has_change_permission(request) \ 
      or (not self.list_editable and self.has_view_permission(request)): 
       return qs 
     # No global, filter by row-level permissions. also use view permission if the changelist is not editable 
     if self.list_editable: 
      return get_objects_for_user(request.user, [self.opts.get_change_permission()], qs) 
     else: 
      return get_objects_for_user(request.user, [self.opts.get_change_permission(), self.get_view_permission(
)], qs, any_perm=True) 

    def has_change_permission(self, request, obj=None): 
     if super(ExtendedGuardedModelAdmin, self).has_change_permission(request, obj): 
      return True 
     if obj is None: 
      # Here check global 'view' permission or if there is any changeable items 
      return self.has_view_permission(request) or self.queryset(request).exists() 
     else: 
      # Row-level checking 
      return request.user.has_perm(self.opts.get_change_permission(), obj) 

    def get_view_permission(self): 
     return 'view_%s' % self.opts.object_name.lower() 

    def has_view_permission(self, request, obj=None): 
     return request.user.has_perm(self.opts.app_label + '.' + self.get_view_permission(), obj) 

    def has_delete_permission(self, request, obj=None): 
     return super(ExtendedGuardedModelAdmin, self).has_delete_permission(request, obj) \ 
       or (obj is not None and request.user.has_perm(self.opts.get_delete_permission(), obj)) 

इस तरह कर सकता है, तो आप:

Django व्यवस्थापक में विशिष्ट पंक्ति-स्तर अनुमति दृश्य के लिए, मैं कोड का सुझाव देना चाहते हैं, यहाँ मैं एक वैकल्पिक 'दृश्य' अनुमति शुरू की है अधिक-लचीला अनुमति जाँच प्राप्त, उपयोगकर्ता अनुमतियाँ अब वैश्विक, उपयोगकर्ता के obj-अनुमतियों कर रहे हैं रो-लेवल आधारित हैं:

  • joe.user_permissions.add(add_task)
    जो नए कार्य जोड़ सकते हैं (कोई पंक्ति-स्तर 'जोड़ें' अनुमति)
  • joe.user_permissions.add(change_task)
    जो कार्यों के सभी बदलने
  • joe.user_permissions.add(delete_task)
    जो कार्यों के सभी को हटा सकते हैं सकता है
  • assign(Task._meta.get_change_permission(), joe, obj)
    जो टास्क obj को बदल सकता है, परिवर्तन सूची युक्त देखना obj के साथ ही अन्य अस्थिर कार्य ।
  • assign(Task._meta.get_delete_permission(), joe, obj)
    जो टास्क obj
  • assign('view_task', joe, obj)
    [वैकल्पिक] जो टास्क obj (आप अनुकूलित व्यवस्थापक दृश्य पेज पर इस अनुमति जांच करना चाह सकते)
  • joe.user_permissions.add(Permission.objects.get(codename='view_task', ...))
    देख सकते हैं हटा सकते हैं [वैकल्पिक] जो चेंजलिस्ट में सभी कार्यों को देख सकता है, जब तक कि परिवर्तक इनलाइन-संपादन योग्य न हो। यह उपयोगी है अगर जो कच्चे_आईडी_फील्ड से वस्तुओं को उठा सकता है, तो परिवर्तन अनुमति हो रही है।
  • ...

आप सुरक्षित रूप से 'दृश्य' अनुमति की अनदेखी कर सकता है कि वह आपके लिए बेकार है।

वर्तमान में, django.contrib.admin.util.get_deleted_objects अनुमति की जांच के दौरान obj सम्मान नहीं है, आप हटाने के दौरान पंक्ति-स्तर अनुमति जाँच करने के लिए, if not user.has_perm(p, obj): को if not user.has_perm(p): लाइन को संशोधित करके get_deleted_objects पैच की जरूरत है। रिश्तेदार टिकट 13539 & 16862

+0

आप self.has_view_permission – Don

+0

@Don हां में 'अनुरोध' और नहीं 'request.user' पास करना चाहिए, धन्यवाद उनका कहना है कि =) – okm

+0

परिवर्तन से संबंधित मुद्दे वर्ज़निंग हो सकता है, लेकिन में चलाने के लिए 'विकल्प' ऑब्जेक्ट में कोई विशेषता नहीं है 'get_change_permission' – Mutant

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

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