我创建使用FilterSet
一个django_filters
,因此用户可以通过使用过滤器,如city
,age
和gender
其他用户的个人资料进行筛选。
在FilterSet的3场做工精细,但我也想通过interest
这是基于MultiSelectField
一个INTEREST_CHOICES
进行过滤。
用户应该能够检查基于这些多个利益和过滤器,除了上面列出的3个字段。
我一直无法得到这个工作。
我好不容易当用户选择从下拉框中的4个利益之一,但显示的兴趣过滤器领域,页面没有找到任何匹配,即使这些利益之一是匹配的。
我怀疑这是因为用户选择多个兴趣,因此,利益被保存在一个列表,而不是单独的,因此FilterSet
找不到独立的兴趣。
如果有人可以查看我的代码,并指出我在正确的方向,我将不胜感激。
models.朋友
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.朋友
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.朋友
@login_required
def profile_filter(request):
f = ProfileFilter(request.GET, queryset=Profile.objects.all())
return render(request, 'profile/profile_filter.html', {'filter': f})
URLs.朋友
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>
你不想通过精确匹配过滤,而是要通过,如果过滤器参数是包含在利益列表检查过滤。所以,你应该改变你这样的过滤器:
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(','))