如何向 ModelViewset 响应添加额外的字典?
How to add an extra dictionary to ModelViewset response?
使用模型
class Sim(modesl.Model):
iccid = models.CharField(max_length=64)
carrier = models.CharField(max_length=50)
status = models.CharField(max_length=100)
class Meta(object):
app_label = "app"
verbose_name = "Sim"
class JSONAPIMeta:
resource_name = "sim"
external_field = "id"
使用视图 :
class SimView(viewsets.ModelViewSet):
queryset = Sim.objects.all()
serializer_class = SimSerializer
使用序列化程序:
class SimSerializer(serializers.ModelSerializer):
class Meta:
model = Sim
fields = "__all__"
for /get/
{
"links": {
"first": "some link",
"last": "some link"
"next": null,
"prev": null
},
"data": [
{
"type": "sim",
"id": "1",
"attributes": {
"carrier": "Vodaphone",
"iccid": "12345678912345678912",
"status": "UnManaged",
}
}
],
"meta": {
"pagination": {
"count": 1,
"limit": 20,
"offset": 0
}
}
}
现在我想在响应中发送字典“license_info
”,它应该在响应中只出现一次,因此响应可能如下所示:
{
"links": {
"first": "some link",
"last": "some link"
"next": null,
"prev": null
},
"data": [
{
"type": "sim",
"id": "1",
"attributes": {
"carrier": "Vodaphone",
"iccid": "12345678912345678912",
"status": "UnManaged",
}
}
#Either add here
{
"license_info":"some value"
}
],
"meta": {
"pagination": {
"count": 1,
"limit": 20,
"offset": 0
}
}
#Or Add here
"license_info":{
"some key value pairs"
}
}
我试图将 license_info 设置为 属性,但每个实例都会重复此操作。
我尝试的另一种方法是覆盖 list
方法
def list(self, request, *args, **kwargs):
instance = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(instance)
if page is not None:
serializer = self.get_serializer(page, many=True)
else:
serializer = self.get_serializer(instance, many=True)
serializer_data = serializer.data # get the default serialized data
serializer_data.append({"license_info": "some value"})
return self.get_paginated_response(serializer.data) if page else Response(serializer_data)
但这给出了以下错误:
"/home/pranav/Desktop/cp_projects/connector/venv/lib/python3.7/site-
packages/rest_framework_json_api/renderers.py\", line 589, in render\n
resource_instance = serializer.instance[position] # Get current instance\nIndexError:
list index out of range", "status_code": 500, "request": "<WSGIRequest: GET
'/api/v1/sim'>", "level": "ERROR"}
我也试过了:
def list(self, request, *args, **kwargs):
instance = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(instance)
if page is not None:
serializer = self.get_serializer(page, many=True)
else:
serializer = self.get_serializer(instance, many=True)
newdict = []
newdict.append(serializer.data)
newdict.append({"license_info": "some value"})
return Response(newdict, status=status.HTTP_201_CREATED)
但是使用这个我得到了没有“链接”和“元”键值的响应负载。
我正在为 rest_framework 使用以下设置:
"DEFAULT_PAGINATION_CLASS": "rest_framework_json_api.pagination.JsonApiLimitOffsetPagination",
"PAGE_SIZE": env["max_page_size"],
"DEFAULT_PARSER_CLASSES": ("rest_framework_json_api.parsers.JSONParser",),
"DEFAULT_RENDERER_CLASSES": rest_framework_json_api.renderers.JSONRenderer,
"DEFAULT_METADATA_CLASS": "rest_framework_json_api.metadata.JSONAPIMetadata",
要以给定的方式向响应添加额外的字典,您可以创建自定义分页 class 并覆盖 get_paginated_response
,这将 return 以所需的方式响应和然后在列表方法中,您可以动态更改该额外字典的值。
class CustomLimitOffsetPagination(JsonApiLimitOffsetPagination):
def get_paginated_response(self, data):
return Response(
{
"results": data,
"meta": {
"pagination": OrderedDict(
[
("count", self.count),
("limit", self.limit),
("offset", self.offset),
]
)
},
"links": OrderedDict(
[
("first", self.get_first_link()),
("last", self.get_last_link()),
("next", self.get_next_link()),
("prev", self.get_previous_link()),
]
),
#Extra dictionary
"license_info":OrderedDict(),
}
)
在设置中为您添加此分页 class rest_framwork
"DEFAULT_PAGINATION_CLASS": "path to your CustomLimitOffsetPagination",
现在要向“license_info”添加值,您必须覆盖视图中的列表方法
def list(self,request,*args,**kwargs):
instance = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(instance)
response = None
if page is not None:
serializer = self.get_serializer(page,many=True)
response = self.get_paginated_response(serializer.data)
response.data["license_info"] = OrderedDict(
[
("key", "value"),
]
)
else:
serializer = self.get_serializer(instance,many=True)
response_data = []
response_data.extend(serializer.data)
response_data.append({"license_info":"some value"})
response = Response(response_data)
return response
使用模型
class Sim(modesl.Model):
iccid = models.CharField(max_length=64)
carrier = models.CharField(max_length=50)
status = models.CharField(max_length=100)
class Meta(object):
app_label = "app"
verbose_name = "Sim"
class JSONAPIMeta:
resource_name = "sim"
external_field = "id"
使用视图 :
class SimView(viewsets.ModelViewSet):
queryset = Sim.objects.all()
serializer_class = SimSerializer
使用序列化程序:
class SimSerializer(serializers.ModelSerializer):
class Meta:
model = Sim
fields = "__all__"
for /get/
{
"links": {
"first": "some link",
"last": "some link"
"next": null,
"prev": null
},
"data": [
{
"type": "sim",
"id": "1",
"attributes": {
"carrier": "Vodaphone",
"iccid": "12345678912345678912",
"status": "UnManaged",
}
}
],
"meta": {
"pagination": {
"count": 1,
"limit": 20,
"offset": 0
}
}
}
现在我想在响应中发送字典“license_info
”,它应该在响应中只出现一次,因此响应可能如下所示:
{
"links": {
"first": "some link",
"last": "some link"
"next": null,
"prev": null
},
"data": [
{
"type": "sim",
"id": "1",
"attributes": {
"carrier": "Vodaphone",
"iccid": "12345678912345678912",
"status": "UnManaged",
}
}
#Either add here
{
"license_info":"some value"
}
],
"meta": {
"pagination": {
"count": 1,
"limit": 20,
"offset": 0
}
}
#Or Add here
"license_info":{
"some key value pairs"
}
}
我试图将 license_info 设置为 属性,但每个实例都会重复此操作。
我尝试的另一种方法是覆盖 list
方法
def list(self, request, *args, **kwargs):
instance = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(instance)
if page is not None:
serializer = self.get_serializer(page, many=True)
else:
serializer = self.get_serializer(instance, many=True)
serializer_data = serializer.data # get the default serialized data
serializer_data.append({"license_info": "some value"})
return self.get_paginated_response(serializer.data) if page else Response(serializer_data)
但这给出了以下错误:
"/home/pranav/Desktop/cp_projects/connector/venv/lib/python3.7/site-
packages/rest_framework_json_api/renderers.py\", line 589, in render\n
resource_instance = serializer.instance[position] # Get current instance\nIndexError:
list index out of range", "status_code": 500, "request": "<WSGIRequest: GET
'/api/v1/sim'>", "level": "ERROR"}
我也试过了:
def list(self, request, *args, **kwargs):
instance = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(instance)
if page is not None:
serializer = self.get_serializer(page, many=True)
else:
serializer = self.get_serializer(instance, many=True)
newdict = []
newdict.append(serializer.data)
newdict.append({"license_info": "some value"})
return Response(newdict, status=status.HTTP_201_CREATED)
但是使用这个我得到了没有“链接”和“元”键值的响应负载。
我正在为 rest_framework 使用以下设置:
"DEFAULT_PAGINATION_CLASS": "rest_framework_json_api.pagination.JsonApiLimitOffsetPagination",
"PAGE_SIZE": env["max_page_size"],
"DEFAULT_PARSER_CLASSES": ("rest_framework_json_api.parsers.JSONParser",),
"DEFAULT_RENDERER_CLASSES": rest_framework_json_api.renderers.JSONRenderer,
"DEFAULT_METADATA_CLASS": "rest_framework_json_api.metadata.JSONAPIMetadata",
要以给定的方式向响应添加额外的字典,您可以创建自定义分页 class 并覆盖 get_paginated_response
,这将 return 以所需的方式响应和然后在列表方法中,您可以动态更改该额外字典的值。
class CustomLimitOffsetPagination(JsonApiLimitOffsetPagination):
def get_paginated_response(self, data):
return Response(
{
"results": data,
"meta": {
"pagination": OrderedDict(
[
("count", self.count),
("limit", self.limit),
("offset", self.offset),
]
)
},
"links": OrderedDict(
[
("first", self.get_first_link()),
("last", self.get_last_link()),
("next", self.get_next_link()),
("prev", self.get_previous_link()),
]
),
#Extra dictionary
"license_info":OrderedDict(),
}
)
在设置中为您添加此分页 class rest_framwork
"DEFAULT_PAGINATION_CLASS": "path to your CustomLimitOffsetPagination",
现在要向“license_info”添加值,您必须覆盖视图中的列表方法
def list(self,request,*args,**kwargs):
instance = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(instance)
response = None
if page is not None:
serializer = self.get_serializer(page,many=True)
response = self.get_paginated_response(serializer.data)
response.data["license_info"] = OrderedDict(
[
("key", "value"),
]
)
else:
serializer = self.get_serializer(instance,many=True)
response_data = []
response_data.extend(serializer.data)
response_data.append({"license_info":"some value"})
response = Response(response_data)
return response