I\'m coding a REST API with Django REST framework. The API will be the backend of a social mobile app. After following the tutorial, I can serialise all my models and I am a
@cpury above suggested using write_only_fields option. This however did not work for me in DRF 3.3.3
In DRF 3.0 the write_only_fields option on ModelSerializer has been moved to PendingDeprecation and in DRF 3.2 replaced with a more generic extra_kwargs:
extra_kwargs = {'password': {'write_only': True}}
I typically treat the User view just like any other API endpoint that required authorization, except I just override the view class's permission set with my own for POST (aka create). I typically use this pattern:
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()
For good measure, here is the serializer I typically use with it:
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
I went ahead and made my own custom view for handling registration since my serializer doesn't expect to show/retrieve the password. I made the url different from the /users resource.
My url conf:
url(r'^users/register', 'myapp.views.create_auth'),
My view:
@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)
I may be wrong, but it doesn't seem like you'll need to limit permissions on this view since you'd want unauthenticated requests ...