0

By going to

url(r'api/users/', views.MyUserCreate.as_view(), name='user-create'),

one can see DRF Browsable API

DRF Create Custom User Browsable API View

which uses MyUserCreate (in views.py)

class MyUserCreate(APIView):
    """ 
    Creates the user. 
    """

    def post(self, request, format='json'):
        serializer = MyUserSerializer(data=request.data)
        if serializer.is_valid():
            MyUser.objects.create_user(
                        serializer.username,
                        serializer.password
            )
            if user:
                return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)

Note that it references MyUserSerializer (in serializers.py)

class MyUserSerializer(serializers.ModelSerializer):
    username = serializers.CharField(
            required=True,
            validators=[UniqueValidator(queryset=MyUser.objects.all())],
            min_length=5,
            max_length=20
            ),
    password = make_password(serializers.CharField(
            write_only=True,
            required=True,
            max_length=256
            ))

    class Meta:
        model = MyUser
        fields = ('username', 'password')

    def create_user(self, validated_data):
        password = make_password(validated_data['password'])
        user = MyUser.objects.create_user(validated_data['username'], password)
        return user

and MyUser (in models.py)

class MyUserManager(BaseUserManager):
    def create_user(self, username, password):
        user = self.model(
            username=username
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

class MyUser(AbstractBaseUser):
    objects = MyUserManager()
    class Meta:
        # managed = False
        db_table = 'user_entity'

    user_id = models.AutoField(primary_key=True, db_column='userId')
    username = models.CharField(db_column='username', unique=True, max_length=20)
    password = models.CharField(db_column='userPassword', max_length=256)

    USERNAME_FIELD = 'username'

    def __str__(self):
        return str(self.user_id) + " (%s)" % str(self.username)

When I post to create a user

{
    "username": "tiagoperes",
    "password": "test"
}

I get

django.db.utils.DataError: (1406, "Data too long for column 'username' at row 1")

Django error Data too long for column 'username' at row 1

Following information from other users, checked if the column is UTF8

UTF8 column

and doesn't make sense to use TextField instead of CharField here.

Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145

1 Answers1

1
  1. You are passing serializer.username to create function, which is not the data you are passed via POST request, hence the error.
  2. Change your method create_user(...), to create(...) in MyUserSerializer so that, DRF will handle the function when you call the .save() method from view. (which is the DRF way)

Change your view as,

class MyUserCreate(APIView):

    def post(self, request, format='json'):
        serializer = MyUserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

as well as your serializer

class MyUserSerializer(serializers.ModelSerializer):
    # rest of your code

    def create(self, validated_data):
        password = make_password(validated_data['password'])
        user = MyUser.objects.create_user(validated_data['username'], password)
        return user
JPG
  • 82,442
  • 19
  • 127
  • 206