我的代码中有两个地方的基本授权。我想把它作为一个函数分开,而不是重复代码。
我的应用:
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和类NoteView中的类NoteList中重复代码。我不知道如何分离这个功能。我用评论标记了重复的行。有什么建议吗?
答案 0 :(得分:2)
我将跳过关于不重复自己的强制性笑话,但是跟进Utkbansal的评论,您可以创建自己的Mixin类,也可以创建自己的基本视图,两个视图都可以从中获取。即对象继承。也就是说,最简单的(也是我敢说的最好!)方法是通过继承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))