2012-09-26 69 views
2

我有一個基本的問題,可以用於新的Django開發人員。如何在Django中根據用戶類型限制對頁面的訪問

我在Django中創建了自己的UserProfile。這個UserProfile有一個叫'type'的特定字段。該字段有兩個值(到現在爲止,也許在未來更多):男 - M /女 - F:

from django.contrib.auth.models import User 

GENDER = (
    (M, 'Male'), 
    (F, 'Female'), 
) 

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 
    type = models.CharField(max_length=2, 
          choices=GENDER, 
          default='F') 

基本上,我想允許訪問限制訪問或根據用戶類型,以適應頁面內容。到現在爲止,我用了一個很基本的和初學者的做法,是爲了測試用戶類型,然後再處理頁面:

def OnePage(request): 
    if request.user.type == 'M': 
     .... 
    else if request.user.type =='F': 
     .... 

然後,我還需要適應不同用戶類型提供的模板:男性用戶將不會有與女性用戶相同的個人資料頁面。

我相信有更好的方法來做到這一點,但作爲一個Django初學者,我完全喪失了Django的所有可能性。所以,如果你有任何最佳實踐來實現這一點,請告訴我(很明顯,我想我可以在每個視圖上使用DRY代碼!)

感謝您的幫助。

回答

2

一種解決方案可以使用{{輪廓}}變量根據用戶類型更改基本模板名稱:

@render_to('some_template.html') 
def some_view(request): 
    base_template = 'base_%s.html' % request.user.profile.type 
    # … 
    return { 
     'base_template': base_template, 
    } 

而在你的模板:

{% extends base_template %} 
{% block some-block %} 
… 
{% endblock %} 

如果你需要做到這一點的每個視圖,您可以使用中間件來設置這個值。

+0

你是什麼意思的中間件? –

+0

[在文檔中](https://docs.djangoproject.com/en/dev/topics/http/middleware/?from=olddocs) –

0

額外的數據添加到用戶看到

Storing additional information about users

然後將配置文件添加到您的背景下,你可以在你的模板

{% if profile.type == "F" %} 
    blah, blah 
{% else %} 
    blah, blah 
{% endif %} 
+0

是的,這就是我所做的,直到如今。但是有沒有辦法在我需要做這個過程的每一頁上不重複自己?像裝飾者或其他東西? –

4

要限制訪問,使用user passes test裝飾:

from django.contrib.auth.decorators import user_passes_test 

male_only = lamda u: u.type == 'M' 
female_only = lamda u: u.type == 'F' 


@user_passes_test(male_only) 
def myfunc(request): 
    pass 

@user_passes_test(female_only) 
def myotherfunc(request): 
    pass 
+0

這應該是公認的答案 –

0

取決於你想要做什麼,如果你需要使用不同的性別非常不同的HTML,你可以試試這個方法:

def gender_filter(func): 
    def _view(request,*args,**kwargs): 
     res=func(request,*args,**kwargs) 
     if request.user.get_profile().type=='F': 
      res.template_name='template_f.html' 
      res.context_data['gender']='female' 
     elif request.user.get_profile().type=='M': 
      res.template_name='template_m.html' 
      res.context_data['gender']='male' 
     return res.render() 
    return _view 

@gender_filter 
def my_view(request): 
    t=TemplateResponse(request,'template_f.html',{...}) 
    return t 

因此,不要在視圖中返回Http共鳴,而是讓它們返回TemplateResponse對象並使用裝飾器來更改模板,添加到一般上下文中,然後將它們轉換爲HttpResponse。

或者類似的東西在許可檢查:

def gender_only(gender): 
    def _dec(func): 
     def _view(request,*args,**kwargs): 
      if request.user.get_profile().type==gender 
       return func.render(request,*args,**kwargs) 
      else: 
       raise Exception("You do not have the right gender") 
     return _view 
    return _dec 

@gender_only('F') 
def my_view(request): 
    ... 
    return render_to_response('template.html',{...},context_instance=RequestContext(request)) 
相關問題