Я ищу способ запроса данных из таких моделей, как Author
с полями [pk, name] и Book
[pk, author, title, опубликовано], так что, в конце концов, у меня будет есть что-то подобное
[
{
'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)
UPDATE:
Ну, это было проще, чем я думал; вот что у меня так далеко:
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
.