参考官方文档。我必须按queryset
进行过滤。
但我的知识有限。然后我决定使用SerializerMethodField
找到list()
方法。它列出了所有项目。
问题:
我想要排除带有[]
的商品
class ProductViewMissingDisplayImageSerializer(ModelControllerSerializer):
missing_types = serializers.SerializerMethodField(read_only=True)
def get_missing_types(self, obj: ProductView) -> typing.List[str]:
return check_image_type(obj)
AS是输出:
{
"product_view_pk": 78,
"name": "ATF",
"service": 4,
"display_mode": "IMAGE ONLY",
"missing_types": [
"CONTENT IMAGE",
"POPUP IMAGE"
]
},
{
"product_view_pk": 83,
"name": "サスティナ(化学合成油)",
"service": 4,
"display_mode": "IMAGE ONLY",
"missing_types": []
},
预期结果:
{
"product_view_pk": 78,
"name": "ATF",
"service": 4,
"display_mode": "IMAGE ONLY",
"missing_types": [
"CONTENT IMAGE",
"POPUP IMAGE"
]
},
以下是check_image_type
。
def check_image_type(obj: ProductView) -> typing.List[str]:
# Unable to put this `dict_required_values` to `base.py` because it use class attribute
dict_required_values = {
settings.PREFERED_LIST[0]: [DisplayImage.CONTENT_IMAGE, DisplayImage.POPUP_IMAGE],
settings.PREFERED_LIST[1]: [DisplayImage.HEADER_IMAGE, DisplayImage.CONTENT_IMAGE,
DisplayImage.POPUP_IMAGE],
settings.PREFERED_LIST[2]: [DisplayImage.HEADER_IMAGE, DisplayImage.POPUP_IMAGE],
settings.PREFERED_LIST[3]: [DisplayImage.POPUP_IMAGE],
}
display_mode = obj.attribute.get('display_mode')
if display_mode not in settings.PREFERED_LIST:
return []
required_values = dict_required_values[display_mode]
logger.info(f'ProductView id: {obj.id}, display_mode: {display_mode}')
logger.info(f'Required fields are {required_values}')
qs = DisplayImage.objects.filter(attribute__product_view_pk=str(obj.id))
for i in qs:
try:
logger.info(f'Removing {i.type}, {i.get_type_display()}')
required_values.remove(i.type)
except Exception as err:
logger.info(f'DisplayImage id: {i.id} {err}')
required_values = [str(DisplayImage.image_type_choices[i][1]).upper() for i in required_values]
return required_values
我该怎么做?
更新
我的时态解决方案是用ViewSet
中的列表推导替换查询集。因为我无法查询@property
。
class MissingDisplayImage(viewsets.ModelViewSet):
serializer_class = ProductViewMissingDisplayImageSerializer
queryset = ProductView.objects.all()
permission_classes = (IsAuthenticated, ProductViewPermission)
def list(self, request, *args, **kwargs):
import timeit
start_time = timeit.default_timer()
queryset = self.filter_queryset(self.get_queryset())
instances = [i for i in queryset if i.image_type != []] # Hack image_type here
page = self.paginate_queryset(instances)
if page is not None:
serializer = self.get_serializer(instances, many=True)
# serializer = self.get_serializer(page, many=True)
elapsed = timeit.default_timer() - start_time
logger.info(f'Elapsed: {elapsed}')
return self.get_paginated_response(serializer.data)
# serializer = self.get_serializer(queryset, many=True)
serializer = self.get_serializer(instances, many=True)
elapsed = timeit.default_timer() - start_time
logger.info(f'Elapsed: {elapsed}')
return Response(serializer.data)
答案 0 :(得分:0)
class ProductViewSet(ModelViewSet):
queryset = Product.objects.all()
permission_classes = (IsAuthenticated)
serializer_class = ProductListSerializer
def get_queryset(self):
queryset = self.queryset
has_missing_types = self.request.query_params.get('has_missing_types', '0')
if has_missing_types == '1':
product_ids = []
for product in queryset:
if len(product.check_image_type())>0:
product_ids.append(product .id)
queryset = queryset.filter(id__in=product_ids).all()
return queryset
按/product/?has_missing_types=1
另一种方法是将missing_types保存到db并在每次更改missing_types时更新它,然后使用django-filter