django - drf 不创建没有配置文件密钥的配置文件
问题描述
我正在尝试在创建用户时创建用户配置文件。我收到此错误:
profile_data = validated_data.pop('profile')
KeyError: 'profile'
当我在创建用户时没有传递配置文件密钥但我在 customuserSerializers 中提到不需要 userprofileserialzer。如果我不传递配置文件密钥,我只想保存 null 。
模型.py:
class CustomUser(AbstractBaseUser, PermissionsMixin):
first_name = models.CharField(_('first name'), max_length=50)
last_name = models.CharField(_("last name"), max_length=50)
email = models.EmailField(_('email address'), unique=True)
mobile_number = PhoneNumberField()
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(default=timezone.now)
user_type = models.IntegerField(_("user_type"))
otp = models.CharField(_("otp"), max_length=10, default="0")
is_varified = models.BooleanField(default=False)
USER_TYPE_CHOICES = (
(1, 'users'),
(2, 'courier'),
(3, 'admin'),
)
user_type = models.PositiveSmallIntegerField(
choices=USER_TYPE_CHOICES, null=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserMananager()
def __str__(self):
return self.email
class UserProfile(models.Model):
user = models.OneToOneField(
CustomUser, primary_key=True, related_name='userProfile', on_delete=models.CASCADE,)
gender = models.CharField(max_length=10, blank=True, null=True)
age = models.IntegerField(blank=True, null=True)
image = models.ImageField(
upload_to='api/user_profile/', blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __unicode__(self):
return self.user.first_name
序列化程序.py:
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
read_only_fields = ('created_at', 'updated_at',)
exclude = ('user',)
class CustomUserSerializer(serializers.ModelSerializer):
profile = UserProfileSerializer(required=False)
password = serializers.CharField(write_only=True, required=False)
class Meta:
model = CustomUser
fields = ('id', 'first_name', 'last_name', 'email',
'mobile_number', 'password', 'is_active', 'user_type', 'otp', 'profile')
def create(self, validated_data):
profile_data = validated_data.pop('profile')
user = CustomUser.objects.create(**validated_data)
UserProfile.objects.create(user=user, **profile_data)
return user
def update(self, instance, validated_data):
profile_data = validated_data.pop('profile')
# update user data
instance.first_name = validated_data.get(
'first_name', instance.first_name)
instance.last_name = validated_data.get(
'last_name', instance.last_name)
instance.email = validated_data.get('email', instance.email)
# update user profile
if not instance.profile:
UserProfile.objects.create(user=instance, **profile_data)
instance.age = profile_data.get('age', instance.profile.age)
instance.gender = profile_data.get('gender', instance.profile.gender)
instance.save()
password = validated_data.get('password', None)
if password:
instance.set_password(password)
instance.save()
update_session_auth_hash(self.context.get('request'), instance)
return instance
视图.py:
@api_view(["POST"])
@permission_classes((AllowAny,))
def register(request):
#permission_classes = [(AllowAny, )]
serializer = CustomUserSerializer(data=request.data)
# print(serializer)
if serializer.is_valid():
serializer.is_active = False
# serializer.make_password(request.data.get('password'))
serializer.save()
user_otp = randint(9999, 99999)
otp_code = str(user_otp)
email = request.data.get('email')
send_mail(
'Otp verification',
otp_code,
'chenaj
il.com',
[email],
fail_silently=False,
)
# serializer.save(otp=user_otp)
otp_update = CustomUser.objects.get(email=request.data.get('email'))
otp_update.otp = user_otp
otp_update.save()
user = CustomUser.objects.get(email=email)
token, created = Token.objects.get_or_create(user=user)
current_time = datetime.datetime.now()
return Response({'status_code': status.HTTP_200_OK, 'status': 'true', 'currentTimeStamp': current_time, 'message': 'User registered successfully, OTP sent to your Mail', 'data': {'id': user.id, 'token': token.key, 'user_type': user.user_type}}, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(["POST"])
@permission_classes((IsAuthenticated, AllowAny))
def verifyUserOtp(request):
print("data.......////")
serializers = VerifyUserOtpSerializer(data=request.data)
if serializers.is_valid(raise_exception=True):
token = request.data.get('email')
otp = request.data.get('otp')
if CustomUser.objects.filter(otp=otp).exists():
user = CustomUser.objects.get(otp=otp)
user.is_varified = 1
user.save()
token, created = Token.objects.get_or_create(user=user)
print(user.profile.age)
return Response({'status_code': status.HTTP_200_OK, 'status': 'true', 'currentTimeStamp': datetime.datetime.now(), 'data': {'id': user.id, 'first_name': user.first_name, 'last_name': user.last_name, 'email': user.email, 'token': token.key, 'user_type': user.user_type}}, status=status.HTTP_200_OK)
return Response({'message': 'OTP not matched', 'status': 'false', 'status_code': status.HTTP_401_UNAUTHORIZED, 'currentTimeStamp': datetime.datetime.now()}, status=status.HTTP_400_BAD_REQUEST)
在这个 verifyuserotp 函数中,我无法使用 user.profile.age 访问配置文件对象。
解决方案
为避免出现此错误,您需要为.pop
方法提供默认值,例如None
并且只要返回值为None
,就不要创建Profile
记录。
def create(self, validated_data):
profile_data = validated_data.pop('profile', None)
user = CustomUser.objects.create(**validated_data)
if profile_data:
UserProfile.objects.create(user=user, **profile_data)
return user
这应该可以解决您的问题。
推荐阅读
- python - 在熊猫的两行之间划分值
- javascript - GroupBy 对象数组 JavaScript
- batch-file - 通过脚本启用本地组策略
- flutter - 无法使用颤振零安全颤振依赖项进行调试
- javascript - 为什么我无法在文档上设置 innerHTML?
- python - 如何正确地将 ComboBox 的模型从 python (pyQt5) 传递给 QML?
- excel - 识别公式中的第一个排序列
- python - 提取 pdf 文件的元数据(尺寸或方向)
- python - 我编写了根据日期将数据从较小数据帧复制到较大数据帧的代码,但速度很慢
- material-ui - 如何将标题内容添加到 Material-UI 的 DataGrid 导出到 CSV?