DJango 休息框架 - API 使用来自相关模型的过滤器字段的列表
DJango rest framework - API list using filter field from related models
您好,我是 Django 和 Django rest 框架的新手,所以我的术语可能不适用。
我正在尝试构建一个 API 返回一个模型中的项目列表,但根据另一个相关模型中的字段进行过滤。
我将提供我当前的视图和序列化程序 类 以及模型
class service(models.Model):
name = models.CharField(max_length=50)
vendor = models.CharField(max_length=50)
version = models.CharField(max_length=10)
registration_status = models.BooleanField(default=False)
class service_network(models.Model):
service = models.OneToOneField(
service,
related_name='network',
on_delete=models.CASCADE,
primary_key=True,
)
forwarded_port = models.CharField(max_length=50)
class ServiceNetworkSerializer(serializers.ModelSerializer):
class Meta:
model = service_network
fields = '__all__'
class ServiceSerializer(serializers.ModelSerializer):
network = ServiceNetworkSerializer()
class Meta:
model = service
fields = [
'id',
'name',
'vendor',
'version',
'registration_status',
'network',
]
class ServiceAPI(ModelViewSet):
queryset = service.objects.all()
serializer_class = ServiceSerializer
filterset_fields = '__all__'
目前我可以使用 URL 查询字符串
获取返回列表
{{baseUrl}}/engine/service?registration_status=true
我想做的是这样的
{{baseUrl}}/engine/service/network?forwarded_port=8080
我希望返回相关网络字段“forwarded_port”等于 8080 的服务列表。
还有其他方法可以查询这个API吗?也许使用 POST 和包含查询的正文?如果 DOCS 中有我可以阅读的内容,我会尝试查看过滤和查询集,但我无法找到任何可以开箱即用的东西
我也是 Whosebug 的新手,我试图用尽可能多的相关信息来使我的问题简短,所以如果有任何遗漏,我很乐意编辑我的问题
试试这个:
{{baseUrl}}/engine/service?network__forwarded_port=8080
可能有用。
文档:https://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships-1
编辑:
如果上面的回答不行,你可以修改ServiceApi class 自己过滤:
class ServiceAPI(ModelViewSet):
def get_queryset(self):
if self.request.GET.get(network__forwarded_port)
return service.objects.filter(network__forwarded_port = self.request.GET.get(network__forwarded_port))
else:
return service.objects.all()
serializer_class = ServiceSerializer
filterset_fields = '__all__'
我能够使用以下查询集覆盖解决这个问题
def get_queryset(self):
if len(self.request.GET) > 0:
query_set = {}
for query in self.request.GET:
query_set[query] = self.request.GET.get(query)
return service.objects.filter(**query_set)
else:
return service.objects.all()
这样做是为了让您过滤字段而无需明确指定它们是什么,以防您有许多需要过滤的字段。我还必须说,因为我没有使用 Django 的经验,所以我不确定这可能会带来什么样的错误,但它是一种对我有用的 hack。如果我发现这真的很糟糕,我会回来删除它。
您好,我是 Django 和 Django rest 框架的新手,所以我的术语可能不适用。
我正在尝试构建一个 API 返回一个模型中的项目列表,但根据另一个相关模型中的字段进行过滤。
我将提供我当前的视图和序列化程序 类 以及模型
class service(models.Model):
name = models.CharField(max_length=50)
vendor = models.CharField(max_length=50)
version = models.CharField(max_length=10)
registration_status = models.BooleanField(default=False)
class service_network(models.Model):
service = models.OneToOneField(
service,
related_name='network',
on_delete=models.CASCADE,
primary_key=True,
)
forwarded_port = models.CharField(max_length=50)
class ServiceNetworkSerializer(serializers.ModelSerializer):
class Meta:
model = service_network
fields = '__all__'
class ServiceSerializer(serializers.ModelSerializer):
network = ServiceNetworkSerializer()
class Meta:
model = service
fields = [
'id',
'name',
'vendor',
'version',
'registration_status',
'network',
]
class ServiceAPI(ModelViewSet):
queryset = service.objects.all()
serializer_class = ServiceSerializer
filterset_fields = '__all__'
目前我可以使用 URL 查询字符串
获取返回列表{{baseUrl}}/engine/service?registration_status=true
我想做的是这样的
{{baseUrl}}/engine/service/network?forwarded_port=8080
我希望返回相关网络字段“forwarded_port”等于 8080 的服务列表。
还有其他方法可以查询这个API吗?也许使用 POST 和包含查询的正文?如果 DOCS 中有我可以阅读的内容,我会尝试查看过滤和查询集,但我无法找到任何可以开箱即用的东西
我也是 Whosebug 的新手,我试图用尽可能多的相关信息来使我的问题简短,所以如果有任何遗漏,我很乐意编辑我的问题
试试这个:
{{baseUrl}}/engine/service?network__forwarded_port=8080
可能有用。
文档:https://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships-1
编辑:
如果上面的回答不行,你可以修改ServiceApi class 自己过滤:
class ServiceAPI(ModelViewSet):
def get_queryset(self):
if self.request.GET.get(network__forwarded_port)
return service.objects.filter(network__forwarded_port = self.request.GET.get(network__forwarded_port))
else:
return service.objects.all()
serializer_class = ServiceSerializer
filterset_fields = '__all__'
我能够使用以下查询集覆盖解决这个问题
def get_queryset(self):
if len(self.request.GET) > 0:
query_set = {}
for query in self.request.GET:
query_set[query] = self.request.GET.get(query)
return service.objects.filter(**query_set)
else:
return service.objects.all()
这样做是为了让您过滤字段而无需明确指定它们是什么,以防您有许多需要过滤的字段。我还必须说,因为我没有使用 Django 的经验,所以我不确定这可能会带来什么样的错误,但它是一种对我有用的 hack。如果我发现这真的很糟糕,我会回来删除它。