Hi, I’m trying to build API for an application with DRF where there will be 2 user types.
I want to do the authentication with one User model and there will 2 different profile model each having it’s own unique properties.
class DoctorProfile(models.Model):
"""Model for Doctors profile"""
class DoctorType(models.TextChoices):
"""Doctor will choose profession category from enum"""
PSYCHIATRIST = "PSYCHIATRIST", "Psychiatrist"
PSYCHOLOGIST = "PSYCHOLOGIST", "Psychologist"
DERMATOLOGIST = "DERMATOLOGIST", "Dermatologist"
SEXUAL_HEALTH = "SEXUAL HEALTH", "Sexual health"
GYNECOLOGIST = "GYNECOLOGIST", "Gynecologist"
INTERNAL_MEDICINE = "INTERNAL MEDICINE", "Internal medicine"
DEVELOPMENTAL_THERAPIST = "DEVELOPMENTAL THERAPIST", "Developmental therapist"
owner = models.OneToOneField(
CustomUser,
on_delete=models.CASCADE,
related_name='doctor_profile'
)
doctor_type = models.CharField(
_("Profession Type"),
max_length=70,
choices=DoctorType.choices,
null=True,
blank=False
)
title = models.IntegerField(_('Title'), default=1, choices=TITLES)
date_of_birth = models.DateField(null=True, blank=False)
gender = models.IntegerField(_('Gender'), default=1, choices=GENDERS)
registration_number = models.IntegerField(_('Registration Number'), null=True, blank=False)
city = models.CharField(_('City'), max_length=255, null=True, blank=True)
country = models.CharField(_('Country'), max_length=255, null=True, blank=True)
def __str__(self):
return f'profile-{self.id}-{self.title} {self.owner.get_full_name()}'
I want to show the information in Doctor Profile page combining both CustomUser and DoctorProfile model.
I wrote two serializers, one for getting all the properties of DoctorProfile model, and used that serializer in the main serializer DoctorProfileSeriaizer where I used the model serializer for CustomUser model and put the serializer mentioned above in a variable named profile. My objective here is to get all the properties from DoctorProfile model under profile key.
class DoctorProfileFields(serializers.ModelSerializer):
"""this will be used in DoctorProfileSerializer as profile key"""
class Meta:
model = DoctorProfile
fields = ('doctor_type', 'title', 'date_of_birth', 'registration_number', 'gender', 'city', 'country', )
class DoctorProfileSerializer(serializers.ModelSerializer):
"""retrieve, update and delete profile"""
profile = DoctorProfileFields(source='*')
class Meta:
model = User
fields = ('name', 'avatar', 'profile', )
@transaction.atomic
def update(self, instance, validated_data):
print("==============", validated_data)
ModelClass = self.Meta.model
profile = validated_data.pop('profile', {})
ModelClass.objects.filter(id=instance.id).update(**validated_data)
if profile:
DoctorProfile.objects.filter(owner=instance).update(**profile)
new_instance = ModelClass.objects.get(id = instance.id)
return new_instance
Payload I’m trying to send
{
"name": "Iron Man Updated",
"profile" : {
"doctor_type": "PSYCHIATRIST",
"date_of_birth": "1995-01-01",
"registration_number": 154878,
"city": "NY",
"country": "USA"
}
}
When I try sending request with GET method it returns in the expected nested format, but the problem is with the PUT method. it’s returning error saying CustomUser has no field doctor_type
my debug shows that, the payload is getting received in this format
{
"name": "Iron Man Updated",
"doctor_type": "PSYCHIATRIST",
"date_of_birth": "1995-01-01",
"registration_number": 154878,
"city": "NY",
"country": "USA"
}
my PatientProfile also structured in the same way as DoctorProfile. so same error saying some-field is not available in CustomUser.
Please guide me through this. Or if you want to ask anything, please.