如何自动填充Django Rest Framework Model字段

时间:2018-11-05 04:13:11

标签: django python-3.x django-models django-rest-framework django-views

尝试使用Django rest框架自动填充模型属性

简介:我有2个模型PatientEmbryo,只有1个用户是超级用户。所有患者均属于超级用户。一个病人可以有很多胚胎,但是一个胚胎只能有一个病人。

我要实现的目标。Embryo模型有一个名为karyotes的字段,该字段是Charfield。当用户输入karyotes时,将自动填充胚胎的sex。唐氏综合症也一样(请参见下面的模型)

错误:我制作模型的方式sexdown_syndrome始终显示为空

enter image description here

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第一建议

enter image description here

1 个答案:

答案 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

仅供参考似乎您不需要sexdown_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")