尝试使用Django rest框架自动填充模型属性
简介:我有2个模型Patient
和Embryo
,只有1个用户是超级用户。所有患者均属于超级用户。一个病人可以有很多胚胎,但是一个胚胎只能有一个病人。
我要实现的目标。Embryo模型有一个名为karyotes
的字段,该字段是Charfield
。当用户输入karyotes
时,将自动填充胚胎的sex
。唐氏综合症也一样(请参见下面的模型)
错误:我制作模型的方式sex
和down_syndrome
始终显示为空
Example (This is not code, just explanation )
if karyotype == "46,XX" #The embryo is a Female
if karyotype == "46,XY" #The embryo is a Male
if karyotype == "47,XY,+21" #The embryo is a Male and has Down Syndrome
if karyotype == "47,XX,+21" #The embryo is a Female and has Down Syndrome
else sex == null and down_syndrome == null
下面是我的模型
class PatientsApiView(viewsets.ModelViewSet):
""" Handles Creating, reading and updating Patients """
class Embryo(models.Model):
""" A ForeignKey model to the patient """
patient = models.ForeignKey(Patient, related_name="embryos", on_delete=models.CASCADE)
code_name = models.CharField(max_length=100)
karyotype = models.CharField(max_length=100)
down_syndrome = models.BooleanField(blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
GENDER_CHOICES = (
("M", "Male"),
("F", "Female"),
)
sex = models.CharField(blank=True, null=True, max_length=1, choices=GENDER_CHOICES)
def __str__(self):
return self.code_name
""" Below is my attempt to get the desired result """
def get_sex(self):
if self.karyotype == "46,XX":
return self.sex == "F"
elif self.karyotype == "46,XY":
return self.sex == "M"
def has_down_syndrome(self):
if self.karyotype == "47,XY,+21":
return self.down_syndrome == True and self.sex == "M"
elif self.karyotype == "47,XX,+21":
return self.down_syndrome == True and self.sex == "F"
else:
return self.down_syndrome == False and self.sex == null
以下是我的观点。py
class EmbroApiView(viewsets.ModelViewSet):
"""Handles Creating, reading and updating Patients"""
serializer_class = serializers.EmbryoSerializer
queryset = Embryo.objects.all()
authentication_classes = (TokenAuthentication,)
filter_backends = (filters.SearchFilter,)
permission_classes = (IsAuthenticated,)
search_fields = ("code_name", "karyotype", "sex", "down_syndrome",)
def perform_create(self, serializer):
serializer.save(pk=self.kwargs.get("pk"))
下面是我的序列化器。py
class EmbryoSerializer(serializers.ModelSerializer):
class Meta:
model = Embryo
fields = ("id", "patient", "code_name", "karyotype", "sex", "down_syndrome", "created_at", "updated_at")
extra_kwargs = {"sex": {"read_only": True},
"down_syndrome": {"read_only": True}
}
根据@Ruddra第一建议
答案 0 :(得分:1)
您可以尝试覆盖模型的save方法,如下所示:
class Embryo(models.Model):
...
def set_sex(self):
if self.karyotype == "46,XX":
self.sex = "F"
elif self.karyotype == "46,XY":
self.sex = "M"
def set_down_syndrome(self):
if self.karyotype == "47,XY,+21":
self.down_syndrome = True
self.sex = "M"
elif self.karyotype == "47,XX,+21":
self.down_syndrome = True
self.sex = "F"
else:
self.down_syndrome = False
def save(self, *args, **kwargs):
if not self.sex:
self.set_sex()
self.set_down_syndrome()
return super(Embryo, self).save(*args, **kwargs)
还需要在模型中更改以下方法:
def get_sex(self):
if self.karyotype == "46,XX":
return "F"
elif self.karyotype == "46,XY":
return "M"
def has_down_syndrome(self):
if self.karyotype == "47,XY,+21":
return True, "M"
elif self.karyotype == "47,XX,+21":
return True, "F"
else:
return False, None
仅供参考似乎您不需要sex
和down_syndrome
信息在数据库中,因为您已经拥有karyotype
了,其中包含相关信息。您可以尝试这样:
#models.py
GENDER_CHOICES = { "M" : "MALE", "F" : "FEMALE"}
class Embryo(models.Model):
# remove sex and down_syndrome fields from Model
...
@property
def sex(self):
if "46,XX" in self.karyotype:
return GENDER_CHOICES.get("F")
elif '47,XY' in self.karyotype:
return GENDER_CHOICES.get("M")
return ""
@property
def down_syndrome(self):
if '+21' in self.karyotype:
return True
return False
#serializer
class EmbryoSerializer(serializers.ModelSerializer):
sex = serializers.ReadOnlyField()
down_syndrome = serializers.ReadOnlyField()
class Meta:
model = Embryo
fields = ("id", "patient", "code_name", "karyotype", "sex", "down_syndrome", "created_at", "updated_at")