У меня есть общий 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()),
]
разрешения.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