Getting RelatedManager instead of getting model object by id

I have a Patient and a Doctor model that inherits from django User

class HmsUser(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(_('username'), max_length=30, unique=True,
        help_text=_('Required. 30 characters or fewer. Letters, numbers and '
                    '@/./+/-/_ characters'),
        validators=[
            validators.RegexValidator(re.compile('^[\w.@+-]+$'), _('Enter a valid username.'), 'invalid')
        ])
    email = models.EmailField(_('email address'), blank=True)
    is_staff = models.BooleanField(_('staff status'), default=False,
        help_text=_('Designates whether the user can log into this admin '
                    'site.'))
    is_active = models.BooleanField(_('active'), default=True,
        help_text=_('Designates whether this user should be treated as '
                    'active. Unselect this instead of deleting accounts.'))
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    objects = UserManager()

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    def __unicode__(self):
        return self.get_full_name();

    def get_profile(self):
        # ....

    def real(self, ):
        try: return self.doctor
        except Doctor.DoesNotExist:
            try: return self.operator
            except Operator.DoesNotExist:
                try: return self.patient
                except Patient.DoesNotExist:
                    try: return self.organization
                    except Organization.DoesNotExist:
                        return self

    def is_doctor(self):
        return self.real().__class__ == Doctor

    def is_patient(self):
        return self.real().__class__ == Patient

    def is_operator(self):
        return self.real().__class__ == Operator

    def is_organization(self):
        return self.real().__class__ == Organization

    def really(self, user_type):
        return isinstance(self.real(), user_type)

class Person(HmsUser):
    GENDER_CHOICES = (
        ('M', 'Male'),
        ('F', 'Female'),
    )
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name  = models.CharField(_('last name'), max_length=30, blank=True)
    dob        = models.DateField('Date Of Birth')
    sex        = models.CharField(max_length=1, choices=GENDER_CHOICES)
    address    = models.CharField(max_length=300, blank=True)
    image      = models.ImageField(upload_to=rename_image, null=True, blank=True)

    class Meta:
        abstract = True
    # ....

class Patient(Person):
    def get_full_name(self):
        return '%s. %s' % ( ('Mr', 'Ms')[self.sex == 'F'], super(Patient, self).get_full_name())

    def get_short_name(self):
        return '%s. %s' % (('Mr', 'Ms')[self.sex == 'F'], super(Patient, self).get_short_name())

    def admission(self):
        admissions = self.admissions.filter(released = None)
        return admissions.count() > 0 and admissions.latest('admitted') or None

    def doctors(self):
        id_list = self.stories.values_list('doctor', flat=True).distinct()
        return Doctor.objects.filter(pk__in=set(id_list))

    def visits(self):
        # ....

    def profile(self):
        return reverse('patient', args=(self.id, ))

class Doctor(Person):
    paramedic     = models.BooleanField()
    specialization = models.CharField(_('Specialization'), max_length=64, blank=True)
    organizations = models.ManyToManyField(Organization, through='Membership', blank=True)

    def get_full_name(self):
        return '%s. %s' % ('Dr', super(Doctor, self).get_full_name())

    def get_short_name(self):
        return '%s. %s' % ('Dr', super(Doctor, self).get_short_name())

    def stories(self):
        # ....

    def patients(self):
        id_list = self.stories.values_list('patient', flat=True).distinct()
        return Patient.objects.filter(pk__in=set(id_list))

    def profile(self):
        return reverse('doctor', args=(self.id, ))

I have different view for doctor and patient models

def patient(request, patient_id):
    patient = Patient.objects.get(id=patient_id)
    print(patient.__class__)        # <class 'identity.models.Patient'>
    print(patient.real().__class__) # <class 'django.db.models.fields.related_descriptors.RelatedManager'>

def doctor(request, doctor_id):
    doctor = Doctor.objects.get(id=doctor_id)
    print(doctor.__class__)        # <class 'identity.models.Doctor'>
    print(doctor.real().__class__) # <class 'identity.models.Doctor'>

doctor.real().__class__ and doctor.__class__ return <class 'identity.models.Doctor'>

But

patient.real().__class__ returns <class 'django.db.models.fields.related_descriptors.RelatedManager'>

However

patient.__class__ returns <class 'identity.models.Patient'>

Why patient.real().__class__ is not <class 'identity.models.Patient'>

Also when I open django shell

In [15]: d = Doctor.objects.get(id=68)    
In [16]: p = Patient.objects.get(id=69)    
In [17]: d.doctor
Out[17]: <Doctor: Dr. Shatadal Saha>    
In [18]: p.patient
Out[18]: <django.db.models.fields.related_descriptors.RelatedManager at 0x7fd86e45ee90>

1 answer

  • answered 2017-06-17 19:21 NeErAj KuMaR

    When you print patient.real().__class__ this.

    So this return a field from real method that has Foreignkey or ManytoMany with another Model. So patient.real().__class__ print Field relation class not self class name