我有一个通用的APIView
,在这里我要覆盖create
方法。这是针对Group
模型的,我在其中添加了密码字段:
views.py
from django.contrib.auth.hashers import check_password, make_password
from django.contrib.auth.models import Group
from django.http import Http404
from rest_framework import generics
from rest_framework import status
from rest_framework.response import Response
from .permissions import AllowOptionsAuthentication
from .serializers import GroupSerializer
class GroupList(generics.ListCreateAPIView):
queryset = Group.objects.all()
serializer_class = GroupSerializer
permission_classes = [AllowOptionsAuthentication]
def create(self, request, *args, **kwargs):
data = request.data
data['password'] = make_password(data['password'])
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
print(Group.objects.get(name=data['d']).__dict__) # shows hashed password
print(serializer.data) # shows hashed password
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
class GroupDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Group.objects.all()
serializer_class = GroupSerializer
permission_classes = [AllowOptionsAuthentication]
def get_object(self):
queryset = self.filter_queryset(self.get_queryset())
try:
# Grabs the 'name' parameter from the URL
group = queryset.get(name=self.kwargs['name'])
except Group.DoesNotExist:
raise Http404
if not check_password(self.request.data['password'], group.password):
raise Http404
group.user_set.add(self.request.user)
self.check_object_permissions(self.request, group)
return group
serializers.py
class GroupSerializer(serializers.ModelSerializer):
class Meta:
model = Group
fields = ('id', 'name', 'password')
models.py
from django.contrib.auth.models import Group
from django.db.models import CharField, Model
Group.add_to_class('password', CharField(max_length=180, null=True, blank=True))
urls.py
from django.urls import path
from .views import GroupList, GroupDetail
urlpatterns = [
path('groups/', GroupList.as_view()),
path('groups/<str:name>/', GroupDetail.as_view()),
]
permissions.py
from rest_framework.permissions import IsAuthenticated
class AllowOptionsAuthentication(IsAuthenticated):
def has_permission(self, request, view):
if request.method == 'OPTIONS':
return True
return super(IsAuthenticated, self).has_permission(request, view)
settings.py
INSTALLED_APPS = [
'rest_framework',
'rest_framework.authtoken',
'djoser',
'corsheaders',
# ...
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
}
莫名其妙地,在检查了serializer.data
并直接在以上print
语句中查询了数据库之后,我确认已将哈希密码传递给该列。但是,以后再查询时,都会看到原始密码已保存。
在将哈希密码保存到数据库后,我无法解释密码如何变得散列。我没有在其他任何地方写Group
模型。
但是当我离开create
方法后查询此模型时:
print(Group.objects.get(name='TestGroup').__dict__) # shows raw password