如何使用django_property_filter过滤Django模型的property属性?
解决django_property_filter过滤模型property属性的问题
首先修正代码中的基础错误:Member类必须继承models.Model,否则无法作为Django模型使用:
# models.py from django.db import models class Manager(models.Model): name = models.CharField(max_length=35) class Plan(models.Model): name = models.CharField(max_length=35) manager = models.ForeignKey(Manager, on_delete=models.CASCADE) class Member(models.Model): # 补充继承models.Model name = models.CharField(max_length=35) plan = models.ForeignKey(Plan, on_delete=models.CASCADE) @property def manager(self): return self.plan.manager
接下来,针对manager这个返回Manager实例的property,你需要使用**PropertyModelChoiceFilter(单选)或PropertyModelMultipleChoiceFilter(多选)**,而非PropertyChoiceFilter系列。原因是:
PropertyChoiceFilter仅支持匹配字符串/数值类型的property值,而你的manager返回的是Manager模型实例,类型不匹配PropertyModelChoiceFilter专门用于处理返回模型实例的property,它会自动将请求传入的主键值转换为对应模型实例,再与property返回值做匹配
单选过滤器实现(filters.py)
from django_property_filter import PropertyFilterSet, PropertyModelChoiceFilter from .models import Member, Manager class MemberFilter(PropertyFilterSet): manager = PropertyModelChoiceFilter( field_name='manager', queryset=Manager.objects.all(), # 自动生成选项的查询集 label='选择经理' ) class Meta: model = Member fields = ['manager']
多选过滤器实现(filters.py)
如果需要同时选择多个经理过滤,改用PropertyModelMultipleChoiceFilter:
from django_property_filter import PropertyFilterSet, PropertyModelMultipleChoiceFilter from .models import Member, Manager class MemberFilter(PropertyFilterSet): manager = PropertyModelMultipleChoiceFilter( field_name='manager', queryset=Manager.objects.all(), label='选择多个经理' ) class Meta: model = Member fields = ['manager']
使用示例(视图)
from django.shortcuts import render from .models import Member from .filters import MemberFilter def member_list(request): member_filter = MemberFilter(request.GET, queryset=Member.objects.all()) return render(request, 'member_list.html', {'filter': member_filter})
模板渲染过滤表单
在模板中可以直接渲染过滤器的表单,以及过滤后的结果:
<form method="get"> {{ filter.form.as_p }} <button type="submit">筛选</button> </form> <div> {% for member in filter.qs %} <p>{{ member.name }} - 所属经理:{{ member.manager.name }}</p> {% endfor %} </div>
内容的提问来源于stack exchange,提问作者guy007
相关产品推荐
相关产品推荐

