[英]Use serializer validated data in get_queryset()
I want to write custom get_queryset() method for serializer based on query params. 我想基于查询参数为序列化程序编写自定义get_queryset()方法。
Here is my serializer: 这是我的序列化器:
class SearchRequestSerializer(serializers.Serializer):
name = serializers.CharField(max_length=255, required=False)
nickname = serializers.RegexField(
r'^(?!(.*?\_){2})(?!(.*?\.){2})[A-Za-z0-9\._]{3,24}$',
max_length=24,
min_length=3,
required=False,
)
modelA_id = serializers.CharField(max_length=11, min_length=11,
required=False)
def validate_modelA_id(self, value):
queryset = modelA.objects.filter(id=value)
if queryset.exists():
return queryset.first()
else:
raise serializers.ValidationError(_('Not found'))
If object of modelA exists - validation will return an instance. 如果modelA的对象存在 - 验证将返回一个实例。 But I don't want to perform the same query in get_queryset() in my if branch.
但我不想在我的if分支中的get_queryset()中执行相同的查询。
def get_queryset(self):
name = self.request.query_params.get('name', None)
nickname = self.request.query_params.get('nickname', None)
queryset = User.objects.filter(Q(name__contains=name)|Q(nickname__contains=nickname))
if 'modelA_id' in self.request.query_params:
# in this case will be annotated extra field to queryset
# extra field will be based on 'modelA' instance which should be returned by serializer
return queryset
I found only one solution - add the following line in my GET method: 我发现只有一个解决方案 - 在我的GET方法中添加以下行:
self.serializer = self.get_serializer()
Than it will be possible to get validated values in my get_queryset() method. 可以在我的get_queryset()方法中获取经过验证的值。 But PyCharm don't like this solution
但PyCharm不喜欢这个解决方案
I'm under strong impression that you are misusing the Serializer. 我强烈反对您滥用序列化程序。 After quick analysis of your issue i think you need DRF filtering
在快速分析您的问题后,我认为您需要DRF过滤
Serializers process request.data
which under the hood is just Django request.POST
and request.FILES
yet in your get_queryset
implementation you make lookups in request.query_params
which in Django terms is request.GET
. 序列化程序处理
request.data
,它只是Django request.POST
和request.FILES
在你的get_queryset
实现中你在request.query_params
中进行查找,在Django术语中是request.GET
。 Check the DRF docs on this. 检查DRF文档。
In order to achieve what you need with Serializers you would have to abuse the Views, Serializer Fields and Serializer itself. 为了通过Serializers实现您所需的功能,您必须滥用Views,Serializer Fields和Serializer本身。 It is simply not what its supposed to do.
根本不是它应该做的事情。 Additionaly I don't think that you need so much validation on search.
另外我认为你不需要在搜索上进行如此多的验证。
Customization and use of Django Filter should solve your problem. 定制和使用Django Filter应该可以解决您的问题。
class UserFilter(filters.FilterSet):
class Meta:
model = User
fields = ['name', 'nickname', 'modelA_id']
def filter_queryset(self, queryset):
name = self.form.cleaned_data.get('name', None)
nickname = self.form.cleaned_data.get('nickname', None)
queryset = queryset.filter(Q(name__contains=name)|Q(nickname__contains=nickname))
if 'modelA_id' in self.form.cleaned_data:
# in this case will be annotated extra field to queryset
# extra field will be based on 'modelA' instance which should be returned by serializer
return queryset
class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
filterset_class = UserFilter
NOTE I did not test code above but it should show you how to tackle this problem.
注意我没有测试上面的代码,但它应该告诉你如何解决这个问题。
How is about user = get_object_or_404(queryset, id=ModelA_id)
. 如何关于
user = get_object_or_404(queryset, id=ModelA_id)
。 It looks better as for me. 它对我来说看起来更好。
get_object_or_404
will catch an object you need, or will raise Not Found
responce. get_object_or_404
将捕获您需要的对象,或者将引发Not Found
响应。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.