создайте поля в соответствии с номером в другом поле в django

#python #django #django-models #django-rest-framework #django-views

Вопрос:

У меня есть 3 таблицы(Темы, сектора , зоны), у одного субъекта много секторов, а у одного сектора много зон.Мой вопрос в том, как я должен внедрять свои модели, представления и сериализаторы, возвращая файл json с указанием имени субъекта и количества секторов и количества зон в каждом секторе. Я попробовал это :

     class Subject(models.Model):
      name = models.CharField(max_length=200)
      host = models.CharField(max_length=200, 
               primary_key=True) 
      nb_sectors = models.IntegerField(null=True)    
      def __str__(self):
    return self.name

    class Sector(models.Model):
       name = models.CharField(max_length=200)
       task = models.ForeignKey(Subject 
               ,on_delete=models.CASCADE)
       nb_zones = models.IntegerField(null=True) 
       def __str__(self):
    return self.name

    class Zone(models.Model):
      name = models.CharField(max_length=200)
      sector = models.ForeignKey(Sector 
               ,on_delete=models.CASCADE) 
      status= ChoiceField(choices)
      def __str__(self):
    return self.name   
 

Комментарии:

1. Вы можете добавить свои представления и сериализаторы ? Вы ставите только модели

Ответ №1:

Вы можете определить множество полей в таблице «Тема» для таблицы «Сектор» и в таблице «Сектор» для таблицы «Зона». Итак, ваши модели.py будет выглядеть так,

 class Subject(models.Model): 
    name = models.CharField(max_length=200)
    host = models.CharField(max_length=200,primary_key=True)
    # other atribs...
    sectors = models. ManyToManyField('Sector')
  
    @property
    def sectors_count(self):
        return (self.sectors.count())

    def __str__(self):
       return self.name


class Sector(models.Model):
    name = models.CharField(max_length=200)
    # other atribs...
    zones = models.ManyToManyField('Zone')

    @property
    def zones_count(self):
        return (self.zones.count())

    def __str__(self):
        return self.name


class Zone(models.Model):
    name = models.CharField(max_length=200)
    status= ChoiceField(choices)

    def __str__(self):
        return self.name
 

В сериализаторе тем вы можете либо указать ссылку на сериализатор секторов

 class SubjectSerializer(serializers.ModelSerializer):
    sectors = SectorSerializer(read_only=True, many=True)
    sectors_count = serializers.ReadOnlyField() # this is defined as property in the model

    class Meta:
        model = Subject
        fields = '__all__'


class SectorSerializer(serializers.ModelSerializer):
    zones_count = serializers.ReadOnlyField() # this is defined as property in the model

    class Meta:
        model = Sector
        fields = '__all__'
 

Или вы также можете использовать поданный метод сериализатора и выполнить итерацию по всему объекту зоны

 class SubjectSerializer(serializers.ModelSerializer):
    sectors = serializers.SerializerMethodField(required=False)
    sectors_count = serializers.ReadOnlyField() # this is defined as property in the model

    class Meta:
        model = Subject
        fields = '__all__'

    def get_sectors(self, obj):
        data = []
        for sector in obj.sectors.all():
            data.append({
                'zones_count': sector.zones_count,
                'name': sector.name
            })
        return data
 

Если вы хотите повторно использовать сериализатор секторов, вы можете выбрать первый.

Комментарии:

1. отношение между моими таблицами одно ко многим , почему я должен использовать ManyToManyField ?