【问题标题】:Meta.filter_overrides for IntegerRangeField in django filter viewdjango 过滤器视图中 IntegerRangeField 的 Meta.filter_overrides
【发布时间】:2018-10-05 11:34:31
【问题描述】:

使用 Django 文档中的示例,使用带有 Postgres 后端的 IntergerRangeField 创建具有以下模型的“年龄”范围:

from django.contrib.postgres.fields import IntegerRangeField
from psycopg2.extras import NumericRange

from django.db import models

class Event(models.Model):
    name = models.CharField(max_length=200)
    ages = IntegerRangeField()

    def __str__(self):  
        return self.name

然而,当使用 Django Rest Frameworks 并使用带有以下过滤器的过滤器视图时,这非常有效:

import django_filters
from django_filters import rest_framework as filters
from app import Event

class EventFilter(django_filters.FilterSet):
ages = django_filters.NumericRangeFilter(queryset=Event.objects.all())
class Meta:
    model = Event
    fields = ['name','ages']

视图在 /api/event_filter/ 处生成 AssertionError,并建议向 Meta.filters_override 添加覆盖。 我真正欣赏的是基于此覆盖的示例模型的示例,django-filters 文档http://django-filter.readthedocs.io/en/latest/ref/filterset.html#filter-overrides 中的示例,并没有帮助我理解如何渲染它。我将不胜感激任何帮助,以便我可以通过这个示例理解以在将来使用它。

【问题讨论】:

  • 请跟踪堆栈?
  • AssertionError: AutoFilterSet 使用“精确”查找将字段“年龄”解析为无法识别的字段类型 IntegerRangeField。尝试向“Meta.filter_overrides”添加覆盖。见:django-filter.readthedocs.io/en/develop/ref/…
  • 或在浏览器视图中:
  • 你访问的网址是什么?
  • 当前 url 是 localhost

标签: django django-rest-framework django-filter


【解决方案1】:

根据文档,覆盖自定义选项似乎是在 Meta 类中完成的,而不是您所做的方式。 ages = django_filters.NumericRangeFilter(queryset=Event.objects.all())

这里有几个潜在的问题:

  1. 声明本身似乎不受支持
  2. Meta 类中似乎支持覆盖
  3. queryset 不是 NumericRangeFilter AFAIk 的有效选项

您可以尝试以下方法吗:

from django.contrib.postgres.fields import IntegerRangeField

class EventFilter(django_filters.FilterSet):
    class Meta:
        model = Event
        fields = ['name','ages']
        filter_overrides = {
             IntegerRangeField: {
                 'filter_class': django_filters.NumericRangeFilter,
             }
        }  

【讨论】:

  • 很抱歉,这并没有解决问题我收到相同的错误 AutoFilterSet 将字段“ages”解析为“精确”查找到无法识别的字段类型 IntegerRangeField。尝试向“Meta.filter_overrides”添加覆盖。请参阅:django-filter.readthedocs.io/en/develop/ref/… 只是为了检查年龄数据在 api 视图上的样子:"ages": "{\"bounds\": \"[)\", \"lower\": \"19 \", \"上\": \"38\"}"
  • 您是否尝试过简单地删除所有覆盖并让 DjangoFilter 默认使用任何过滤器?
  • 我尝试了我建议的代码,它非常适合我;我设置了一个测试 Django 项目并对其进行了验证。你可以在这里克隆它并自己检查:github.com/rtindru/interger_range_filter
  • 我已经克隆并安装了你的程序,我是否错过了浏览器中对这些 url 的视图:^admin/ ^events/$ [name='event-list'] ^events\。 (?P[a-z0-9]+)/?$ [name='event-list'] ^events/(?P[^/.]+)/$ [name='event -detail'] ^events/(?P[^/.]+)\.(?P[a-z0-9]+)/?$ [name='event-detail'] ^ $ [name='api-root'] ^\.(?P[a-z0-9]+)/?$ [name='api-root'] 但存在一个问题,因为没有创建模板渲染诸如 events/ 的视图正在寻找 rest_framework/horizo​​ntal/form.html 我已经创建了一个模板目录,稍后会查看它。
  • runserver 起作用的事实是因为上面提到的代码更改。如果您从代码中删除 filter_override ,runserver 会因您遇到的相同错误而中断。试试看
【解决方案2】:

从事类似的工作。

from django.contrib.postgres.fields import ArrayField
import django_filters

class SkillFilter(django_filters.Filters):
    class Meta:
        model = Skill
        filter_overrides = {
            ArrayField: {
                'filter_class': django_filters.CharFilter,
                'extra': lambda f: {
                    'lookup_expr': 'icontains',
                },
            },
        }


class SkillType(DjangoObjectType):
    class Meta:
        model = Skill
        filterset_class = SkillFilter
        interfaces = (relay.Node, )

然后是我的模型

from django.contrib.postgres.fields import ArrayField
from django.db import models


class Skill(models.Model):
    name = models.CharField(max_length=50)
    skills = ArrayField(models.CharField(max_length=200), blank=True)

这样做可以解决问题,希望您可以利用它来获得解决方案

注意:我认为 django_filters 不支持数组过滤器,这就是我使用 CharFilter 的原因,这对我有用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    • 2018-09-02
    • 2017-11-27
    • 2019-03-18
    • 2023-01-15
    • 2021-09-18
    • 1970-01-01
    相关资源
    最近更新 更多