Выбор вложенного сериализатора из выпадающего списка в Django REST Framework

Я хочу иметь возможность POST / PUT вложенного сериализатора, связанного с уже существующим другим ресурсом, выбирая этот другой ресурс из выпадающей кнопки.

Моя текущая ситуация, которая работает, но не является для меня идеальной, следующая:

У меня есть следующие модели, с набором данных, существующим для данного проекта и данного источника данных.

  • Project - это модель, которая существует независимо от источника данных и от набора данных. Ее url - projects/projectid/

    .
  • Datasource - это модель, которая существует независимо от Project и от Dataset. Ее url - datasources/datasourceid/

    .
  • Для создания набора данных необходимы проект и источник данных. Его url - projects/projectid/datasets/datasetid

    .
class Project(models.Model):
    """Class that models analytical projects"""
    title = models.CharField(max_length=300)
    description = models.TextField(null=True)

    def __str__(self):
        return self.title


class Datasource(models.Model):
    """Class that models datasources under projects"""
    title = models.CharField(max_length=300)
    description = models.CharField(max_length=300)

    def __str__(self):
        return self.title


class Dataset(models.Model):
    """Class that models datasets under projects"""
    title = models.CharField(max_length=300)
    project = models.ForeignKey(Project,
                                on_delete=models.CASCADE,
                                related_name='datasets')
    datasource = models.ForeignKey(Datasource,
                                   on_delete=models.CASCADE,
                                   related_name='datasources')
(...)


    def __str__(self):
        return self.title

Вот сериализаторы, которые я сначала создал для Datasource и Dataset:

class DatasourceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Datasource
        fields = ['id', 'title', 'description']




class DatasetSerializer(serializers.ModelSerializer):
    queryset = Datasource.objects.all()
    # datasource = DatasourceSerializer(many=False, read_only=False) , will be uncommented below
    datasource = serializers.PrimaryKeyRelatedField(queryset=queryset,
                                                    read_only=False,
                                                    many=False)

    class Meta:
        model = Dataset
        fields = ['id', 'title', 'datasource',
                  'description', 'dataformat', 'extraction_method',
                  'confidentiality_level', 'high_priority',
                  'used_in_model']

    def create(self, validated_data):
        validated_data['project_id'] = self.context['project_id']
        return super().create(validated_data)

В результате получается следующий JSON-формат набора данных:

enter image description here

Это работает нормально, поскольку я могу POST и PUT наборы данных для данного проекта, выбирая источник данных с помощью выпадающей кнопки.

Однако это немного ограничено, поскольку единственная информация, которую я получаю от Datasource, - это ID, а не его внутренняя информация (название, описание). Я хотел бы получить вложенный сериализатор Datasource, а не просто ID Datasource.

Я пытался сделать следующее в сериализаторах:

class DatasourceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Datasource
        fields = ['id', 'title', 'description']




class DatasetSerializer(serializers.ModelSerializer):
    queryset = Datasource.objects.all()
    datasource = DatasourceSerializer(many=False, read_only=False) # is commented above
    # datasource = serializers.PrimaryKeyRelatedField(queryset=queryset,   is not commented above
    #                                                 read_only=False,
    #                                                 many=False)

    class Meta:
        model = Dataset
        fields = ['id', 'title', 'datasource',
                  'description', 'dataformat', 'extraction_method',
                  'confidentiality_level', 'high_priority',
                  'used_in_model']

    def create(self, validated_data):
        validated_data['project_id'] = self.context['project_id']
        return super().create(validated_data)

Но это привело только к следующему результату, который не является удовлетворительным, поскольку я должен ввести информацию о Datasource вручную, как если бы он был новым, и я не могу выбрать Datasource с помощью выпадающей кнопки, в отличие от вышеуказанного:

enter image description here

Можно ли сделать так, чтобы информация о вложенном источнике данных находилась внутри сериализатора набора данных, а при выполнении POST / PUT для набора данных можно было выбрать источник данных из существующих с помощью выпадающего списка?

Я посмотрел документацию для Nested relationships https://www.django-rest-framework.org/api-guide/relations/#nested-relationships, но примеры, которые они приводят с альбомами и треками, не соответствуют моей ситуации, поскольку в их случае они создают треки "на лету", когда они создают альбом, так как альбом не может существовать без треков, но источник данных может существовать без набора данных в моем случае, и я только хочу выбрать существующий источник данных для создания нового набора данных.

Вернуться на верх