【问题标题】:How to use django-filter package for foreign key fields in Django?如何在 Django 中为外键字段使用 django-filter 包?
【发布时间】:2022-01-26 21:33:21
【问题描述】:

大家好!

Django 中的新手,很困惑,感谢帮助!感谢stackoverflow用户,我创建了一个表,例如:

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 模型和上诉日期(Appeal_date Appeal_date 字段)过滤表格内容。案例:用户打开一个表格,然后从表格上方的搜索栏中选择要查看的申诉表和/或日期范围。

问题:如何使用django-filter包过滤views.py上面的查询?

【问题讨论】:

  • 您过滤的是哪个型号?组织还是上诉?
  • 嗨@nigel222,我正在过滤组织模型。

标签: python django django-models foreign-keys django-filter


【解决方案1】:

定义复杂过滤器的最通用方法是使用方法参数。我不能说我完全理解你的问题,但是你可以应用任何你可以通过这种方式设计查询集的过滤器。概述:

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

这是我编写的一个相当简单的方法,用于创建一个带有去掉空格的字段值的注释,然后对其进行文本包含过滤器。

    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"')

希望这会有所帮助。您基本上将通过遵循模型之间的关系进行过滤,使用双下划线在模型之间移动,并可能对注释进行注释和过滤,或者使用 Q 对象等进行操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 2020-10-20
    • 2021-11-02
    • 2021-10-25
    • 1970-01-01
    相关资源
    最近更新 更多