bounty将在2小时后过期。回答此问题可获得+50的声望奖励。Karthik正在寻找可靠来源的答案。
问题-1
- 即使我们没有在请求查询中传递任何
tag
,也会执行datasetfiletagsquery
函数
问题-2
- 如果我按要求设置了
dataset_id
,那么它也会在retrieve
和其他action
API函数中强制执行。
上下文
- 只有在请求中传递
tag
查询时,我才需要将dataset_id
设置为所需查询
代码
class DatasetFileViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
class DatasetFileFilter(filters.FilterSet):
def datasetfiletagsquery(request):
try:
dataset_id = request.query_params['dataset_id']
qs = Tag.objects.filter(object_id=dataset_id, content_type=ContentType.objects.get_for_model(Dataset),
category=Tag.CategoryChoices.DATASET_FILE)
except KeyError:
raise serializers.ValidationError({'dataset_id': 'This query is required'})
return qs
def datasetfiletagsfilter(queryset, name, value):
tag_ids = [tag.pk for tag in value]
qs = queryset.filter_by_tags(tag_ids)
return qs
dataset_id = filters.NumberFilter()
tag = filters.ModelMultipleChoiceFilter(queryset=datasetfiletagsquery, to_field_name='name', method=datasetfiletagsfilter)
class Meta:
model = DatasetFile
fields = ['dataset_id', 'tag']
queryset = DatasetFile.objects.prefetch_related('tags', 'related_child_dataset_files__child').select_related('datasetbatchfile').extend_order_by()
serializer_class = DatasetFileSerializer
filterset_class = DatasetFileFilter
def get_queryset(self):
if self.action == 'download':
qs = DatasetFile.objects.all()
else:
qs = super().get_queryset()
qs = qs.filter(dataset__organization_id=self.request.user.organization_id)
return qs
@action(methods=['POST'], detail=True, url_path='download', serializer_class=DatasetFileDownloadSerializer)
def download(self, request, pk):
"""
api for downloading dataset file
"""
instance = self.get_object()
instance = instance.dataset.get_datasetfiles_for_download(datasetfile_ids=[instance.pk])[0]
serializer = self.get_serializer(instance)
return Response(serializer.data, status=status.HTTP_200_OK)
字符串
问题1的预期执行
- 如果请求中不存在
tag
查询,则不应执行datasetfiletagsquery
函数
问题2的预期执行
- 筛选器的
required
字段必须仅对list
API强制执行。
3条答案
按热度按时间eeq64g8w1#
执行
datasetfiletagsquery
以获取所有可能的值,以便按标签进行过滤。它在两种情况下执行:1.如果提供了标记,则检查它是否是允许的标记(这是您所期望的)。
1.如果没有提供标签,用户可以使用OPTIONS http方法请求获得过滤器允许的选项。这对于REST API在网页上显示过滤器中的可能值也很有用。
所以不可能不执行它,DRF在其代码中强制执行它。这里唯一的可能性是从filter字段中删除
queryset= datasetfiletagsquery
属性,并在过滤时手动验证该标记是否允许。第二个问题可能也无法直接解决,除非您将其设置为DRF不需要的,并在过滤过程中手动验证它。这也会导致端点的错误模式(它不会指示列表方法中需要这些字段)。如果这对您来说是一个问题,您可以将模式覆盖到您自己手动创建的模式。
此外,在stackoverflow上有一个规则,每个问题只需要解决一个问题。
rryofs0p2#
要解决问题1,请修改DatasetFileViewSet中的datasetfiletagquery,以便在请求中不存在“tag”参数时返回空或默认的queryset。对于问题2,仅当存在标记查询时,在同一视图集中重写get_filterset_kwargs,以便根据需要动态设置dataset_id,允许您根据请求的上下文选择性地强制执行此条件。此解决方案确保了高效和上下文-Django应用程序中的敏感过滤。
你可以尝试修改代码:
字符串
gg58donl3#
字符串
您需要将占位符(如
yourapp.models
和DatasetFileSerializer
)替换为项目中使用的实际模块和类名。extend_order_by()
方法和其他自定义方法或属性也应该根据应用程序的逻辑定义或替换。