I'm writing a Django Rest API using Django Rest Framework and in it I have a base custom user User
and two kinds of user that inherit from User
, Doctor
and Pacient
.
Each one has a different endpoint, so to create a Doctor
we make a POST
request to /api/v1/doctor
and to create a Paciente
, a POST
to api/v1/pacient/
.
If I try creating a user (using those endpoints) but with an e-mail that is already registered (I have changed Django to use e-mail instead), I get the following.
{
"email": [
"user with this email already exists."
]
}
What I'm trying to achieve is to change this error message, but not only change, I need to verify if the e-mail if from a Pacient
or Doctor
regardless of which endpoint I'm using, so I can display different messages for each case.
PacientViewSet
(DoctorViewSet is basically the same) :
class PacientViewSet(viewsets.ModelViewSet):
serializer_class = PacientSerializer
queryset = Pacient.objects.all()
permission_classes = (AllowAny, )
Serializer:
class PacientSerializer(serializers.ModelSerializer):
def create(self, validated_data):
user = Paciente.objects.create_paciente_user(
nome_completo=self.validated_data['full_name'],
password=self.validated_data['password'],
email=self.validated_data['email'],
)
return user
class Meta:
model = Pacient
fields = ('id', 'email', 'password', 'full_name', ...)
extra_kwargs = {
'password': {
'write_only': True,
}
}
Please let me know if there's something else I need to share.
EDIT:
class CustomUser(AbstractBaseUser, PermissionsMixin):
full_name = models.CharField(max_length=100, null=True, blank=True)
email = models.EmailField(_('email address'), unique=True)
SEX_CHOICES = [
(ConstantesSexo.MALE, 'Male'),
(ConstantesSexo.FEMALE, 'Female'),
]
sex = models.CharField(max_length=1, choices=SEX_CHOICES, null=True, blank=True)
is_staff = models.BooleanField(_('staff status'), default=False)
is_active = models.BooleanField(_('active'), default=True)
created = models.DateTimeField(_('date joined'), default=timezone.now)
modified = models.DateTimeField(auto_now=True)
username_validator = UnicodeUsernameValidator()
username = models.CharField(
_('username'),
max_length=150,
unique=True,
blank=True,
null=True,
validators=[username_validator],
error_messages={
'unique': _("Username already exists."),
},
)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
USER_CHOICES = [
(UserType.DOCTOR, 'Doctor'),
(UserType.PACIENT, 'Pacient'),
]
user_type = models.CharField(max_length=3, choices=USER_CHOICES)
class Pacient(CustomUser):
nome_social = models.CharField(blank=True, null=True, max_length=50)
class Doctor(CustomUser):
doctor_id = models.CharField(max_length=50)
bio = models.TextField(blank=True, null=True)
verified = models.DateTimeField(null=True, blank=True)
In the end I solved it by overriding the create method in the ModelViewSet (not in the serializer):
class DoctorViewSet(viewsets.ModelViewSet):
def create(self, request, *args, **kwargs):
email = request.data.get('email')
user = CustomUser.objects.filter(email=email).first()
if email and user:
if user.is_doctor():
error_msg = 'doctor error msg'
elif user.is_pacient():
error_msg = 'pacient error msg'
return Response({'error': error_msg}, status=status.HTTP_400_BAD_REQUEST)
return super().create(request, *args, **kwargs)