0

I am have an app that allows patients to reserve doctor's appointments. On the doctor's portal, I want to retrieve all appointments that is connected to the doctor using the portal.

The problem is "Cannot query "Person Name": Must be "Doctor" instance. Upon debugging I realized that doctor actually refers to the upin specified in the Doctor model instead of the username.

Models.py:

class User(AbstractUser):
    users = (
        ('doctor', 'Doctor'),
        ('patient', 'Patient'),
        ('assistant', 'Assistant'),
    )

    user_type = models.CharField(choices=users, max_length=9, default='patient')

    #return the users' name
    def __str__(self):
        return self.first_name  + " " + self.last_name

class Doctor(models.Model):
    upin = models.AutoField(primary_key=True) #unique physician identification number
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    user.user_type = "doctor"
    specialty = models.CharField(max_length=20)
    appointments_per_hour = models.IntegerField(null=True)
    picture = models.ImageField(upload_to = '', default = '')

    #return the doctors' name
    def __str__(self):
        return str(self.user)

class Patient(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    user.user_type = "patient"
    pid = models.AutoField(unique=True, primary_key=True) #patient identification

    #return the patients' name
    def __str__(self):
        return str(self.user)

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        if instance.user_type == "doctor":
            Doctor.objects.create(user=instance)
        elif instance.user_type == "patient":
            Patient.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    if instance.user_type == "doctor":
        instance.doctor.save()
    elif instance.user_type == "patient":
        instance.patient.save()

class Appointment(models.Model):
    TIMESLOT_LIST = (
        (1, '10:00 – 11:00'),
        (2, '11:00 – 12:00'),
        (3, '12:00 – 13:00'),
        (4, '13:00 – 14:00'),
        (5, '14:00 – 15:00'),
        (6, '15:00 – 16:00'),
        (7, '16:00 – 17:00'),
        (8, '17:00 – 18:00'),
        (8, '18:00 – 19:00'),
    )

    timeslot = models.IntegerField(choices=TIMESLOT_LIST, null=True)
    doctor = models.ForeignKey(Doctor, on_delete = models.CASCADE, related_name='doctor')
    patient = models.ForeignKey(Patient, on_delete = models.CASCADE, related_name='patient')


    def __str__(self):
        return str(self.doctor) + " " + str(self.patient) + " - " + str(self.get_timeslot_display()) 

Views.py:

def doctor_portal(request):
    appointments = Appointment.objects.get(doctor=request.user)
    return TemplateResponse(request, 'scheduling/doctor.html', {"appointments" : appointments})

For the query criteria I can use either doctor or doctor.id. As expected, doctor.id refers to the upin in the Doctor model. But why isn't doctor referring to the username of the doctor?

1 Answers1

0

Your Appointment model field doctor = models.ForeignKey(Doctor, on_delete = models.CASCADE, related_name='doctor') is linking to the Doctor, not User model.

So try this:

def doctor_portal(request):
    appointments = Appointment.objects.get(doctor=request.user.doctor)
    return TemplateResponse(request, 'scheduling/doctor.html', {"appointments" : appointments})
HenryM
  • 5,557
  • 7
  • 49
  • 105
  • I tried that and it said "name `doctor` is not defined". The issue is not with request.user since it IS returning the doctor's name. However, `doctor` or `doctor.id` is returning the `upin`. – Joseph Cheng Apr 03 '19 at 18:40
  • Ok I found a workaround for my problem. Instead of getting the doctor's username I grabbed his/her upin by calling `request.user.doctor.upin`. Your answer has certainly led me to the right direction. Thank you! – Joseph Cheng Apr 03 '19 at 18:46