как автоматически заполнять поля Django Rest Framework Model - PullRequest
0 голосов
/ 05 ноября 2018

Попытка автоматического заполнения атрибутов модели с помощью Django rest framework

Введение: У меня есть 2 модели Patient и Embryo Существует только 1 пользователь, который является суперпользователем. Все пациенты принадлежат суперпользователю. У одного пациента может быть много эмбрионов, но у эмбриона может быть только один пациент.

Чего я хочу достичь Модель Embryo имеет поле под названием karyotes, которое является Charfield. когда пользователь вводит karyotes, sex эмбриона заполняется автоматически. То же самое с синдромом Дауна (см. Модели ниже)

Ошибка: То, как я сделал свои модели. sex и down_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

Ниже приведены мои views.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"))

ниже мои serializers.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}
                        }

Согласно 1-му совету @Ruddra

enter image description here

1 Ответ

0 голосов
/ 05 ноября 2018

Вы можете попытаться переопределить метод сохранения модели следующим образом:

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

FYI Кажется, вам не нужно хранить информацию 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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...