DRF创建用户时出现username字段过长错误的排查求助
Let's break down the root causes of this error and walk through the fixes step by step:
1. Critical Issue: Accessing Serializer Fields Instead of Validated Data
The biggest mistake is in your view code—you're passing serializer field instances (not the actual username/password values from the request) to create_user. The string representation of a CharField instance is way longer than 20 characters, which directly causes the DataError when inserting into the username column.
Fix the View (views.py)
class MyUserCreate(APIView): """ Creates the user. """ def post(self, request, format='json'): serializer = MyUserSerializer(data=request.data) if serializer.is_valid(): # Use validated_data to get the actual request values user = MyUser.objects.create_user( username=serializer.validated_data['username'], password=serializer.validated_data['password'] ) # No need for redundant user check—create_user returns the user return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
2. Syntax Error: Trailing Comma on Serializer Username Field
The trailing comma after your username field definition turns it into a tuple instead of a valid CharField instance. This breaks validation and leads to unexpected behavior.
3. Misused make_password in Serializer
Wrapping make_password around the password field definition hashes the field object itself (not the user's input password) when the serializer loads. Your model's create_user method already handles password hashing via set_password, so this is redundant and incorrect.
Fix the Serializer (serializers.py)
class MyUserSerializer(serializers.ModelSerializer): username = serializers.CharField( required=True, validators=[UniqueValidator(queryset=MyUser.objects.all())], min_length=5, max_length=20 ) # Removed trailing comma password = serializers.CharField( write_only=True, required=True, max_length=256 ) # Removed make_password wrapper class Meta: model = MyUser fields = ('username', 'password') # Override create to use the model's create_user method def create(self, validated_data): return MyUser.objects.create_user( username=validated_data['username'], password=validated_data['password'] )
4. Verify Model Logic (Already Correct)
Your MyUser model and MyUserManager are correctly set up—create_user uses set_password to hash the password, and the username field has a valid max length of 20. No changes needed here.
Why This Works
After applying these fixes:
- The view correctly pulls the actual username/password values from the validated request data
- The serializer properly validates the username length (5-20 characters) before passing it to the model
- The password is hashed correctly by the model's
create_usermethod - Your POST request
{"username": "tiagoperes", "password": "test"}will now insert a valid username (10 characters, well under the 20 limit) into the database.
内容的提问来源于stack exchange,提问作者Tiago Peres

