将 类 与 django-filters 相关联
Associate classes with django-filters
您好,我有一个关于 django-filters 的问题。我的问题是:
我的 models.py 中定义了两个 classes,它们是:
class Volcano(models.Model):
vd_id = models.AutoField("ID, Volcano Identifier (Index)",
primary_key=True)
[...]
class VolcanoInformation(models.Model):
# Primary key
vd_inf_id = models.AutoField("ID, volcano information identifier (index)",
primary_key=True)
# Other attributes
vd_inf_numcal = models.IntegerField("Number of calderas")
[...]
# Foreign key(s)
vd_id = models.ForeignKey(Volcano, null=True, related_name='vd_inf_vd_id',
on_delete=models.CASCADE)
他们两个是 link 通过 vd_id 属性编辑的。
我想开发一个搜索工具,允许用户按火山口数量 (vd_inf_numcal) 搜索火山。
我正在使用 django-filters,现在这是我的 filters.py:
from .models import *
import django_filters
class VolcanoFilter(django_filters.FilterSet):
vd_name = django_filters.ModelChoiceFilter(
queryset=Volcano.objects.values_list('vd_name', flat=True),
widget=forms.Select, label='Volcano name',
to_field_name='vd_name',
)
vd_inf_numcal = django_filters.ModelChoiceFilter(
queryset=VolcanoInformation.objects.values_list('vd_inf_numcal', flat=True),
widget=forms.Select, label='Number of calderas',
)
class Meta:
model = Volcano
fields = ['vd_name', 'vd_inf_numcal']
我的views.py是:
def search(request):
feature_list = Volcano.objects.all()
feature_filter = VolcanoFilter(request.GET, queryset = feature_list)
return render(request, 'app/search_list.html', {'filter' : feature_filter, 'feature_type': feature_type})
在我的应用程序中,出现了可能的火山口数量的下拉列表,但搜索 returns 没有结果,这是正常的,因为 VolcanoInformation.vd_inf_numcal、VolcanoInformation.vd_id 和Volcano.vd_id.
它甚至说 "Select a valid choice. That choice is not one of the available choices."
我的问题是如何使用 django_filters 制作此 link?
我想我应该在 class 中写一些方法,但我完全不知道该怎么做。
如果有人知道答案,我将不胜感激!
一般来说,您需要回答两个问题:
- 我们要查询什么字段以及需要生成什么 query/lookup 表达式。
- 我们应该过滤什么样的值。
这些答案基本上是您 .filter()
电话的左侧和右侧。
在这种情况下,您要过滤火山-火山信息关系 (vd_inf_vd_id
) 的反面,针对火山的破火山口数量 (vd_inf_numcal
)。此外,您需要 exact
匹配。
对于值,您需要一组包含整数的选项。
AllValuesFilter
将查看数据库列并根据列值生成选择。然而,缺点是选择不会包含任何缺失值,这在呈现时看起来很奇怪。您可以调整此字段,或使用普通 ChoiceFilter
,自行生成值。
def num_calderas_choices():
# Get the maximum number of calderas
max_count = VolcanoInformation.objects.aggregate(result=Max('vd_inf_numcal'))['result']
# Generate a list of two-tuples for the select dropdown, from 0 to max_count
# e.g, [(0, 0), (1, 1), (2, 2), ...]
return zip(range(max_count), range(max_count))
class VolcanoFilter(django_filters.FilterSet):
name = ...
num_calderas = django_filters.ChoiceFilter(
# related field traversal (note the connecting '__')
field_name='vd_inf_vd_id__vd_inf_numcal',
label='Number of calderas',
choices=num_calderas_choices
)
class Meta:
model = Volcano
fields = ['name', 'num_calderas']
请注意,我还没有亲自测试上面的代码,但它应该足够接近让你开始。
非常感谢!这正是我要找的!我不明白 .filter()
是如何工作的。
我对其他属性所做的是生成选择,但方式不同。例如,如果我只想显示可用位置的列表,我会使用:
# Location attribute
loc = VolcanoInformation.objects.values_list('vd_inf_loc', flat=True)
vd_inf_loc = django_filters.ChoiceFilter(
field_name='vd_inf_vd_id__vd_inf_loc',
label='Geographic location',
choices=zip(loc, loc),
)
您好,我有一个关于 django-filters 的问题。我的问题是: 我的 models.py 中定义了两个 classes,它们是:
class Volcano(models.Model):
vd_id = models.AutoField("ID, Volcano Identifier (Index)",
primary_key=True)
[...]
class VolcanoInformation(models.Model):
# Primary key
vd_inf_id = models.AutoField("ID, volcano information identifier (index)",
primary_key=True)
# Other attributes
vd_inf_numcal = models.IntegerField("Number of calderas")
[...]
# Foreign key(s)
vd_id = models.ForeignKey(Volcano, null=True, related_name='vd_inf_vd_id',
on_delete=models.CASCADE)
他们两个是 link 通过 vd_id 属性编辑的。
我想开发一个搜索工具,允许用户按火山口数量 (vd_inf_numcal) 搜索火山。
我正在使用 django-filters,现在这是我的 filters.py:
from .models import *
import django_filters
class VolcanoFilter(django_filters.FilterSet):
vd_name = django_filters.ModelChoiceFilter(
queryset=Volcano.objects.values_list('vd_name', flat=True),
widget=forms.Select, label='Volcano name',
to_field_name='vd_name',
)
vd_inf_numcal = django_filters.ModelChoiceFilter(
queryset=VolcanoInformation.objects.values_list('vd_inf_numcal', flat=True),
widget=forms.Select, label='Number of calderas',
)
class Meta:
model = Volcano
fields = ['vd_name', 'vd_inf_numcal']
我的views.py是:
def search(request):
feature_list = Volcano.objects.all()
feature_filter = VolcanoFilter(request.GET, queryset = feature_list)
return render(request, 'app/search_list.html', {'filter' : feature_filter, 'feature_type': feature_type})
在我的应用程序中,出现了可能的火山口数量的下拉列表,但搜索 returns 没有结果,这是正常的,因为 VolcanoInformation.vd_inf_numcal、VolcanoInformation.vd_id 和Volcano.vd_id.
它甚至说 "Select a valid choice. That choice is not one of the available choices."
我的问题是如何使用 django_filters 制作此 link? 我想我应该在 class 中写一些方法,但我完全不知道该怎么做。
如果有人知道答案,我将不胜感激!
一般来说,您需要回答两个问题:
- 我们要查询什么字段以及需要生成什么 query/lookup 表达式。
- 我们应该过滤什么样的值。
这些答案基本上是您 .filter()
电话的左侧和右侧。
在这种情况下,您要过滤火山-火山信息关系 (vd_inf_vd_id
) 的反面,针对火山的破火山口数量 (vd_inf_numcal
)。此外,您需要 exact
匹配。
对于值,您需要一组包含整数的选项。
AllValuesFilter
将查看数据库列并根据列值生成选择。然而,缺点是选择不会包含任何缺失值,这在呈现时看起来很奇怪。您可以调整此字段,或使用普通 ChoiceFilter
,自行生成值。
def num_calderas_choices():
# Get the maximum number of calderas
max_count = VolcanoInformation.objects.aggregate(result=Max('vd_inf_numcal'))['result']
# Generate a list of two-tuples for the select dropdown, from 0 to max_count
# e.g, [(0, 0), (1, 1), (2, 2), ...]
return zip(range(max_count), range(max_count))
class VolcanoFilter(django_filters.FilterSet):
name = ...
num_calderas = django_filters.ChoiceFilter(
# related field traversal (note the connecting '__')
field_name='vd_inf_vd_id__vd_inf_numcal',
label='Number of calderas',
choices=num_calderas_choices
)
class Meta:
model = Volcano
fields = ['name', 'num_calderas']
请注意,我还没有亲自测试上面的代码,但它应该足够接近让你开始。
非常感谢!这正是我要找的!我不明白 .filter()
是如何工作的。
我对其他属性所做的是生成选择,但方式不同。例如,如果我只想显示可用位置的列表,我会使用:
# Location attribute
loc = VolcanoInformation.objects.values_list('vd_inf_loc', flat=True)
vd_inf_loc = django_filters.ChoiceFilter(
field_name='vd_inf_vd_id__vd_inf_loc',
label='Geographic location',
choices=zip(loc, loc),
)