Получение связанных записей модели с помощью одного запроса GET к основной модели в DRF

#django-rest-framework #django-serializer

#django-rest-framework #django-сериализатор

Вопрос:

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

Мои модели:

 #MASTER TABLE
class UserDetails(models.Model):
    user_id = models.UUIDField(primary_key=True,default=uuid.uuid4,editable=False)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)

#RELATED TABLES
class EducationProfile(models.Model):
    degree_level = models.CharField(max_length=100, null=True, blank=True)
    degree = models.CharField(max_length=100, null=True, blank=True)
    start_date = models.DateField(null=True, blank=True)
    completion_date = models.DateField(null=True, blank=True)
    user = models.ForeignKey(UserDetails, related_name='education')

class AwardsRecognitions(models.Model):
    award_name = models.CharField(max_length=100, null=True, blank=True)
    awarded_by = models.CharField(max_length=100, null=True, blank=True)
    award_date = models.DateField(null=True, blank=True)
    user = models.ForeignKey(UserDetails, related_name='awards')
  

Я пытаюсь получить информацию обо всех связанных моделях с помощью запроса GET к UserDetails модели. Я пытался использовать PrimaryKeyRelatedField в UserDetailsSerializer , но это не дает мне ожидаемого результата. Результатом является наличие только идентификатора связанной записи во вложенных полях.

Мои сериализаторы:

 class UserDetailsSerializer(serializers.ModelSerializer):
    education = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
    awards = serializers.PrimaryKeyRelatedField(read_only = True, many = True)

    class Meta:
        model = UserDetails
        fields = '__all__'

class EducationProfileSerializer(serializers.ModelSerializer):

    class Meta:
        model = EducationProfile
        fields = '__all__'

class AwardsRecognitionsSerializer(serializers.ModelSerializer):

    class Meta:
        model = AwardsRecognitions
        fields = '__all__'
  

Ожидаемый результат:

Формат запроса GET — <<UserDetails_model_endpoint>>/<<user_id_primary_key>>/

Формат ответа —

 {"user_id" : <<user_id>>,
 "first_name" : "foo",
 "last_name" : "bar",
 "education":[{"id":5,
               "degree_level": "xxxx",
               "degree":"xxxx",
               "start_date":"xxxx",
               "completion_date":"xxxx"},
              {"id":7,
               "degree_level": "yyyy",
               "degree":"yyyy",
               "start_date":"yyyy",
               "completion_date":"yyyy"}],
 "awards":[{"id":3,
            "award_name":"nnnn",
            "awarded_by":"nnnn",
            "awarded_date":"nnnn"},
           {"id":7,
            "award_name":"mmm",
            "awarded_by":"mmmm",
            "award_date":"mmmm"}]
  

Пожалуйста, укажите мне правильное направление для достижения этой цели, любая идея приветствуется. TIA

Ответ №1:

Включите сериализаторы для моделей, которые вы создали для связанных моделей, вместо поля, связанного с первичным ключом. PrimaryKeyRelatedField предоставит вам только первичный ключ в JSON, как следует из названия.

 class UserDetailsSerializer(serializers.ModelSerializer):
    education = EducationProfileSerializer(many=True, read_only=True)
    awards = AwardsRecognitionsSerializer(many=True, read_only=True)

    class Meta:
        model = UserDetails
        fields = '__all__'
  

Для получения более подробной информации проверьте https://www.django-rest-framework.org/api-guide/relations/#nested-relationships

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

1. Спасибо. Я тоже пробовал это, я получаю ожидаемый результат. С точки зрения производительности я не уверен, что это лучший способ получить результат. Не могли бы вы любезно помочь мне понять с этой точки зрения?

2. Что именно вы подразумеваете под производительностью? Это рекомендуемый способ сделать это, упомянутый в документах DRF. Если под производительностью вы подразумеваете количество запросов, сгенерированных из-за того, что вы имеете дело с несколькими связанными моделями, тогда это будет зависеть от вашего набора запросов, просто убедитесь, что вы не столкнулись с проблемой запроса N 1