[英]How do I use multi tag filters in Django REST Framework API response?
首先,如果我沒有用更好的詞來問問題,我深表歉意。 我正在構建 DRF 應用程序,我有Products
Model、 ProductSerializer
和ProductsSummaryView
。 此外,我有 Workspace Model(不打算談論它,因為它與問題無關)。 現在,我想在成功響應中返回那些附加在特定工作區的產品詳細信息,並根據某些參數進行過濾。
我做了什么:我定義filterset_fields
和filter_backends
。 它工作正常。 例如,如果我 go 到這個 URL {{domain}}/path/?country__title=Japan
,它會過濾日本的數據並顯示給我。 但問題是,我想使用多標簽進行過濾,比如如果我想查看日本和韓國的詳細信息,那么我想要這樣的{{domain}}/path/?country__title=Japan&country__title=Korea
,但它不起作用,它只返回所有詳細信息。 我什至嘗試在 URL 中添加空列表格式並嘗試此 URL {{domain}}/path/?country__title[]=Japan&country__title[]=Korea
,但它仍然沒有用。
有人可以幫我嗎?
我的Product
Model 是:
class Product(BaseModel):
"""Product model to store all prices of a product and
related brand and countries it's available in"""
product = models.CharField(max_length=255)
country = models.ForeignKey(Country, null=True, on_delete=models.DO_NOTHING)
car_brand = models.ForeignKey(
CarBrand, on_delete=models.DO_NOTHING, null=True, blank=True
)
part = models.ForeignKey(Part, null=True, blank=True, on_delete=models.DO_NOTHING)
fzg_segment = models.ForeignKey(
FZGSegment, on_delete=models.DO_NOTHING, null=True, blank=True
)
parts_group = models.ForeignKey(
PartsGroup, on_delete=models.DO_NOTHING, null=True, blank=True
)
last_collected = models.DateField(null=True, blank=True)
usage_recommendation = models.CharField(max_length=255)
recommended_action = models.CharField(max_length=255)
recommended_action_value = models.DecimalField(max_digits=6, decimal_places=2)
recommended_price = models.DecimalField(max_digits=6, decimal_places=2)
rrp = models.DecimalField(max_digits=6, decimal_places=2)
iam_price = models.DecimalField(max_digits=6, decimal_places=2)
currency = models.ForeignKey(
Currency, null=True, blank=True, on_delete=models.DO_NOTHING
)
iam_index = models.DecimalField(max_digits=6, decimal_places=2)
factor = models.DecimalField(max_digits=6, decimal_places=2)
items_count = models.PositiveIntegerField(default=0)
manufacturer = models.ForeignKey(
Manufacturer, on_delete=models.DO_NOTHING, null=True, blank=True
)
is_in_stock = models.BooleanField(default=True)
added_at = models.DateField(null=True, blank=True)
last_in_stock = models.DateField(null=True, blank=True)
last_searched_at = models.DateField(null=True, blank=True)
avg_in_stock = models.DecimalField(
null=True, blank=True, max_digits=6, decimal_places=2
)
def __str__(self):
return self.product
我的ProductSerializer
序列化器是:
class ProductSerializer(serializers.ModelSerializer):
"""Serializer for the part object"""
parts_group = PartsGroupSerializer()
fzg_segment = FZGSegmentSerializer()
class Meta:
model = Product
fields = (
"id",
"product",
"fzg_segment",
"parts_group",
"last_collected",
"usage_recommendation",
"recommended_action",
"recommended_action_value",
"recommended_price",
"rrp",
"iam_price",
"iam_index",
"factor",
"items_count",
)
read_only_fields = ("id",)
我的ProductsSummaryView
API 是:
class ProductsSummaryView(mixins.ListModelMixin, viewsets.GenericViewSet):
"""Viewset to return data for products in a workspace"""
serializer_class = serializers.ProductSerializer
permission_classes = (permissions.IsWorkspaceAdminPermission,)
pagination_class = StandardSetPagination
filter_backends = [DjangoFilterBackend]
filterset_fields = [
"fzg_segment__title",
"parts_group__title",
"car_brand__title",
"usage_recommendation",
"recommended_action",
]
def get_queryset(self) -> models.Product:
"""Returns queryset of all the products of a workspace"""
workspace = self.kwargs["workspace"]
workspace = get_object_or_404(models.Workspace, pk=workspace)
return workspace.products.all()
誰能幫助我,讓我知道我需要做什么才能實現所需的功能?
更新:我創建了filters.py
文件如下:
# filters.py
import django_filters
from .models import Product
class ProductFilter(django_filters.FilterSet):
fzg_segment__title = django_filters.CharFilter(field_name="fzg_segment__title", lookup_expr='in')
parts_group__title = django_filters.CharFilter(field_name="parts_group__title", lookup_expr='in')
car_brand__title = django_filters.CharFilter(field_name="car_brand__title", lookup_expr='in')
part__title = django_filters.CharFilter(field_name="part__title", lookup_expr='in')
country__title = django_filters.CharFilter(field_name="country__title", lookup_expr='in')
manufacturer__title = django_filters.CharFilter(field_name="manufacturer__title", lookup_expr='in')
class Meta:
model = Product
fields = [
"fzg_segment__title",
"parts_group__title",
"car_brand__title",
"part__title",
"country__title",
"manufacturer__title",
]
並且我更新了我的views.py
如下:
# views.py
class ProductsSummaryView(mixins.ListModelMixin, viewsets.GenericViewSet):
"""Viewset to return data for products in a workspace"""
serializer_class = serializers.ProductSerializer
permission_classes = (permissions.IsWorkspaceAdminPermission,)
pagination_class = StandardSetPagination
filter_backends = [DjangoFilterBackend]
filterset_class = filters.ProductFilter
def get_queryset(self) -> models.Product:
"""Returns queryset of all the products of a workspace"""
workspace = self.kwargs["workspace"]
workspace = get_object_or_404(models.Workspace, pk=workspace)
queryset = workspace.products.all()
queryset = self.filter_queryset(queryset)
return queryset
我嘗試在 URL 中使用如下過濾器:
{{domain]]/path/?country__title=Japan&country__title=Korea
和
`{{domain]]/path/?country__title__in=Japan&country__title__in=Korea``
和
{{domain]]/path/?country__title__in=Japan,Korea
和
{{domain]]/path/?country__title[]=Japan&country__title[]=Korea
但一切都是徒勞的,我什至無法使用單個過濾器,留下多個過濾器。 我做錯了什么?
要根據 Django Rest Framework (DRF) 中特定字段的多個值過濾查詢集,您可以在過濾器集中使用 in 查找類型。 要使用此查找類型,您需要更新您的過濾器集字段以包含 in 查找,如下所示:
class ProductFilter(filters.FilterSet):
country__title = filters.CharFilter(field_name='country__title', lookup_expr='in')
class Meta:
model = Product
fields = ['country__title']
使用此過濾器集,您可以在 URL 查詢參數中使用 in 查找類型,以根據多個值過濾查詢集。 例如,要過濾標題為“日本”和“韓國”的產品的查詢集,您可以使用以下 URL:
{{domain}}/path/?country__title__in=Japan,Korea
或者,您也可以在過濾器集中使用 Django-filter 提供的 MultipleChoiceFilter 以允許對特定字段的多個值進行過濾。
class ProductFilter(filters.FilterSet):
country__title = filters.MultipleChoiceFilter(field_name='country__title')
class Meta:
model = Product
fields = ['country__title']
有了這個過濾器集,您就可以使用以下 URL 來過濾帶有標題為“日本”和“韓國”的國家/地區的產品的查詢集:
{{domain}}/path/?country__title=Japan&country__title=Korea
您需要使用BaseInFilter ,例如:
from django_filters.filters import BaseInFilter
from django_filters import rest_framework as filters
class CharInFilter(BaseInFilter, filters.CharFilter):
pass
class ProductFilterSet(filters.FilterSet):
country = filters.CharInFilter(field_name="country__title", lookup_expr='in')
參數 url 如: /?country=Japan,Korea
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.