我已经使用FilterSet
创建了一个django_filters
,因此用户可以使用city
,age
和gender
等过滤器来过滤其他用户的个人资料。 / p>
FilterSet中的这3个字段可以正常工作,但是我也想通过interest
进行过滤,该MultiSelectField
是基于INTEREST_CHOICES
的{{1}}。
除了上面列出的3个字段之外,用户还应该能够检查多个兴趣并根据这些兴趣进行过滤。
我无法使它正常工作。
我设法显示了一个兴趣过滤器字段,但是当用户从下拉框中选择4个兴趣之一时,即使这些兴趣之一被匹配,页面也不会返回任何匹配项。
我怀疑是因为用户选择了多个兴趣,因此兴趣被保存在列表中而不是单独保存,因此FilterSet
找不到独立兴趣。
如果有人可以查看我的代码并将我指向正确的方向,我将不胜感激。
models.py
class Profile(models.Model):
INTEREST_CHOICES = (
('FITNESS', 'Fitness'),
('CHURCH', 'Church'),
('VEGANISM', 'Veganism'),
('MOVIES', 'Movies'),
)
GENDER_CHOICES = (
('M', 'Male'),
('F', 'Female'),
('X', 'Neither')
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
interests = MultiSelectField(choices = INTEREST_CHOICES)
city = models.CharField(max_length=30)
age = models.CharField(max_length=2)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
filters.py
import django_filters
from .models import Profile
class ProfileFilter(django_filters.FilterSet):
class Meta:
model = Profile
fields = {
'city': ['iexact'],
'interests': ['exact'],
'age': ['iexact'],
'gender': ['exact'],
}
views.py
@login_required
def profile_filter(request):
f = ProfileFilter(request.GET, queryset=Profile.objects.all())
return render(request, 'profile/profile_filter.html', {'filter': f})
urls.py
path('filter', user_views.profile_filter, name='profile_filter'),
profile_filter.html
<h1>Filter people.</h1>
<form method="GET">
{{ filter.form|crispy }}
<button type="submit" class="small">Search.</button>
</form>
答案 0 :(得分:1)
您不想按完全匹配进行过滤,而是希望通过检查兴趣列表中是否包含过滤器参数来进行过滤。因此,您应该这样更改过滤器:
class ProfileFilter(django_filters.FilterSet):
class Meta:
model = Profile
fields = {
'city': ['iexact'],
'interests': ['icontains'],
'age': ['iexact'],
'gender': ['exact'],
}
编辑:允许按多个兴趣进行过滤。
在这里,您必须编写一个自定义方法来解析兴趣并将其转换为数组,然后再进行过滤。它们通常以带有逗号分隔值的字符串形式出现。
将方法添加到过滤器类中,如下所示:
class ProfileFilter(django_filters.FilterSet):
interests = django_filters.CharFilter(field_name='interests', method='filter_interests')
city = django_filters.CharFilter(field_name='city', lookup_expr='iexact')
age = django_filters.NumberFilter(field_name='age', lookup_expr='iexact')
gender = django_filters.CharFilter(field_name='gender', lookup_expr='iexact')
class Meta:
model = Profile
fields = ['age', 'city', 'gender', 'interests']
def filter_interests(self, queryset, name, interests):
return queryset.filter(interests__contains=interests.split(','))