我创建了一个自定义用户,并通过knox身份验证,我想为每个用户创建一个配置文件,这是我的个人资料模型
class Profile(models.Model):
user = models.OneToOneField(User,null=True,on_delete=models.CASCADE)
GENDER = (
('M','Male'),
('F','Female'),
)
username = models.CharField(max_length=150,blank=True)
gender = models.CharField(max_length=1, choices=GENDER,blank=True)
def create(self,user,username):
self.user=user
self.username = username
return self
序列化器
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','username','email','phone_number')
class RegisterSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','username','email','phone_number','password')
extra_kwargs = {'password':{'write_only':True}}
def create(self, validated_data):
user = User.objects.create_user(
**validated_data
)
username = validated_data['username']
profile = Profile.objects.create(user=user,username=username)
user.set_password(validated_data['password'])
return user,profile
class LoginSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField()
def validate(self, data):
user = authenticate(**data)
if user and user.is_active:
return user
raise serializers.ValidationError('Incorrect Credentials')
#serializer for profile
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ['username','gender']
username = serializers.CharField(source='User.username')
和此为意见
class UserApiView(generics.RetrieveAPIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
serializer_class = UserSerializer
def get_object(self):
return self.request.user
class RegisterApiView(generics.GenericAPIView):
serializer_class = RegisterSerializer
def post(self,request,*args,**kwargs):
serializer = self.get_serializer(data = request.data)
serializer.is_valid(raise_exception=True)
user,profile = serializer.save()
return Response({
'user': UserSerializer(user,context=self.get_serializer_context()).data,
'token':AuthToken.objects.create(user)[1],
'profile':ProfileSerializer(profile,context=self.get_serializer_context()).data
})
class LoginApiView(generics.GenericAPIView):
serializer_class = LoginSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data
return Response({
"user": UserSerializer(user, context=self.get_serializer_context()).data,
"token": AuthToken.objects.create(user)[1]
})
class ProfileApiView(generics.RetrieveAPIView):
serializer_class = ProfileSerializer
permission_classes = [permissions.AllowAny]
def get(self,request,*args,**kwargs):
serializer = self.get_serializer(data=request.data)
return Response({
"username":ProfileSerializer(context=self.get_serializer_context()).data
})
而且,我一般来说对drf和django还是陌生的,我想知道是否有人可以建议一个更好的做法来在注册时为每个用户创建个人资料。
谢谢。
编辑:我尝试执行以下操作:
user,profile = serializer.save()
并产生以下回溯
Traceback (most recent call last):
File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
raise exc
File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\Bragdon\PycharmProjects\version1\users\api\views.py", line 24, in post
'profile':ProfileSerializer(profile,context=self.get_serializer_context()).data
File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\serializers.py", line 562, in data
ret = super().data
File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\serializers.py", line 260, in data
self._data = self.to_representation(self.instance)
File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\serializers.py", line 516, in to_representation
attribute = field.get_attribute(instance)
File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\fields.py", line 487, in get_attribute
raise type(exc)(msg)
AttributeError: Got AttributeError when attempting to get a value for field `username` on serializer `ProfileSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Profile` instance.
Original exception text was: 'Profile' object has no attribute 'User'.
create
方法返回user, profile
,您只需调用此方法一次,然后使用元组拆包分配user
和profile
即可
从serializer.save()
中删除重复的RegisterApiView
。相反,请执行以下操作。