【发布时间】:2020-01-03 15:27:59
【问题描述】:
我正在尝试过滤搜索其余 api 页面并希望使用方法字段作为搜索字段之一,但是当我这样做时,我收到一条错误消息,指出该字段无效,然后它会在我的模型中列出该字段作为唯一有效的来源
序列化器:
class SubnetDetailsSerializer(QueryFieldsMixin, serializers.HyperlinkedModelSerializer):
subnet = serializers.SerializerMethodField()
device = serializers.ReadOnlyField(
source='device.hostname',
)
circuit_name = serializers.ReadOnlyField(
source='circuit.name',
)
subnet_name = serializers.ReadOnlyField(
source='subnet.description',
)
safe_subnet = serializers.SerializerMethodField()
def get_safe_subnet(self, obj):
return '{}{}'.format(obj.subnet.subnet, obj.subnet.mask.replace('/','_'))
def get_subnet(self, obj):
return '{}{}'.format(obj.subnet.subnet, obj.subnet.mask)
class Meta:
model = DeviceCircuitSubnets
fields = ('id','device_id','subnet_id','circuit_id','subnet','safe_subnet','subnet_name','device','circuit_name')
观看次数:
class SubnetDetailsSet(viewsets.ReadOnlyModelViewSet):
queryset = DeviceCircuitSubnets.objects.all().select_related('circuit','subnet','device')
serializer_class = SubnetDetailsSerializer
permission_classes = (IsAdminUser,)
filter_class = DeviceCircuitSubnets
filter_backends = (filters.SearchFilter,)
search_fields = (
'device__hostname',
'circuit__name',
'subnet__subnet',
'safe_subnet'
)
如何在搜索字段中包含 safe_subnet?
谢谢
编辑 这是现在的代码
views.py
class SubnetDetailsSet(viewsets.ReadOnlyModelViewSet):
queryset = DeviceCircuitSubnets.objects.all()
serializer_class = SubnetDetailsSerializer
permission_classes = (IsAdminUser,)
filter_class = DeviceCircuitSubnets
filter_backends = (filters.SearchFilter,)
search_fields = (
'device__hostname',
'circuit__name',
'subnet__subnet',
'safe_subnet'
)
def get_queryset(self):
return (
super().get_queryset()
.select_related('circuit','subnet','device')
.annotate(
safe_subnet=Concat(
F('subnet__subnet'),
Replace(F('subnet__mask'), V('/'), V('_')),
output_field=CharField()
)
)
)
serializer.py
class SubnetDetailsSerializer(QueryFieldsMixin, serializers.HyperlinkedModelSerializer):
subnet = serializers.SerializerMethodField()
device = serializers.ReadOnlyField(
source='device.hostname',
)
circuit_name = serializers.ReadOnlyField(
source='circuit.name',
)
subnet_name = serializers.ReadOnlyField(
source='subnet.description',
)
def get_safe_subnet(self, obj):
return getattr(obj, 'safe_subnet', None)
def get_subnet(self, obj):
return '{}{}'.format(obj.subnet.subnet, obj.subnet.mask)
class Meta:
model = DeviceCircuitSubnets
fields = ('id','device_id','subnet_id','circuit_id','subnet','safe_subnet','subnet_name','device','circuit_name')
型号:
class DeviceCircuitSubnets(models.Model):
device = models.ForeignKey(Device, on_delete=models.CASCADE)
circuit = models.ForeignKey(Circuit, on_delete=models.CASCADE, blank=True, null=True)
subnet = models.ForeignKey(Subnet, on_delete=models.CASCADE)
active_link = models.BooleanField(default=False, verbose_name="Active Link?")
active_link_timestamp = models.DateTimeField(auto_now=True, blank=True, null=True)
错误:
Exception Type: ImproperlyConfigured at /api/subnets/
Exception Value: Field name `safe_subnet` is not valid for model `DeviceCircuitSubnets`.
【问题讨论】:
-
使用查询执行搜索,您不能在方法字段上进行搜索。
-
你能把模型和错误也贴出来吗?
-
对此有什么想法吗?谢谢
-
您需要对所有这些都使用 ?search=,还是可以使用支持
?subnet=192.168/24&device=django&circut=31样式查询的自定义过滤器?在这种情况下,后者更可取。
标签: django django-rest-framework django-rest-viewsets