2010-01-18 26 views
5

Kullanıcıların sistemde bir şeyleri yapmak için doğru izinlere sahip olduklarından emin olmak için bir düzine kadar izlemeye ihtiyacım var (örn. Profilini düzenleyebilirlerse doğru grupta olduklarından emin olun) Grup yöneticisi ise, vb.Gözden geçirme olmayan görünümleri döndürme

bir onay şöyle olabilir:

from django.contrib.auth.decorators import user_passes_test 

test_canvote = lambda u: u.has_perm('polls.can_vote') 

@user_passes_test(test_canvote) 
def my_view(request): 
    # ... 

Bu (benim biraz daha çirkin) aslında Django öğreticisindeki kodudur. Bazen bir kontrol çok veritabanını yoğunlaştırır, birden çok sorguyu kapatır. Çok sayıda kullanıcının izinli sayfaları vurmasıyla, işler hızla yavaşlayabilir.

Sorum şu ki, (yardımınızla) 'TESTCACHE' + user.pk + 'testname' anahtarının önbelleğini arayan user_passes_test dekoratör için bir sarıcı (veya değiştirme) oluşturabilir ve mevcut değilse, sınamayı yürütür ve sonucunu kaydeder.

Daha önce dekoratör yazdım ama ben sadece bir dize olarak testi geçen, user_passes_test biri neredeyse aynı görünür düşünün:

@cached_user_passes_test('test_canvote') 
def my_view(request): 
    # ... 

Ve her zamanki gibi, beni ben eğer bildirmek madem veya Django zaten benim için bunu yaparsa (bu yüzden başka yerlerde sorunum var).

Düzenleme: Standart dekoratörler burada bulabilirsiniz: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/decorators.py

Ben daha kolay işte başlangıç ​​noktası o oluyor sarma daha user_passes_test yerine olabileceğini düşünüyorum. Tabii ki, eğer sen bu ifade yanlış olduğumu hissediyorum, bana bildirin: (Ben cache anahtarı olarak kullanmak zaman yapmıyorum)

try: 
    from functools import update_wrapper, wraps 
except ImportError: 
    from django.utils.functional import update_wrapper, wraps # Python 2.3, 2.4 fallback. 

from django.contrib.auth import REDIRECT_FIELD_NAME 
from django.http import HttpResponseRedirect 
from django.utils.http import urlquote 
from django.utils.decorators import auto_adapt_to_methods 

def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): 
    """ 
    Decorator for views that checks that the user passes the given test, 
    redirecting to the log-in page if necessary. The test should be a callable 
    that takes the user object and returns True if the user passes. 
    """ 
    if not login_url: 
     from django.conf import settings 
     login_url = settings.LOGIN_URL 

    def decorator(view_func): 
     def _wrapped_view(request, *args, **kwargs): 
      if test_func(request.user): 
       return view_func(request, *args, **kwargs) 
      path = urlquote(request.get_full_path()) 
      tup = login_url, redirect_field_name, path 
      return HttpResponseRedirect('%s?%s=%s' % tup) 
     return wraps(view_func)(_wrapped_view) 
    return auto_adapt_to_methods(decorator) 

cevap

1

Sen fonksiyonunu seri gerekebilir böyle bir şey ancak çalışması gerekir:

from django.core.cache import cache 

def cached_user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): 
    if not login_url: 
     from django.conf import settings 
     login_url = settings.LOGIN_URL 

    def decorator(view_func): 
     def _wrapped_view(request, *args, **kwargs): 
      key = str(test_func) + str(request.user) 
      cached_test_result = cache.get(key) 
      if cached_test_result != None: 
       test_result = cached_test_result 
      else: 
       test_result = test_func(request.user) 
       cache.set(key, test_result, 60)  

      if test_result: 
       return view_func(request, *args, **kwargs) 
      path = urlquote(request.get_full_path()) 
      tup = login_url, redirect_field_name, path 
      return HttpResponseRedirect('%s?%s=%s' % tup) 
     return wraps(view_func)(_wrapped_view) 
    return auto_adapt_to_methods(decorator) 
+0

Test işlevinin argümanlarının da açık nedenlerden dolayı anahtarın bir parçası olması gerekir. – Oli

+0

Elbette, sonuncusuyla çok zekice olmaya çalışıyorum ... dekoratörün içine girip ayar yapmak için düzenlenmiş. Bu işe yarar mı? – ara818

0

İlk basitçe yazabilirsiniz:

from django.contrib.auth.decorators import permission_required 

@permission_required('polls.can_vote') 
def my_view(request): 
    # ... 

İkinci, izinler zamanla değişmez, sen oturumda biraz bilgi depolamak için serbesttir (Daha fazla kolaylık buldum Kullanıcı oturum açtığında, kullanıcı giriş yaptıktan sonra, bir oturumda saklamaktan daha iyidir.

Ancak, izinleri değiştirirseniz, kullanıcının oturumu kapatması ve yeni izinlerle çalışmaya devam etmesi gerektiğini unutmayın.

+0

Bence noktayı kaçırdınız. Dediğim gibi, testlerim basit bir “allow_required” den biraz daha karmaşık ve hepsi de “user_passes_test” üzerinde dönüyor. "Bir dekoratörü nasıl önleyebilirim?" daha doğru bir başlık olabilirdi. Bu, önbelleğe alma işlemini nasıl yapacağınız hakkında çok daha fazlasıdır. – Oli

İlgili konular