如何在 Django 中为外键字段使用 django-filter 包?
How to use django-filter package for foreign key fields in Django?
大家好!
Django新手,一头雾水,不胜感激!我创建了一个 table, ,感谢 Whosebug 用户,例如:
Organization
Total amount of appeals
Amount of written form appeals
Amount of oral form appeals
Organization 1
3
1
2
Organization 2
2
1
1
拥有三个模型:
class Organization(models.Model):
organization_name = models.CharField(max_length=50)
class AppealForm(models.Model):
form_name = models.CharField(max_length=50)
class Appeal(models.Model):
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
appeal_form = models.ForeignKey(AppealForm, on_delete=models.CASCADE)
applicant_name = models.CharField(max_length=150)
appeal_date = models.DateField()
组织模型的对象:
organization_name
Organization 1
Organization 2
AppealForm 模型的对象:
form_name
In written form
In oral form
上诉对象模型:
organization
appeal_form
applicant_name
Organization 1
In written form
First and Last name
Organization 1
In oral form
First and Last name
Organization 1
In oral form
First and Last name
Organization 2
In written form
First and Last name
Organization 2
In oral form
First and Last name
在 views.py 文件的函数中,我创建了一个要呈现的查询,例如:
from django.db.models import Count, Q
organizations = Organization.objects.annotate(
).annotate(
total=Count('appeal'),
total_written=Count('appeal', filter=Q(appeal__appeal_form__form_name='in written form')),
total_oral=Count('appeal', filter=Q('appeal__appeal_form__form_name='in oral form'))
)
现在我想通过 AppealForm 模型和上诉日期过滤 table 内容(appeal_date 上诉模型 的领域)。案例:用户打开 table 并从 table 上方的搜索栏中选择要查看的日期范围 and/or 的申诉表单。
问题:如何使用 django-filter 包过滤 views.py 上面的查询?
定义复杂过滤器的最常用方法是使用方法参数。我不能说我完全理解你的问题,但你可以应用任何过滤器,你可以通过这种方式为其设计一个查询集。大纲:
import django-filters as DF
class SomeFilters( DF.FilterSet):
name = DF.xxxFilter( method='my_method', field_name='object_field', label='whatever', ...)
...
def my_method( self, qs, name, value):
# in here you create a new more restrictive queryset based on qs
# to implement your filter, and return it.
# name is the field name. Note, you don't have to use or follow it
# value is the value that the user typed
qs = qs.filter( ...) # or .exclude, or complicated stuff
return qs
这是我编写的一个相当简单的方法,用于创建一个带有去除空格的字段值的注释,然后对其执行 text-contains 过滤器。
def filter_array_desc( self, qs, name, value):
value = value.replace(' ','')
qs = qs.annotate(
arr_d_nospaces = Replace( 'array_desc', Value(' '), Value('')) # delete all spaces
).filter(
arr_d_nospaces__icontains = value )
return qs
这是一个通用的,可以通过ChoiceFilter
应用于任何字段来过滤该字段是否为空:
YESNO = (('Y','Yes'), ('N','No'))
marr_b = FD.ChoiceFilter( field_name='marr', label='M_array is blank', method='filter_blank_yesno',
choices=YESNO, empty_label="Don't Care" )
...
def filter_blank_yesno( self, qs, name, value):
if value=="Y":
return qs.filter(**{ name:'' })
elif value=="N":
return qs.exclude( **{ name:'' })
raise ValueError(f'filter_blank_yesno received value="{value}" which is neither "Y" nor "N"')
希望这对您有所帮助。您基本上将通过遵循模型之间的关系进行过滤,使用 double-underscores 在模型之间移动,并可能在注释上进行注释和过滤,或者使用 Q 对象等进行操作。
大家好!
Django新手,一头雾水,不胜感激!我创建了一个 table, ,感谢 Whosebug 用户,例如:
Organization | Total amount of appeals | Amount of written form appeals | Amount of oral form appeals |
---|---|---|---|
Organization 1 | 3 | 1 | 2 |
Organization 2 | 2 | 1 | 1 |
拥有三个模型:
class Organization(models.Model):
organization_name = models.CharField(max_length=50)
class AppealForm(models.Model):
form_name = models.CharField(max_length=50)
class Appeal(models.Model):
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
appeal_form = models.ForeignKey(AppealForm, on_delete=models.CASCADE)
applicant_name = models.CharField(max_length=150)
appeal_date = models.DateField()
组织模型的对象:
organization_name |
---|
Organization 1 |
Organization 2 |
AppealForm 模型的对象:
form_name |
---|
In written form |
In oral form |
上诉对象模型:
organization | appeal_form | applicant_name |
---|---|---|
Organization 1 | In written form | First and Last name |
Organization 1 | In oral form | First and Last name |
Organization 1 | In oral form | First and Last name |
Organization 2 | In written form | First and Last name |
Organization 2 | In oral form | First and Last name |
在 views.py 文件的函数中,我创建了一个要呈现的查询,例如:
from django.db.models import Count, Q
organizations = Organization.objects.annotate(
).annotate(
total=Count('appeal'),
total_written=Count('appeal', filter=Q(appeal__appeal_form__form_name='in written form')),
total_oral=Count('appeal', filter=Q('appeal__appeal_form__form_name='in oral form'))
)
现在我想通过 AppealForm 模型和上诉日期过滤 table 内容(appeal_date 上诉模型 的领域)。案例:用户打开 table 并从 table 上方的搜索栏中选择要查看的日期范围 and/or 的申诉表单。
问题:如何使用 django-filter 包过滤 views.py 上面的查询?
定义复杂过滤器的最常用方法是使用方法参数。我不能说我完全理解你的问题,但你可以应用任何过滤器,你可以通过这种方式为其设计一个查询集。大纲:
import django-filters as DF
class SomeFilters( DF.FilterSet):
name = DF.xxxFilter( method='my_method', field_name='object_field', label='whatever', ...)
...
def my_method( self, qs, name, value):
# in here you create a new more restrictive queryset based on qs
# to implement your filter, and return it.
# name is the field name. Note, you don't have to use or follow it
# value is the value that the user typed
qs = qs.filter( ...) # or .exclude, or complicated stuff
return qs
这是我编写的一个相当简单的方法,用于创建一个带有去除空格的字段值的注释,然后对其执行 text-contains 过滤器。
def filter_array_desc( self, qs, name, value):
value = value.replace(' ','')
qs = qs.annotate(
arr_d_nospaces = Replace( 'array_desc', Value(' '), Value('')) # delete all spaces
).filter(
arr_d_nospaces__icontains = value )
return qs
这是一个通用的,可以通过ChoiceFilter
应用于任何字段来过滤该字段是否为空:
YESNO = (('Y','Yes'), ('N','No'))
marr_b = FD.ChoiceFilter( field_name='marr', label='M_array is blank', method='filter_blank_yesno',
choices=YESNO, empty_label="Don't Care" )
...
def filter_blank_yesno( self, qs, name, value):
if value=="Y":
return qs.filter(**{ name:'' })
elif value=="N":
return qs.exclude( **{ name:'' })
raise ValueError(f'filter_blank_yesno received value="{value}" which is neither "Y" nor "N"')
希望这对您有所帮助。您基本上将通过遵循模型之间的关系进行过滤,使用 double-underscores 在模型之间移动,并可能在注释上进行注释和过滤,或者使用 Q 对象等进行操作。