Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.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
Python 如何做';不要重复你自己(干)_Python_Django_Django Views_Http Authentication - Fatal编程技术网

Python 如何做';不要重复你自己(干)

Python 如何做';不要重复你自己(干),python,django,django-views,http-authentication,Python,Django,Django Views,Http Authentication,我在代码中的两个地方有基本授权。我想把它作为一个函数分开,而不是重复代码 我的应用程序: from django.shortcuts import render from django.views.generic import View from django.http import HttpResponse, Http404 from django.contrib.auth import authenticate from django.core.exceptions import Permi

我在代码中的两个地方有基本授权。我想把它作为一个函数分开,而不是重复代码

我的应用程序:

from django.shortcuts import render
from django.views.generic import View
from django.http import HttpResponse, Http404
from django.contrib.auth import authenticate
from django.core.exceptions import PermissionDenied
import base64

from notes.models import Note, load_initial_data


class NoteListView(View):



    def filter_queryset(self, query_set):
        query_params = self.request.GET
        if 'board' in query_params:
            query_set = query_set.filter(board=query_params['board'])
        return query_set

    def get(self, request):
        load_initial_data()
        query_set = self.filter_queryset(Note.objects.all())
        basic_auth = True
        # this lines below !
        if basic_auth:
            if 'HTTP_AUTHORIZATION' in request.META:
                auth = request.META['HTTP_AUTHORIZATION'].split()
                if len(auth) == 2:
                    if auth[0].lower() == "basic":
                        uname, passwd = base64.b64decode(auth[1]).split(':')
                        user = authenticate(username=uname, password=passwd)
                        if user is not None and user.is_active:
                            request.user = user
                            if not request.user.is_staff:
                                raise PermissionDenied
                            return HttpResponse(query_set)

            response = HttpResponse()
            response.status_code = 401
            response['WWW-Authenticate'] = 'Basic realm="%s"' % "Basic Auth Protected"
            return response
        else:
            return HttpResponse(query_set)



class NoteView(View):

    def get_object(self, obj_id):
        try:
            return Note.objects.get(id=int(obj_id))
        except IndexError:
            raise Http404

    def get(self, request, note_id):
        load_initial_data()
        basic_auth = True
        #this lines below
        if basic_auth:
            if 'HTTP_AUTHORIZATION' in request.META:
                auth = request.META['HTTP_AUTHORIZATION'].split()
                if len(auth) == 2:
                    if auth[0].lower() == "basic":
                        uname, passwd = base64.b64decode(auth[1]).split(':')
                        user = authenticate(username=uname, password=passwd)
                        if user is not None and user.is_active:
                            request.user = user

                            return HttpResponse(self.get_object(note_id))

            response = HttpResponse()
            response.status_code = 401
            response['WWW-Authenticate'] = 'Basic realm="%s"' % "Basic Auth Protected"
            return response
        else:
            return HttpResponse(self.get_object(note_id))

我在get func的类NoteListView和类NoteView中重复代码。我不知道如何分离这个功能。我用注释标记了重复的行。有什么建议吗?

我将跳过关于不重复我自己的强制性笑话,但是根据Utkbansal的评论,您可以创建自己的Mixin类,也可以创建自己的基础视图,这两个视图都是从中派生的。i、 对象继承。也就是说,实现这一点最简单(我敢说是最奇特的!)的方法是将
PermissionRequiredMixin子类化:

from django.contrib.auth.mixins import PermissionRequiredMixin

class BasicAuthRequired(PermissionRequiredMixin):
    def __init__(self):
        super(BasicAuthRequired, self).__init__()
        self.basic_auth = True

    def has_permission(self):
        if self.basic_auth:
            if 'HTTP_AUTHORIZATION' not in request.META:
                return False
            auth = request.META['HTTP_AUTHORIZATION'].split()
            if len(auth) != 2 or auth[0].lower() != "basic":
                return False
            uname, passwd = base64.b64decode(auth[1]).split(':')
            user = authenticate(username=uname, password=passwd)
            if not user or not user.is_active:
                return False
            self.request.user = user # from `View`
            return user.is_staff
        return True # some other type of auth
现在,在您的视图中,您只需执行以下操作,即可确保基本身份验证已得到正确验证和处理,并且只需处理肯定的情况:

class NoteView(BasicAuthRequired, View):
    def get_object(self, obj_id):
        try:
            return Note.objects.get(id=int(obj_id))
        except IndexError:
            raise Http404

    def get(self, request, note_id):
        load_initial_data()   
        return HttpResponse(self.get_object(note_id))

我将跳过关于不重复我自己的强制性笑话,但是在Utkbansal的评论之后,您可以创建自己的Mixin类,也可以创建自己的基础视图,这两个视图都是从中派生的。i、 对象继承。也就是说,实现这一点最简单(我敢说是最奇特的!)的方法是将
PermissionRequiredMixin子类化:

from django.contrib.auth.mixins import PermissionRequiredMixin

class BasicAuthRequired(PermissionRequiredMixin):
    def __init__(self):
        super(BasicAuthRequired, self).__init__()
        self.basic_auth = True

    def has_permission(self):
        if self.basic_auth:
            if 'HTTP_AUTHORIZATION' not in request.META:
                return False
            auth = request.META['HTTP_AUTHORIZATION'].split()
            if len(auth) != 2 or auth[0].lower() != "basic":
                return False
            uname, passwd = base64.b64decode(auth[1]).split(':')
            user = authenticate(username=uname, password=passwd)
            if not user or not user.is_active:
                return False
            self.request.user = user # from `View`
            return user.is_staff
        return True # some other type of auth
现在,在您的视图中,您只需执行以下操作,即可确保基本身份验证已得到正确验证和处理,并且只需处理肯定的情况:

class NoteView(BasicAuthRequired, View):
    def get_object(self, obj_id):
        try:
            return Note.objects.get(id=int(obj_id))
        except IndexError:
            raise Http404

    def get(self, request, note_id):
        load_initial_data()   
        return HttpResponse(self.get_object(note_id))

你可以用一个装饰师,这看起来很容易理解。您似乎已经知道需要将其放入自己的方法中,那么是什么阻止了您呢?这可能是一个不错的选择,但如果a有两个不同的返回呢?当我创建自己的方法时,代码无法正常工作,只需使用自定义的auth实现创建一个mixin类。在你所有的视图中都使用这种混合。你可以使用一个装饰器,这看起来很容易考虑。您似乎已经知道需要将其放入自己的方法中,那么是什么阻止了您呢?这可能是一个不错的选择,但如果a有两个不同的返回呢?当我创建自己的方法时,代码无法正常工作,只需使用自定义的auth实现创建一个mixin类。在所有视图中使用该混合。