Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Django中如何根据用户类型限制对页面的访问_Django_Django Templates_Django Views - Fatal编程技术网

在Django中如何根据用户类型限制对页面的访问

在Django中如何根据用户类型限制对页面的访问,django,django-templates,django-views,Django,Django Templates,Django Views,我有一个对Django新开发人员有用的基本问题 我在Django中创建了自己的用户配置文件。此UserProfile有一个名为“type”的特定字段。该字段可以有两个值(到目前为止,将来可能会有更多):男性-M/女性-F: from django.contrib.auth.models import User GENDER = ( (M, 'Male'), (F, 'Female'), ) class UserProfile(models.Model): user =

我有一个对Django新开发人员有用的基本问题

我在Django中创建了自己的用户配置文件。此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的所有可能性都感到迷茫。因此,如果您有任何实现此功能的最佳实践,请告诉我(显然,我希望在每个视图上都能使用干式代码!)


感谢您的帮助。

要向用户添加额外数据,请参见

然后将概要文件添加到上下文中,您可以在模板中使用{{profile}}变量

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

一种解决方案是根据用户类型更改基本模板名称:

@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 %}

如果需要在每个视图上执行此操作,可以使用中间件设置此值。

要限制访问,请使用装饰器:

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

根据您想做什么,如果您需要为不同性别使用非常不同的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 resonpse,您可以让它们返回对象,并使用decorator更改模板,添加到常规上下文中,然后将它们转换为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))

是的,直到现在我都是这么做的。但是,有没有一种方法可以避免在我需要做这个过程的每一页上重复我自己?像装饰师或其他什么?你说的中间件是什么意思?