DRF:如何在手动创建对象时添加注释?
DRF: How to add annotates when create an object manually?
目前我正在尝试创建一个预期的 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 = f'{boards_endpoint}{board.id}/'
手动构建 URL,而是考虑使用 reverse
,例如url = reverse("path-name", kwargs={"pk": board.id})
.
目前我正在尝试创建一个预期的 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 = f'{boards_endpoint}{board.id}/'
手动构建 URL,而是考虑使用 reverse
,例如url = reverse("path-name", kwargs={"pk": board.id})
.