2012-09-26 25 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)) 
相关问题