我正在使用Django Rest Framework编写REST API。我在这里令人费解。 我有一个名为“用户”的应用。
Models.py:
@python_2_unicode_compatible
class User(AbstractUser):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
profile_picture = models.ForeignKey(File, on_delete=models.DO_NOTHING, default=None, null=True, blank=True)
email = models.EmailField('Email address', unique=True)
name = models.CharField('Name', default='', max_length=255)
phone_no = models.CharField('Phone Number', max_length=255, unique=True)
company_name = models.CharField('Company Name', default='', max_length=255)
verification_token = models.CharField('Verification Token', default='', max_length=255)
address = models.CharField('Address', default='', max_length=255)
address_coordinates = models.CharField('Address Coordinates', default='', max_length=255)
country = models.CharField('Country', default='', max_length=255)
pincode = models.CharField('Pincode', default='', max_length=255)
pan_number = models.CharField('Pan Number', default='', max_length=255, blank=True)
gst_number = models.CharField('GST Number', default='', max_length=255, blank=True)
is_advertisor = models.BooleanField(default=False)
is_signage_owner = models.BooleanField(default=False)
phone_verified = models.BooleanField(default=False)
email_verified = models.BooleanField(default=False)
updated_at = models.DateTimeField(auto_now_add=True)
from_time = models.TimeField(blank=True, default='00:00')
to_time = models.TimeField(blank=True, default='00:00')
category = models.CharField('Category', default='', max_length=255, blank=True)
reset_token = models.CharField(max_length=255, default='')
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
def __str__(self):
return self.email
Views.py:
class UserViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
mixins.UpdateModelMixin,
mixins.CreateModelMixin,
viewsets.GenericViewSet):
queryset = User.objects.all()
permission_classes = (AllowAny,)
filter_backends = [DjangoFilterBackend]
filterset_fields = ['id', 'email', 'phone_no']
def get_serializer_class(self):
if self.action == 'create':
return CreateUserSerializer
elif self.action == 'update':
return UpdateUserSerializer
else:
return UserSerializer
Serializers.py:
class CreateUserSerializer(serializers.ModelSerializer):
def create(self, validated_data):
token = account_activation_token.make_token(validated_data['email'])
validated_data['verification_token'] = token
user = User.objects.create_user(**validated_data)
subject = 'Account Verification'
message = 'Your Verification token is http://167.71.234.51/verify?token=%s' % token
send_mail_from = 'support@cilliai.com'
recipients = [user.email]
send_mail(subject, message, send_mail_from, recipients)
response = send_otp(validated_data['phone_no'])
if "success" not in response:
return __badrequest__("Error while generating OTP")
return user
class Meta:
unique_together = ('email',)
model = User
fields = (
'id', 'password', 'email', 'username', 'phone_no'
)
extra_kwargs = {'password': {'write_only': True}}
class UpdateUserSerializer(serializers.ModelSerializer):
def update(self, instance, validated_data):
instance.email_verified = validated_data.get('email_verified', instance.email_verified)
instance.phone_verified = validated_data.get('phone_verified', instance.phone_verified)
instance.name = validated_data.get('name', instance.name)
instance.email = validated_data.get('email', instance.email)
instance.phone_no = validated_data.get('phone_no', instance.phone_no)
instance.company_name = validated_data.get('company_name', instance.company_name)
instance.address = validated_data.get('address', instance.address)
instance.country = validated_data.get('country', instance.country)
instance.pincode = validated_data.get('pincode', instance.pincode)
instance.pan_number = validated_data.get('pan_number', instance.pan_number)
instance.gst_number = validated_data.get('gst_number', instance.gst_number)
instance.is_advertisor = validated_data.get('is_advertisor', instance.is_advertisor)
instance.is_signage_owner = validated_data.get('is_signage_owner', instance.is_signage_owner)
instance.from_time = validated_data.get('from_time', instance.from_time)
instance.to_time = validated_data.get('to_time', instance.to_time)
instance.category = validated_data.get('category', instance.category)
instance.profile_picture = validated_data.get('profile_picture', instance.profile_picture)
instance.reset_token = validated_data.get('reset_token', instance.reset_token)
instance.save()
return instance
class Meta:
model = User
fields = (
'id', 'name', 'email_verified', 'phone_verified', 'email', 'phone_no', 'auth_token',
'company_name', 'address', 'country', 'pincode', 'pan_number', 'gst_number',
'is_advertisor', 'is_signage_owner', 'from_time', 'to_time', 'category', 'profile_picture',
'reset_token'
)
read_only_fields = ('auth_token',)
class UserSerializer(serializers.ModelSerializer):
profile_picture = FileSerializer()
class Meta:
unique_together = ('email',)
model = User
fields = (
'id', 'password', 'email', 'name', 'auth_token', 'email_verified', 'phone_verified',
'phone_no', 'company_name', 'address', 'country', 'pincode', 'pan_number', 'gst_number',
'is_advertisor', 'is_signage_owner', 'from_time', 'to_time', 'category', 'profile_picture',
'reset_token'
)
read_only_fields = ('auth_token',)
这是有趣的部分。当我在指向UserViewSet的路由上发出PUT请求时,在get_serializer_class方法中返回了UpdateUserSerializer,但碰巧是未调用UpdateUserSerializer类中的update方法。
这是我得到的答复:
{“电子邮件”:[“此字段为必填。”],“ phone_no”:[“此字段为必填。”]}
答案 0 :(得分:0)
这是API的验证错误。默认情况下,每个模型字段的空白将为false。我可以看到在您的用户模型中,电子邮件和 phone_no 字段的空白未设置为True。因此,这里发生的是,当您发送不带电子邮件和phone_no的请求时,将收到此类验证错误。一种快速的解决方案是在用户模型的电子邮件和 phone_no 字段中都添加 blank = True 。
更改您的用户模型中的以下代码并进行迁移。
email = models.EmailField('Email address', unique=True, blank=True)
phone_no = models.CharField('Phone Number', max_length=255, unique=True, blank=True)
和
在用户序列化器中添加此代码
email = serializers.EmailField(required=False)
phone_no = serializers.CharField(required=False)
这是Django文档空白字段的链接。 https://docs.djangoproject.com/en/2.2/ref/models/fields/#blank