我是我的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
答案 0 :(得分:3)
这不是串行器的问题。问题在于DRF需要使用 PUT 方法的所有字段。不需要所有字段的方法是 PATCH 。
您需要在视图集中覆盖更新方法:
def update(self, request, *args, **kwargs):
partial = True # Here I change partial to True
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
return Response(serializer.data)
答案 1 :(得分:1)
如果您正在使用 PUT 更新值,并且只想省略对password
字段的验证,那么您可以尝试对viewset和{{3} }:
class UserSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
super(UserSerializer, self).__init__(*args, **kwargs)
if self.context['request'].method == "PUT":
self.fields.pop('password')
# rest of the code