Есть ли способ ввести значения списка в queryset как пользовательский агрегированный столбец

#python #django #django-queryset

#python #django #django-queryset

Вопрос:

Я ищу способ запрашивать данные из моделей, например, Author с полями [pk, name] и Book [pk, author, title, published] так что, в конце концов, я бы получил что-то вроде этого

 [
  {
    'pk': 'author_pk_1', 'name': 'author__name_1', 'books': [
      {
        'pk': 'book__pk_1',
        'title': 'book_name_1',
        'published': 'book_published_1',
      },
      {
        'pk': 'book__pk_2',
        'title': 'book_name_2',
        'published': 'book_published_2',
      }
    ]
  }
]
  

На данный момент я добился этого, выполнив итерацию по QuerySet и вручную сгруппировав их, но это выглядит совсем не хорошо:

 authors = Author.objects.values('pk', 'name')
grouped = list()
for author in authors:
    entry = dict()
    entry['pk'] = author['pk']
    entry['name'] = author['name']
    entry['books'] = list(Book.objects.filter(author=author['pk']).values('pk', 'title', 'published'))
    grouped.append(entry)
  

Обновить:

Ну, это было проще, чем я думал; вот что у меня есть до сих пор:

view.py

 @api_view(['GET'])
def api_get_grouped_books(request, *args, **kwargs):
  if request.method == 'GET':
    authors = Author.objects.all()
    serializer = AuthorSerializer(authors, many=True)
    return Response(serializer.data)
  

serializers.py

 class BookSerializer(serializers.ModelSerializer):
  class Meta:
    model = Book
    fields = ('title', 'published', )


class AuthorSerializer(serializers.ModelSerializer):

  books = BookSerializer(many=True)

  class Meta:
    model = Author
    fields = ('name', 'books', )

  def create(self, validated_data):
    books_data = validated_data.pop('books')

    author, _ = Author.objects.get_or_create(
      name=validated_data.get('name'),
      defaults=validated_data
    )

    for book_data in books_data:
      try:
        Book.objects.get(title=book_data.get('title'))
      except ObjectDoesNotExist:
        Book.objects.create(author=author, **book_data)

    return author
  

Примечание: Сначала я получал ошибку AttributeError при попытке опубликовать некоторые данные — он жаловался, что поле books не является частью Author модели, поэтому в итоге я добавил атрибут related_name='books' в author поле ForeignKey в Book модели.

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

1. для чего вам это нужно? что такое конечная точка?

2. Используете ли вы фреймворк Django REST?

3. @JPG Да, я делаю.

4. У вас есть какой-нибудь сериализатор для этого?

5. @JPG Пожалуйста, взгляните на обновление.