Django REST 프레임 워크에 사용자를 등록하는 방법은 무엇입니까?
Django REST 프레임 워크 로 REST API를 코딩하고 있습니다. API는 소셜 모바일 앱의 백엔드가 될 것입니다. 자습서를 수행 한 후 모든 모델을 직렬화 할 수 있으며 새 리소스를 만들고 업데이트 할 수 있습니다.
인증을 위해 AuthToken을 사용하고 있습니다.
내 질문은 :
/users
리소스가 확보 되면 앱 사용자가 등록 할 수 있기를 바랍니다. 그렇다면 /register
익명 사용자가 /users
새 리소스 에 게시 할 수 있도록 별도의 리소스를 사용 하거나 허용 하는 것이 더 낫 습니까?
또한 권한에 대한 몇 가지 지침이 좋습니다.
serializer가 암호를 표시 / 검색 할 것으로 예상하지 않기 때문에 등록을 처리하기위한 고유 한 사용자 지정보기를 만들었습니다. URL을 / users 리소스와 다르게 만들었습니다.
내 URL 설정 :
url(r'^users/register', 'myapp.views.create_auth'),
내 견해 :
@api_view(['POST'])
def create_auth(request):
serialized = UserSerializer(data=request.DATA)
if serialized.is_valid():
User.objects.create_user(
serialized.init_data['email'],
serialized.init_data['username'],
serialized.init_data['password']
)
return Response(serialized.data, status=status.HTTP_201_CREATED)
else:
return Response(serialized._errors, status=status.HTTP_400_BAD_REQUEST)
내가 틀렸을 수도 있지만 인증되지 않은 요청을 원하기 때문에이보기에 대한 권한을 제한 할 필요가없는 것 같습니다.
Django REST Framework 3 은 serializer에서 메서드 재정의를 허용합니다create
.
from rest_framework import serializers
from django.contrib.auth import get_user_model # If used custom user model
UserModel = get_user_model()
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
def create(self, validated_data):
user = UserModel.objects.create(
username=validated_data['username']
)
user.set_password(validated_data['password'])
user.save()
return user
class Meta:
model = UserModel
# Tuple of serialized model fields (see link [2])
fields = ( "id", "username", "password", )
상속 된 클래스의 직렬화 된 필드는 Django Rest Framework v3.5 및 최신 버전 ModelSerializer
에서 특허로 선언되어야합니다 .Meta
api.py 파일 :
from rest_framework import permissions
from rest_framework.generics import CreateAPIView
from django.contrib.auth import get_user_model # If used custom user model
from .serializers import UserSerializer
class CreateUserView(CreateAPIView):
model = get_user_model()
permission_classes = [
permissions.AllowAny # Or anon users can't register
]
serializer_class = UserSerializer
DRF 3.x에서 작동하는 가장 간단한 솔루션 :
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'password', 'email', 'first_name', 'last_name')
write_only_fields = ('password',)
read_only_fields = ('id',)
def create(self, validated_data):
user = User.objects.create(
username=validated_data['username'],
email=validated_data['email'],
first_name=validated_data['first_name'],
last_name=validated_data['last_name']
)
user.set_password(validated_data['password'])
user.save()
return user
다른 변경은 필요하지 않습니다. 인증되지 않은 사용자에게 새 사용자 개체를 만들 수있는 권한이 있는지 확인하기 만하면됩니다.
write_only_fields
덮어 쓴 create
방법은 암호가 일반 텍스트가 아닌 해시로 저장되도록하는 동안 암호 (실제로는 우리가 저장 한 해시)가 표시되지 않도록합니다.
Django 1.5의 사용자 지정 사용자 모델을 지원하기 위해 Cahlan의 답변을 업데이트하고 응답에 사용자의 ID를 반환했습니다.
from django.contrib.auth import get_user_model
from rest_framework import status, serializers
from rest_framework.decorators import api_view
from rest_framework.response import Response
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
@api_view(['POST'])
def register(request):
VALID_USER_FIELDS = [f.name for f in get_user_model()._meta.fields]
DEFAULTS = {
# you can define any defaults that you would like for the user, here
}
serialized = UserSerializer(data=request.DATA)
if serialized.is_valid():
user_data = {field: data for (field, data) in request.DATA.items() if field in VALID_USER_FIELDS}
user_data.update(DEFAULTS)
user = get_user_model().objects.create_user(
**user_data
)
return Response(UserSerializer(instance=user).data, status=status.HTTP_201_CREATED)
else:
return Response(serialized._errors, status=status.HTTP_400_BAD_REQUEST)
일반적으로 사용자보기는 권한이 필요한 다른 API 끝점과 동일하게 취급합니다. 단,보기 클래스의 권한 집합을 POST (만들기)에 대한 고유 한 권한 집합으로 재정의하기 만하면됩니다. 일반적으로이 패턴을 사용합니다.
from django.contrib.auth import get_user_model
from rest_framework import viewsets
from rest_framework.permissions import AllowAny
class UserViewSet(viewsets.ModelViewSet):
queryset = get_user_model().objects
serializer_class = UserSerializer
def get_permissions(self):
if self.request.method == 'POST':
self.permission_classes = (AllowAny,)
return super(UserViewSet, self).get_permissions()
좋은 측정을 위해 일반적으로 사용하는 직렬 변환기는 다음과 같습니다.
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
fields = (
'id',
'username',
'password',
'email',
...,
)
extra_kwargs = {
'password': {'write_only': True},
}
def create(self, validated_data):
user = get_user_model().objects.create_user(**validated_data)
return user
def update(self, instance, validated_data):
if 'password' in validated_data:
password = validated_data.pop('password')
instance.set_password(password)
return super(UserSerializer, self).update(instance, validated_data)
djangorestframework 3.3.x / Django 1.8.x
위의 @cpury는 write_only_fields
옵션 사용을 제안했습니다 . 그러나 이것은 DRF 3.3.3에서 나를 위해 작동하지 않았습니다.
DRF 3.0 에서는 write_only_fields
ModelSerializer 의 옵션이 PendingDeprecation으로 이동되었으며 DRF 3.2 에서는보다 일반적인 extra_kwargs로 대체되었습니다.
extra_kwargs = {'password': {'write_only': True}}
All of the answers so far create the user, then update the user's password. This results in an two DB writes. To avoid an extra unnecessary DB write, set the user's password before saving it:
from rest_framework.serializers import ModelSerializer
class UserSerializer(ModelSerializer):
class Meta:
model = User
def create(self, validated_data):
user = User(**validated_data)
# Hash the user's password.
user.set_password(validated_data['password'])
user.save()
return user
A little late to the party, but might help someone who do not want to write more lines of code.
We can user the super
method to achieve this.
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(
write_only=True,
)
class Meta:
model = User
fields = ('password', 'username', 'first_name', 'last_name',)
def create(self, validated_data):
user = super(UserSerializer, self).create(validated_data)
if 'password' in validated_data:
user.set_password(validated_data['password'])
user.save()
return user
A Python 3, Django 2 & Django REST Framework viewset based implementation:
File: serializers.py
from rest_framework.serializers import ModelSerializers
from django.contrib.auth import get_user_model
UserModel = get_user_model()
class UserSerializer(ModelSerializer):
password = serializers.CharField(write_only=True)
def create(self, validated_data):
user = UserModel.objects.create_user(
username=validated_data['username'],
password=validated_data['password'],
first_name=validated_data['first_name'],
last_name=validated_data['last_name'],
)
return user
class Meta:
model = UserModel
fields = ('password', 'username', 'first_name', 'last_name',)
File views.py:
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import CreateModelMixin
from django.contrib.auth import get_user_model
from .serializers import UserSerializer
class CreateUserView(CreateModelMixin, GenericViewSet):
queryset = get_user_model().objects.all()
serializer_class = UserSerializer
File urls.py
from rest_framework.routers import DefaultRouter
from .views import CreateUserView
router = DefaultRouter()
router.register(r'createuser', CreateUserView)
urlpatterns = router.urls
ReferenceURL : https://stackoverflow.com/questions/16857450/how-to-register-users-in-django-rest-framework
'development' 카테고리의 다른 글
MySQL 사용자에게 호스트 액세스 권한 재 할당 (0) | 2020.12.27 |
---|---|
UIScrollView에서 확대 / 축소를 활성화하는 방법 (0) | 2020.12.27 |
새 Google Analytics 3.0 베타를 설치하려고 할 때 발생하는 링커 오류 (0) | 2020.12.27 |
layout / main.xml에서 내부 클래스보기를 참조하는 중 오류가 발생했습니다. (0) | 2020.12.27 |
사전 항목을 추가하거나 늘리는 방법은 무엇입니까? (0) | 2020.12.27 |