我的问题是 django-filter 库无法与 django Rest 框架中的选择字段一起正常工作:
模型.py
class Incident(models.Model):
caller = models.ForeignKey(
'core.Caller',
verbose_name='caller',
on_delete=models.PROTECT,
related_name='incidents',
blank=True,
null=True,
)
declarant = models.ForeignKey(
'core.Declarant',
verbose_name='declarant',
on_delete=models.CASCADE,
related_name='incidents',
blank=True,
null=True,
)
kind = models.ForeignKey(
IncidentKind,
verbose_name='kind',
on_delete=models.SET_NULL,
related_name='incidents',
blank=True,
null=True,
)
duplicate_of = models.ForeignKey(
'self',
verbose_name='duplicate',
on_delete=models.CASCADE,
related_name='duplicates',
blank=True,
null=True,
)
source = models.CharField(
'source',
max_length=255,
default=consts.IncidentSource.APP,
choices=consts.IncidentSource.CHOICES,
)
status = models.CharField(
'status',
max_length=255,
choices=consts.IncidentStatus.CHOICES,
default=consts.IncidentStatus.REQUEST_112,
)
过滤器
class Incident(django_filters.FilterSet):
description = django_filters.CharFilter(lookup_expr='icontains')
declarant_phone = django_filters.CharFilter(field_name='declarant__phone', lookup_expr='icontains')
incident_address = django_filters.CharFilter(field_name='address__full_address', lookup_expr='icontains')
source = django_filters.ChoiceFilter(choices=consts.IncidentSource.CHOICES, lookup_expr='icontains')
status = django_filters.ChoiceFilter(choices=consts.IncidentStatus.CHOICES, lookup_expr='icontains')
service = django_filters.Filter(method='filter_service')
address_caller = django_filters.CharFilter(field_name='caller__address', lookup_expr='icontains')
victims = django_filters.BooleanFilter(method='filter_victims')
death = django_filters.BooleanFilter(method='filter_death')
dt_create = django_filters.Filter(method='filter_dt_create')
incident_moment = django_filters.Filter(method='filter_incident_moment')
class Meta:
model = models.Incident
fields = [
'is_needs_reaction',
'is_social_significant',
'is_risk_emergency',
'description',
'declarant_phone',
'status',
'source',
'operator',
'incident_address',
'kind',
'service',
'address_caller',
'victims',
'death',
'dt_create',
]
来源和状态选择字段。
我遇到了错误
super()._set_choices(value)
AttributeError: 'super' object has no attribute '_set_choices'
如果我使用 CharFilter,那么过滤会起作用,但不完全符合预期
source = django_filters.CharFilter(choices=consts.IncidentSource.CHOICES, lookup_expr='icontains')
status = django_filters.CharFilter(choices=consts.IncidentStatus.CHOICES, lookup_expr='icontains')
我的回溯:
Traceback (most recent call last):
File "/core/tests/test_incident.py", line 60, in test_update
response = self.client.put(self.detail_url)
File "/venv/lib/python3.10/site-packages/rest_framework/test.py", line 304, in put
response = super().put(
File "/venv/lib/python3.10/site-packages/rest_framework/test.py", line 214, in put
return self.generic('PUT', path, data, content_type, **extra)
File "/venv/lib/python3.10/site-packages/rest_framework/test.py", line 234, in generic
return super().generic(
File "/venv/lib/python3.10/site-packages/django/test/client.py", line 617, in generic
return self.request(**r)
File "/venv/lib/python3.10/site-packages/rest_framework/test.py", line 286, in request
return super().request(**kwargs)
File "/venv/lib/python3.10/site-packages/rest_framework/test.py", line 238, in request
request = super().request(**kwargs)
File "/venv/lib/python3.10/site-packages/django/test/client.py", line 1013, in request
self.check_exception(response)
File "/venv/lib/python3.10/site-packages/django/test/client.py", line 743, in check_exception
raise exc_value
File "/venv/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/venv/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/venv/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
return view_func(request, *args, **kwargs)
File "/venv/lib/python3.10/site-packages/rest_framework/viewsets.py", line 124, in view
return self.dispatch(request, *args, **kwargs)
File "/venv/lib/python3.10/site-packages/rest_framework/views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "/venv/lib/python3.10/site-packages/rest_framework/views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "/venv/lib/python3.10/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
raise exc
File "/venv/lib/python3.10/site-packages/rest_framework/views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "/venv/lib/python3.10/site-packages/rest_framework/mixins.py", line 65, in update
instance = self.get_object()
File "/venv/lib/python3.10/site-packages/rest_framework/generics.py", line 87, in get_object
queryset = self.filter_queryset(self.get_queryset())
File "/venv/lib/python3.10/site-packages/rest_framework/generics.py", line 154, in filter_queryset
queryset = backend().filter_queryset(self.request, queryset, self)
File "/venv/lib/python3.10/site-packages/django_filters/rest_framework/backends.py", line 94, in filter_queryset
if not filterset.is_valid() and self.raise_exception:
File "/lib/python3.10/site-packages/django_filters/filterset.py", line 212, in is_valid
return self.is_bound and self.form.is_valid()
File "/venv/lib/python3.10/site-packages/django_filters/rest_framework/filterset.py", line 24, in form
form = super().form
File "/venv/lib/python3.10/site-packages/django_filters/filterset.py", line 264, in form
Form = self.get_form_class()
File "/venv/lib/python3.10/site-packages/django_filters/filterset.py", line 254, in get_form_class
fields = OrderedDict([
File "/venv/lib/python3.10/site-packages/django_filters/filterset.py", line 255, in <listcomp>
(name, filter_.field)
File "/venv/lib/python3.10/site-packages/django_filters/filters.py", line 137, in field
self._field = self.field_class(label=self.label, **field_kwargs)
File "/venv/lib/python3.10/site-packages/django_filters/fields.py", line 281, in __init__
super().__init__(*args, **kwargs)
File "/venv/lib/python3.10/site-packages/django_filters/fields.py", line 262, in __init__
super().__init__(*args, **kwargs)
File "/venv/lib/python3.10/site-packages/django/forms/fields.py", line 880, in __init__
self.choices = choices
File "/venv/lib/python3.10/site-packages/django_filters/fields.py", line 268, in _set_choices
我也只是尝试将源和状态字段传递到字段字段,它也没有帮助。 他问了GPT问题,他说其中一个可能的问题可能是库本身的bug,所以他决定在这里问另一个问题,以防有人有类似的情况
使用选择字段时删除
lookup_expr
。默认情况下,它使用精确的查找表达式,因为它是一个选择字段。
我的 Django 应用程序中的工作过滤器示例如下所示:
DOMAIN_CHOICES = (
('Educations', 'Educations'),
('Certificates', 'Certificates'),
('Qualifications', 'Qualifications'),
)
class HistoryFilter(filters.FilterSet):
domain = filters.ChoiceFilter(choices=DOMAIN_CHOICES, required=True)
class Meta:
model = EmployeeHistory
fields = ['domain']