1

I'm trying to create an user and his profile through DRF, but I don't find the correct way to do it.

Here's my models.py

from __future__ import unicode_literals
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token
from django.db import models

class Profile(models.Model):

    user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True, null=True)
    language = models.CharField(max_length=4, default='es')

    def __unicode__(self):
            return "%s - %s" % (self.user, self.language)

my serializers.py

from rest_framework import serializers
from models import Profile
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model

class ProfileCreateSerializer(serializers.ModelSerializer):

username = serializers.CharField(source='user.username')

class Meta:

    model = Profile
    fields = [
    'username',
    'language',
    ]

def create (self, validated_data):

    user = get_user_model().objects.create(username=validated_data['username'])
    user.set_password(User.objects.make_random_password())
    user.save()

    profile = Profile.objects.create(user = user)

    return profile

my views.py

from rest_framework.response import Response
from rest_framework.generics import CreateAPIView
from serializers import ProfileCreateSerializer
from models import Profile

class ProfileCreateAPIView(CreateAPIView):

    model = Profile
    serializer_class = ProfileCreateSerializer

My urls.py

from django.conf.urls import patterns, include, url
import views
from django.contrib import admin

urlpatterns = [
    url(r'^', views.ProfileCreateAPIView.as_view(), name='crear perfil'),
]

if I try to create it shows me this error:

Cannot assign "{u'username': u'test'}": "Profile.user" must be a "User" instance.

if i create an user and his profile via admin panel doesn't show me any error.

my admin.py:

from django.contrib import admin
from models import Profile
from django.contrib.auth.admin import UserAdmin

class ProfileInline(admin.StackedInline):
    model = Profile
    can_delete = False
    verbose_name_plural = 'Perfil'
    fk_name = 'user'

class UserAdmin(UserAdmin):
    inlines = (ProfileInline,)

admin.site.unregister(User)
admin.site.register(User, UserAdmin)

I'm using django 1.9.1 and django rest framework 3.3.2

1 Answer 1

2

Why do you need UserSerializer at first place? Change your ProfileCreateSerializer to following. It should work

class ProfileCreateSerializer(serializers.ModelSerializer):
   username = serializers.CharField(source='user.username')

   class Meta:
       model = Profile
       fields = [
       'username',
       'language',
       ]

   def create (self, validated_data):
    user = get_user_model().objects.create(username=validated_data['username'])
    user.set_password(User.objects.make_random_password())
    user.save()

    profile = Profile.objects.create(user = user)

    return profile

Since the create method is override at your serializer, you need to send the data as a format the serializer process. So, you need to override the POST request at the views and create data as follows :

from rest_framework import status
from rest_framework.response import Response

class ProfileCreateAPIView(CreateAPIView):
    model = Profile
    serializer_class = ProfileCreateSerializer

    def post(self, request, *args, **kwargs):
        data = {
            'username': request.data.get('username', None),
            'language': request.data.get('language', None),

        }

        serializer = ProfileCreateSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(
                serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response( serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Sign up to request clarification or add additional context in comments.

10 Comments

It shows: Field.to_internal_value() must be implemented.
Change serializers.field to CharField as above. username = serializers.CharField(source='user.username')
done, now shows me an error just saying key error 'username'
Can you check your validated_data? You should have 'username' in that validated_data dictionary.
Fixed already, now show me that Cannot assign "{u'username': u'ddesq'}": "Profile.user" must be a "User" instance. Any idea? :|
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.