Эффективная сериализация нескольких объектов, которым необходимо совершить REST-вызов
Допустим, у меня есть простая модель, Account
, следующего вида:
class Account(models.Model):
name = models.CharField(db_index=True)
И AccountSerializer
следующим образом:
class AccountSerializer(serializers.ModelSerializer):
name = CharField(source="account.name")
def _get_favorite_color(self, obj: Account):
# Make a rest call to get this account's favorite color
favorite_color = _get_favorite_color(name)
У меня также есть ViewSet
с действием list
для получения всех счетов, а также Serializer
для сериализации каждого элемента. Возвращаемый JSON
имеет следующую форму:
{
'accounts':[
{'name':'dave', 'favorite_color':'blue'},
{'name':'john', 'favorite_color':'black'},
]
}
Каким образом django-esque можно "массово" получить эти любимые цвета? Этот вызов REST
для получения любимых цветов может принимать на вход список всех учетных записей id
и возвращать их в одном списке, избегая n
вызовов REST, когда достаточно одного.
Где эта логика будет иметь наибольший смысл? Я не могу поместить эту логику в Serializer
, учитывая, что она обрабатывает только один объект за раз. Есть ли другое место, куда ее можно поместить, а не в ViewSet
? Насколько я понимаю, ViewSet
должны быть как можно более компактными.
Вы можете использовать декоратор действия в Account Viewset для получения данных, где вы можете передать идентификаторы счетов в url args.
@action(methods=['GET'], detail=False, url_name='favourite_color')
def favourite_color(self, request, pk=None):
account_ids = list(request.query_params.get('account_ids').split(","))
queryset = Account.objects.filter(id__in=account_ids).values('favourite_color')
# Not sure how favourite color is linked to account
# You will get the values hitting one query, and you can make a json response which needs to be returned
return Response(json_response_of_favourite_colors)
Url будет выглядеть примерно так:
url: accounts/favourite_color/?account_ids=1,2,3