validacion usuarios usuario tipos sistema sesiones registro manejo example crear django python-2.7 django-models django-rest-framework

usuarios - tipos de usuario django



¿Cómo registrar usuarios en el marco Django REST? (8)

Estoy codificando una API REST con el marco Django REST . La API será el back-end de una aplicación móvil social. Después de seguir el tutorial, puedo serializar todos mis modelos y puedo crear nuevos recursos y actualizarlos.

Estoy usando AuthToken para la autenticación.

Mi pregunta es:

Una vez que tenga el recurso /users , quiero que el usuario de la aplicación pueda registrarse. Entonces, ¿es mejor tener un recurso separado como /register o permitir que usuarios anónimos envíen a /users un nuevo recurso?

Además, alguna orientación sobre permisos sería genial.


@cpury arriba sugirió utilizar la opción write_only_fields . Sin embargo, esto no funcionó para mí en DRF 3.3.3

En DRF 3.0, la opción write_only_fields en ModelSerializer se ha movido a PendingDeprecation y en DRF 3.2 se ha reemplazado por un extra_kwargs más genérico:

extra_kwargs = {''password'': {''write_only'': True}}


Actualicé la respuesta de Cahlan para admitir modelos de usuario personalizados de Django 1.5 y devuelvo la identificación del usuario en la respuesta.

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)


Django REST Framework 3 allow anular el método de create en serializadores:

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

También 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


La solución más simple, trabajando en 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

No necesita otros cambios, solo asegúrese de que los usuarios no autenticados tengan permiso para crear un nuevo objeto de usuario.

write_only_fields se asegurará de que las contraseñas (en realidad: su hash que almacenamos) no se muestren, mientras que el método de create sobrescrito garantiza que la contraseña no se almacene en texto claro, sino como un hash.


Normalmente trato la vista de usuario como cualquier otro punto final de API que requiera autorización, excepto que simplemente anulo el conjunto de permisos de la clase de vista con el mío para POST (también conocido como create). Normalmente utilizo este patrón:

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()

Para una buena medida, aquí está el serializador que normalmente uso con él:

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


Seguí adelante e hice mi propia vista personalizada para manejar el registro ya que mi serializador no espera mostrar / recuperar la contraseña. Hice la url diferente del recurso / users.

Mi url conf:

url(r''^users/register'', ''myapp.views.create_auth''),

Mi vista:

@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)

Puede que esté equivocado, pero no parece que deba limitar los permisos en esta vista, ya que querría solicitudes no autenticadas ...


Todas las respuestas hasta ahora crean el usuario y luego actualizan la contraseña del usuario. Esto da como resultado dos escrituras DB. Para evitar una escritura DB innecesaria, configure la contraseña del usuario antes de guardarla:

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


Un poco tarde para la fiesta, pero podría ayudar a alguien que no quiera escribir más líneas de código.

Podemos usar el super método para lograr esto.

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