【发布时间】:2019-05-14 22:28:00
【问题描述】:
我的 Django Rest API 用户序列化程序中的一个问题是:发出 PUT 请求时,密码字段是必需的。在 POST 请求中这是有道理的,但对于 PUT 尤其是如果 PUT 由管理员执行,密码字段应该允许为空。
如何更改我的序列化程序,以便 POST 需要密码,但 PUT 为空?
class UserSerializer(serializers.ModelSerializer):
"""The UserSerializer"""
gender = serializers.IntegerField(source='profile.gender', read_only=False)
clinic = serializers.CharField(
source='profile.clinic.code', read_only=False)
title_prefix = serializers.CharField(
source='profile.academic_title_prefix',
allow_blank=True,
read_only=False)
title_suffix = serializers.CharField(
source='profile.academic_title_suffix',
allow_blank=True,
read_only=False)
email = serializers.EmailField(
required=True,
validators=[UniqueValidator(queryset=User.objects.all())])
username = serializers.CharField(
validators=[UniqueValidator(queryset=User.objects.all())])
password = serializers.CharField(min_length=8, write_only=True)
class Meta:
model = User
fields = ('id', 'url', 'username', 'first_name', 'last_name', 'gender',
'title_prefix', 'title_suffix', 'clinic', 'email',
'is_staff', 'is_superuser', 'date_joined', 'last_login',
'password')
def create(self, validated_data):
"""Create and return a new user and its associated profile."""
user = User.objects.create_user(
validated_data['username'],
validated_data['email'],
validated_data['password'],
)
user.set_password(validated_data['password'])
user.first_name = validated_data['first_name']
user.last_name = validated_data['last_name']
user.is_staff = validated_data['is_staff']
user.is_superuser = validated_data['is_superuser']
user.save()
# create associated profile
profile_data = validated_data.pop('profile')
profile = Profile.objects.create(
user=user,
gender=profile_data['gender'],
clinic=Clinic.objects.get(code=profile_data['clinic']['code']),
academic_title_prefix=profile_data['academic_title_prefix'],
academic_title_suffix=profile_data['academic_title_suffix'],
)
user.profile = profile
return user
def update(self, instance, validated_data):
"""Update and return a existing user and its associated profile."""
instance.first_name = validated_data.get('first_name',
instance.first_name)
instance.last_name = validated_data.get('last_name',
instance.last_name)
# Only Superuser can make Superusers
if self.context['request'].user.is_superuser:
instance.is_staff = validated_data.get('is_staff',
instance.is_staff)
instance.is_superuser = validated_data.get('is_superuser',
instance.is_superuser)
profile_data = validated_data.pop('profile')
profile = Profile.objects.get(user=instance)
profile.gender = profile_data['gender']
profile.clinic = Clinic.objects.get(
code=profile_data['clinic']['code'])
profile.academic_title_prefix = profile_data['academic_title_prefix']
profile.academic_title_suffix = profile_data['academic_title_suffix']
profile.save()
instance.profile = profile
return instance
【问题讨论】:
-
为 Post 和 Put 请求创建单独的序列化程序
-
根据 REST 原则,PUT 应该包含整个对象。但是,PATCH 用于部分更新选定的字段,并且只允许包含需要更新的字段。所以我建议你改用 PATCH
标签: django django-rest-framework