首页 > 解决方案 > 如何从 django 序列化程序中的父类获取特定值

问题描述

语境

我正在尝试重新创建医院管理系统,一旦用户在网站上登录[作为患者或医生];患者/用户可以跟踪他们的健康记录,相关医生也可以。为此,我使用 AbstractBaseUser 类创建了一个自定义用户模型,其中用户可以在注册期间选择他们的用户角色,即医生或患者

class UserProfile(AbstractBaseUser, PermissionsMixin):
    """ Database Model for users in the system """
    email = models.EmailField(max_length=255, unique=True)
    name = models.CharField(max_length=255)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    USER_TYPE_CHOICES = (
        ('DOCTOR', 'DOCTOR'),
        ('PATIENT', 'PATIENT'),
    )
    user_type = models.CharField(max_length=255,
                                 choices=USER_TYPE_CHOICES, null=True)

医生模型是 UserProfile 模型的扩展,以 doc 作为 ForeignKey 属性

class Doctor(models.Model):
    doc = models.ForeignKey(
        UserProfile, null=True, blank=True, on_delete=models.CASCADE)
    #.....Other doctor attributes.....

    def __str__(self):
        return f'{self.doc.name}'

患者模型是 UserProfile 和 Doctor 的扩展

class Patient(models.Model):
    pat = models.ForeignKey(
        UserProfile, null=True, blank=True, on_delete=models.CASCADE)
    doctor = models.ForeignKey(
        Doctor, on_delete=models.SET_NULL, null=True, blank=True)

    def __str__(self):
        return f'{self.pat.name}'

患者的疾病是另一种具有外键属性患者的模型

class DiseaseOfPatient(models.Model):
    pat = models.ForeignKey(Patient,null=True,blank=True,on_delete=models.CASCADE)
    #other attributes are ailment attributes of that particular patient

问题 当我运行“python manage.py shell”并在其中运行时,我查询

doc1 = Doctor.objects.get(id=1)
doc1.patient_set.all()
--> <QuerySet [<Patient: Naruto Uzumaki>, <Patient: Sasuke Uchiha>]>
*I need this in my serializer as well*

当我在我的 ListAPIView 中执行此操作时,我定义了 get_queryset() 并编写了相同的逻辑,即

def get_queryset(self):
        doctor_query= models.Doctor.objects.filter(
            doc=self.request.user.id)
        queryset = doctor_query.patient_set.all()#to get each patient from that doctor
        return queryset

,但我使用的是 ForiegnKey 属性而不是名称,我得到了他们的“id”

*The output I get*
[
    {
        "doc": 1,
        "pat": 1,
        "id": 2
    },
    {
        "doc": 1,
        "pat": 2,
        "id": 1
    }
]
*The output I expect*
[
    {
        "doc": "Sakura Haruno",
        "pat": [
                {
                  "name": "Sasuke Uchiha",
                   "id":2 #--> This is "id" field of "Patient" model
                }
                {
                  "name": "Naruto Uzumaki",
                   "id":1 #--> This is "id" field of "Patient" model
                }
               ]
        "id":1 #--> This is "id" field of "Doctor" model
        
    }
]

我曾想过使用 HyperlinkedIdentityField,但它会创建一个我不想要的 URL。我找不到合适的 serializer_relation 可以实现这一点

先感谢您

标签: djangodjango-modelsserializationdjango-rest-frameworkdjango-views

解决方案


这里需要进行多项更改。

queryset = doctor_query.patient_set.all()

这将为每位患者返回一行。自然,当这被序列化时,这将导致多行。您无法从 get_queryset() 函数中解决此问题

相反,您应该做的是在序列化程序中添加一个字段:

user = serializers.SerializerMethodField()

和一个函数

def get_user():
    # Get Doctor ID
    # Get all patients
    # Use PatientSerializer to serialize all patients and return an array of arrays of their serialization 

推荐阅读