扩展用户模型 Django REST 框架 3.x.x
Extend user model Django REST framework 3.x.x
我正在尝试使用 gender
、created_at
、updated_at
字段扩展 Django 休息框架(版本 3.x.x),这些字段在名为 UserProfile
。当我尝试更新包含嵌套 User
模型实例的 UserProfile
模型实例时,它仅更新 UserProfile
实例 (gender, updated_at fields
)。所以基本上我想要实现的是能够更新 User
模型
中的 email, first_name and last_name
字段
models.py:
class UserProfile(models.Model):
user = models.OneToOneField(User, primary_key = True, related_name = 'profile')
gender = models.CharField(choices = GENDERS, default = 2, max_length = 64)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
def __unicode__(self):
return self.user.username
@receiver(post_save, sender = User)
def create_profile_for_user(sender, instance = None, created = False, **kwargs):
if created:
UserProfile.objects.get_or_create(user = instance)
@receiver(pre_delete, sender = User)
def delete_profile_for_user(sender, instance = None, **kwargs):
if instance:
user_profile = UserProfile.objects.get(user = instance)
user_profile.delete()
serializers.py:
class UserProfileSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(source = 'pk', read_only = True)
username = serializers.CharField(source = 'user.username', read_only = True)
email = serializers.CharField(source = 'user.email')
first_name = serializers.CharField(source = 'user.first_name')
last_name = serializers.CharField(source = 'user.last_name')
class Meta:
model = UserProfile
fields = (
'id', 'username', 'email', 'first_name', 'last_name',
'created_at', 'updated_at', 'gender',
)
read_only_fields = ('created_at', 'updated_at',)
def update(self, instance, validated_data):
#user = User.objects.get(pk = instance.user.pk);
user = instance.user
user.email = validated_data.get('user.email', user.email)
user.first_name = validated_data.get('user.first_name', user.first_name)
user.last_name = validated_data.get('user.last_name', user.last_name)
user.save()
instance.gender = validated_data.get('gender', instance.gender)
instance.save()
return instance
def create(self, validated_data):
user_data = validated_data.pop('user')
user = User.objects.create(**user_data)
profile = UserProfile.objects.create(user = user, **validated_data)
return profile
views.py:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
class UserProfileViewSet(viewsets.ModelViewSet):
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
这是我的做法:
def update(self, instance, validated_data):
# First, update the User
user_data = validated_data.pop('user', None)
for attr, value in user_data.items():
setattr(instance.user, attr, value)
# Then, update UserProfile
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
return instance
基本上,我查看了 serializers
(here, line 800) 的原始代码并对其进行了修改,使其符合我的需要。
祝你好运。
对上述代码稍作修改,将 None 替换为 {}
因为'NoneType'对象没有属性'items'
def update(self, instance, validated_data):
# First, update the User
user_data = validated_data.pop('user', {})
for attr, value in user_data.items():
setattr(instance.user, attr, value)
# Then, update UserProfile
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
return instance
我正在实施另一种负责验证的方法。我正在实施它来处理 PATCH
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email', 'first_name', 'last_name')
class ProfileSerializer(serializers.ModelSerializer):
email = serializers.CharField(source='user.email')
first_name = serializers.CharField(source='user.first_name')
last_name = serializers.CharField(source='user.last_name')
class Meta:
model = Profile
exclude = ('user',)
def update(self, instance, validated_data):
user_data = validated_data.pop('user', {})
user_serializer = UserSerializer(instance.user, data=user_data, partial=True)
user_serializer.is_valid(raise_exception=True)
user_serializer.update(instance.user, user_data)
super(ProfileSerializer, self).update(instance, validated_data)
return instance
我正在尝试使用 gender
、created_at
、updated_at
字段扩展 Django 休息框架(版本 3.x.x),这些字段在名为 UserProfile
。当我尝试更新包含嵌套 User
模型实例的 UserProfile
模型实例时,它仅更新 UserProfile
实例 (gender, updated_at fields
)。所以基本上我想要实现的是能够更新 User
模型
email, first_name and last_name
字段
models.py:
class UserProfile(models.Model):
user = models.OneToOneField(User, primary_key = True, related_name = 'profile')
gender = models.CharField(choices = GENDERS, default = 2, max_length = 64)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
def __unicode__(self):
return self.user.username
@receiver(post_save, sender = User)
def create_profile_for_user(sender, instance = None, created = False, **kwargs):
if created:
UserProfile.objects.get_or_create(user = instance)
@receiver(pre_delete, sender = User)
def delete_profile_for_user(sender, instance = None, **kwargs):
if instance:
user_profile = UserProfile.objects.get(user = instance)
user_profile.delete()
serializers.py:
class UserProfileSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(source = 'pk', read_only = True)
username = serializers.CharField(source = 'user.username', read_only = True)
email = serializers.CharField(source = 'user.email')
first_name = serializers.CharField(source = 'user.first_name')
last_name = serializers.CharField(source = 'user.last_name')
class Meta:
model = UserProfile
fields = (
'id', 'username', 'email', 'first_name', 'last_name',
'created_at', 'updated_at', 'gender',
)
read_only_fields = ('created_at', 'updated_at',)
def update(self, instance, validated_data):
#user = User.objects.get(pk = instance.user.pk);
user = instance.user
user.email = validated_data.get('user.email', user.email)
user.first_name = validated_data.get('user.first_name', user.first_name)
user.last_name = validated_data.get('user.last_name', user.last_name)
user.save()
instance.gender = validated_data.get('gender', instance.gender)
instance.save()
return instance
def create(self, validated_data):
user_data = validated_data.pop('user')
user = User.objects.create(**user_data)
profile = UserProfile.objects.create(user = user, **validated_data)
return profile
views.py:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
class UserProfileViewSet(viewsets.ModelViewSet):
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
这是我的做法:
def update(self, instance, validated_data):
# First, update the User
user_data = validated_data.pop('user', None)
for attr, value in user_data.items():
setattr(instance.user, attr, value)
# Then, update UserProfile
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
return instance
基本上,我查看了 serializers
(here, line 800) 的原始代码并对其进行了修改,使其符合我的需要。
祝你好运。
对上述代码稍作修改,将 None 替换为 {}
因为'NoneType'对象没有属性'items'
def update(self, instance, validated_data):
# First, update the User
user_data = validated_data.pop('user', {})
for attr, value in user_data.items():
setattr(instance.user, attr, value)
# Then, update UserProfile
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
return instance
我正在实施另一种负责验证的方法。我正在实施它来处理 PATCH
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email', 'first_name', 'last_name')
class ProfileSerializer(serializers.ModelSerializer):
email = serializers.CharField(source='user.email')
first_name = serializers.CharField(source='user.first_name')
last_name = serializers.CharField(source='user.last_name')
class Meta:
model = Profile
exclude = ('user',)
def update(self, instance, validated_data):
user_data = validated_data.pop('user', {})
user_serializer = UserSerializer(instance.user, data=user_data, partial=True)
user_serializer.is_valid(raise_exception=True)
user_serializer.update(instance.user, user_data)
super(ProfileSerializer, self).update(instance, validated_data)
return instance