test restframework rest_framework pip3 framework example python django django-models django-rest-framework

python - restframework - Django REST Framework Creación de usuario personalizado



pip3 install rest_framework (6)

Al usar Django Rest Framework tienes que tener cuidado. Cualquier modelo de usuario personalizado no puede utilizar la autenticación de token integrada. Hasta que pueda hacer eso, sugeriría usar un OneToOneField con usuario en su modelo personalizado. Su modelo personalizado contendrá los campos adicionales que desea conservar. One to One le da acceso al usuario del usuario personalizado y al usuario personalizado del usuario.

Soy nuevo en el reino de Django pero veo que hay mucha "magia" ahí. Estoy usando Django REST Framework y creando una aplicación que permitirá el registro gratuito de usuarios. Mi usuario necesita algunos campos adicionales que no están disponibles en el usuario de Django. Así que busqué en Google para extender el usuario. Hay una idea de que esto debería hacerse creando algo como esto

class MyUser(models.Model): user = models.ForeignKey(User, unique=True) city = models.CharField(max_length=50, blank=True, default='''')

Esto está bien pero tengo este serializador

class UserSerializer(serializers.ModelSerializer): class Meta: model = MyUser fields = (''id'', ''username'', ''password'', ''first_name'', ''last_name'', ''email'', ''city'')

Entonces, el problema es que este serializador hace algo de "magia" aquí. Intenta averiguar qué campo debería tener el modelo ... Quiero que el usuario tenga los campos que se enumeran aquí, y estos son campos que están en Usuario y "ciudad" es un nuevo campo personalizado. Serializador no consigue que se vea dentro del modelo de usuario.

¿Que me estoy perdiendo aqui? ¿Cómo decirle a este serializador que quiero algunos campos dentro de Usuario? Necesito ser capaz de crear usuarios también.


Así que aparentemente no tengo suficiente reputación para publicar un comentario en una respuesta. Pero para elaborar sobre lo que describió Kevin Stone, si modelas es algo como lo siguiente:

class AppUser(models.Model): user = models.OneToOneField(User) ban_status = models.BooleanField(default=False)

Puedes hacer algo como esto para crear tanto el usuario personalizado como el usuario de django:

class AppUserSerializer(serializers.ModelSerializer): username = serializers.CharField(source=''user.username'') email = serializers.CharField(source=''user.email'') password = serializers.CharField(source=''user.password'') ban_status = serializers.Field(source=''ban_status'') class Meta: model = AppUser fields = (''id'', ''username'', ''email'', ''password'', ''ban_status'') def restore_object(self, attrs, instance=None): """ Given a dictionary of deserialized field values, either update an existing model instance, or create a new model instance. """ if instance is not None: instance.user.email = attrs.get(''user.email'', instance.user.email) instance.ban_status = attrs.get(''ban_status'', instance.ban_status) instance.user.password = attrs.get(''user.password'', instance.user.password) return instance user = User.objects.create_user(username=attrs.get(''user.username''), email= attrs.get(''user.email''), password=attrs.get(''user.password'')) return AppUser(user=user)


De acuerdo, un par de cosas. Desea crear un OneToOneField para la extensión de su modelo de usuario.

class MyUser(models.Model): user = models.OneToOneField(User) city = models.CharField(max_length=50, blank=True, default='''')

Ahora, el poder de Django Rest Framework, es que puede construir su serializador, para tomar datos de ambos modelos cuando se serializa.

class UserSerializer(serializers.ModelSerializer): city = serializers.CharField(source=''myuser.city'') class Meta: model = User fields = (''id'', ''username'', ''password'', ''first_name'', ''last_name'', ''email'', ''city'')

Finalmente, donde está creando el usuario, ya que está usando campos personalizados, necesita implementar su propio restore_object() que construye ambos modelos a partir de los datos de entrada.

Además, la creación de Usuarios en Django es un poco diferente, debe llamar a create_user() y proporcionar una contraseña con hash, por lo que no es tan simple como almacenar campos desde un serializador.


Prefiero usar el módulo de signals django, que envía señales a la aplicación cuando sucede algo, y entre otras cosas le permitirá llamar a una función propia antes / después de otras funciones. Mi respuesta es similar a la de Stuart pero mantiene todo el código relevante para su nueva clase de extensión en un lugar (si desea eliminar el perfil más tarde o cambiar su nombre, no tiene que buscar en ningún otro lugar).

El siguiente código establece su modelo de clase extendida, en este caso un perfil de usuario, luego crea una instancia vacía cuando se crea un modelo de usuario, luego guarda la instancia con nueva información (que debe agregar usted mismo) guardando la instancia de usuario principal, es decir - user.save()

modelos.py

from django.db.models.signals import post_save from django.db import models from django.contrib.auth.models import User class Profile(models.Model): #This extends the user class to add profile information user = models.OneToOneField(User, on_delete=models.CASCADE) #add your extra traits here: is_nice, is_shwifty, address, etc. is_nice = models.BooleanField(default=True, blank=True) # a user model was just created! This now creates your extended user (a profile): @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: # instance is the user model being saved. Profile.objects.create(user=instance) # a user model was just saved! This now saves your extended user (a profile): @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): instance.profile.save()

Si no tiene un ProfileSerializer: serializers.py

#use hyperlinkedmodelserializer for easy api browsing + clicking class ProfileSerializer(serializers.HyperlinkedModelSerializer): user = UserSerializer() class Meta: model = Profile fields = (''url'', ''user'', ''is_nice'')

Después de crear su usuario y guardarlo, tendrá un perfil de usuario vacío para agregar información. Por ejemplo, después de ejecutar python manage.py shell intente:

from backend.models import User, Profile #create your user user=User(username="GravyBoat") user.save() #now update your user''s profile user.profile.is_nice=False #that''s one mean gravy boat user.save() user.profile.is_nice #False


Sería bueno si este caso de uso fuera más fácil de encontrar en los documentos. Como @jamod señaló, en DRF 3, puedes encontrarlo django-rest-framework.org/topics/3.0-announcement/#serializers :

class UserSerializer(serializers.ModelSerializer): profile = ProfileSerializer() class Meta: model = User fields = (''username'', ''email'', ''profile'') def create(self, validated_data): profile_data = validated_data.pop(''profile'') user = User.objects.create(**validated_data) Profile.objects.create(user=user, **profile_data) return user


Si está utilizando django 1.5 o superior, en su lugar use un modelo de usuario personalizado , de esta manera, el modelo de usuario tendrá su propia tabla dedicada y el serializador recogerá los campos correctamente.