Как изменить набор запросов в Django?

Я пытаюсь изменить вывод сериализатора Django.

Представление на основе классов имеет функцию get_projects, которая возвращает набор запросов экземпляров контракта.

projects = Project.objects.all()
contracts = Contract.objects.filter(project__in=projects)

Отношения контракта и проекта — один ко многим:

class Contract(models.Model):
    project = models.ForeignKey(Project)

Теперь у меня есть такой MySerializer:

class MySerializer(serializers.Serializer):
    project_guid = serializers.UUIDField(source='guid')
    project_name = serializers.CharField(source='name')
    contract_guid = serializers.UUIDField(source='guid')
    contract_number = serializers.CharField(source='number')

Ответ MySerializer:

[
  {
    "projectGuid": "project_guid_1",
    "projectName": "project_name_1",
    "contractGuid": "contract_guid_1",
    "contractNumber": "contract_number_1"
  },
  {
    "projectGuid": "project_guid_1",
    "projectName": "project_name_1",
    "contractGuid": "contract_guid_2",
    "contractNumber": "contract_number_2"
  },
  {
    "projectGuid": "project_guid_2",
    "projectName": "project_name_2",
    "contractGuid": "contract_guid_4",
    "contractNumber": "contract_number_4"
  },
  {
    "projectGuid": "project_guid_2",
    "projectName": "project_name_2",
    "contractGuid": "contract_guid_5",
    "contractNumber": "contract_number_5"
  },
]

Я хотел бы изменить вывод сериализатора - сгруппировать контракты для конкретных проектов, например:

[
 {
  "project_guid": "project_guid_1",
  "project_name": "project_name_1",
  "contracts": [
    {
      "contract_guid": "contract_guid_1",
      "contract_number": "contract_number_1",
    },
    {
      "contract_guid": "contract_guid_2",
      "contract_number": "contract_number_2",
    },
    ....
  ]
 },
 {
  "project_guid": "project_guid_2",
  "project_name": "project_name_2",
  "contracts": [
    {
      "contract_guid": "contract_guid_4",
      "contract_number": "contract_number_4",
    },
    {
      "contract_guid": "contract_guid_5",
      "contract_number": "contract_number_5",
    },
    ....
  ]
 },
]

Как я могу это сделать?

Сначала вам следует создать ContractSerializer и использовать его сериализатор внутри ProjectSerializer поля контракта contracts = ContractSerializer(blabla....

user70 25.03.2024 20:51

Отвечает ли это на ваш вопрос? Вложенная модель Django или сериализаторы

user70 25.03.2024 20:57
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
63
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Для этого вы можете попробовать это

class ContactSerializer(serializers.ModelSerializer):
    class Meta:
       model = Contract
       fields = ["contract_guid", "contract_number"]

class ProjectSerializer(serializers.ModelSerializer):
    contracts = ContactSerializer(many=True)
    class Meta:
        model = Project 
        fields = ["project_guid", "project_name", "contracts"]

И не забывайте использовать предварительную выборку для оптимизации вашего запроса.

Ответ принят как подходящий

Проблема была в наборе запросов. Я провел рефакторинг qs в get_projects:

projects = Project.objects.filter(active=True).prefetch_related(
        Prefetch('contract_set', queryset=Contract.objects.filter(**filters), to_attr='contracts')
    )

И реорганизовал MySerializer следующим образом:

class ContractSerializer(serializers.Serializer):
    contract_guid = serializers.UUIDField(source='guid')
    contract_number = serializers.CharField(source='number')

class MySerializer(serializers.Serializer):
    project_guid = serializers.UUIDField(source='guid')
    project_name = serializers.CharField(source='name')
    contracts = ContractSerializer(many=True)

Спасибо SerhiiL за подсказку с prefetch_related.

Другие вопросы по теме