DRF: Как добавить аннотации при создании объекта вручную?
В настоящее время я пытаюсь создать ожидаемый json для использования в моем тесте:
@pytest.mark.django_db(databases=['default'])
def test_retrieve_boards(api_client):
board = baker.make(Board)
objs = BoardSerializerRetrieve(board)
print(objs.data)
url = f'{boards_endpoint}{board.id}/'
response = api_client().get(url)
assert response.status_code == 200
Но я получаю следующую ошибку:
AttributeError: Got AttributeError when attempting to get a value for field `cards_ids` on serializer `BoardSerializerRetrieve`.
E The serializer field might be named incorrectly and not match any attribute or key on the `Board` instance.
E Original exception text was: 'Board' object has no attribute 'cards_ids'
В настоящее время cards_ids
добавлены в мой viewSet на get_queryset
метод:
def get_queryset(self):
#TODO: last update by.
#TODO: public collections.
"""Get the proper queryset for an action.
Returns:
A queryset object according to the request type.
"""
if "pk" in self.kwargs:
board_uuid = self.kwargs["pk"]
qs = (
self.queryset
.filter(id=board_uuid)
.annotate(cards_ids=ArrayAgg("card__card_key"))
)
return qs
return self.queryset
а это мой сериализатор:
class BoardSerializerRetrieve(serializers.ModelSerializer):
"""Serializer used when retrieve a board
When retrieve a board we need to show some informations like last version of this board
and the cards ids that are related to this boards, this serializer will show these informations.
"""
last_version = serializers.SerializerMethodField()
cards_ids = serializers.ListField(child=serializers.IntegerField())
def get_last_version(self, instance):
last_version = instance.history.first().prev_record
return HistoricalRecordSerializer(last_version).data
class Meta:
model = Board
fields = '__all__'
как лучше всего решить эту проблему? Я думал создать метод get_cards_ids
на сериализаторе и удалить аннотацию, но я не знаю, как это сделать и просто гуглю сейчас. правда не знаю, правильный ли это способ сделать.
Тестируйте представление, а не сериализатор, т.е. удалите BoardSerializerRetrieve(board)
из кода тестирования.
cards_ids
аннотируется на уровне ViewSet. Затем аннотированный кверисет передается сериализатору.
@pytest.mark.django_db(databases=['default'])
def test_retrieve_boards(api_client):
board = baker.make(Board)
url = f'{boards_endpoint}{board.id}/'
response = api_client().get(url)
assert response.status_code == 200
Кроме того, вместо того, чтобы строить URL вручную с помощью url = f'{boards_endpoint}{board.id}/'
, используйте reverse
, например url = reverse("path-name", kwargs={"pk": board.id})
.