DRF нормализует вложенный сериализатор для загрузки отчета Excel с помощью XLSXRenderer
у меня есть
ManyToMany
поле в моих моделях. В сериализаторе я могу получить вложенные сериализованные данные, но хочу их нормализовать.
models.py
class Authors(models.Model):
name = models.CharField(max_length=20)
class Mets:
db_table = "authors"
class Books(models.Model):
book_name = models.CharField(max_length=100)
authors = models.ManyToManyField(Authors, related_names="books")
class Meta:
db_table = "books"
serializers.py
class AuthorSerializer(serializer.ModelSerializer):
name = serializer.CharField()
class Meta:
model = Authors
field = ("name",)
class BooksSerializer(serializer.ModelSerializer):
authors = AuthorSerializer()
class Meta:
model = Books
field = ("book_name", "authors")
Результатом выше будет:
"result": [
{
"book_name": "Sample",
"authors": [
{
"name": "Person 1",
},
{
"name": "Person 2",
}
]
}
]
Но я хочу вывести что-то вроде этого:
"result": [
{
"book_name": "Sample",
"author_name": "Person 1",
},
{
"book_name": "Sample",
"author_name": "Person 2",
},
]
ОБНОВИТЬ
views.py
class ReportViewSet(XLSXFileMixin, viewsets.ReadOnlyModelViewSet):
serializer_class = BookSerializer
renderer_classes = [XLSXRenderer]
filename = 'my_export.xlsx'
def get_queryset(self):
queryset = Book.objects.all()
book_id = self.request.query_params.get("pk", None)
if book_id is not None:
queryset = queryset.filter(id=book_id)
return queryset
В отчете Excel должны быть столбцы:,
author_name
Но с решением, предоставленным @Klim Bim, я получаю пустой отчет Excel с только именами столбцов:
book_name
а также
authors
.
Заранее спасибо.
2 ответа
вы должны использоватьlist
вместоget_queryset
:
class ReportViewSet(XLSXFileMixin, ReadOnlyModelViewSet):
serializer_class = BookSerializer
renderer_classes = [XLSXRenderer]
filename = 'my_export.xlsx'
def list(self, request, *arg, **kwargs):
queryset = Books.objects.filter(#some_filter#)
return Response(data=self.serializer_class(queryset, many=True).data)
и никогда не забывайте менятьurls.py
как показано ниже:
urlpatterns = [
...
path('download-my-file/', ReportViewSet.as_view({'get': 'list'})),
....
]
Если вы хотите изменить поведение отображения, вы должны переопределить
to_representation()
def to_representation(self, instance):
data = super().to_representation(instance)
authors = data.pop('authors')
retval = list()
for author in authors:
retval.append({**data, "author_name": author.get("name")})
return {"result": retval}