【问题标题】:Django-Filter: Creating checkboxes for Boolean FieldDjango-Filter:为布尔字段创建复选框
【发布时间】:2020-08-12 04:56:55
【问题描述】:

Models.py

class Task(models.Model):
    online = models.BooleanField(blank=False)

我想使用 django-filter 在表单中创建以下复选框:

[] 在线 [] 物理

如果表单为空或两者都打勾,请获取Task.objects.all()。如果只勾选一个,则执行Task.objects.filter('Online'=True/False)

我尝试添加以下内容:

import django_filters
from app.models import Task
from django.db import models

class TaskFilter(django_filters.FilterSet):
    online = django_filters.BooleanFilter(name='online', lookup_expr='isnull')

    class Meta:
        model = Task
        fields = ['online']
        filter_overrides = {
            models.BooleanField: { 
                'filter_class': django_filters.BooleanFilter,
                'extra': lambda f: {
                    'widget': forms.CheckboxInput,
                },
            },
        }

我尝试了以下小部件:Select, RadioSelect, CheckboxInput,但似乎我得到了所有这些小部件的相同输出。我得到一个下拉列表,例如

在线:[下拉菜单从是、否、未知中选择一个值]

【问题讨论】:

    标签: python django django-filter


    【解决方案1】:

    您可以对这类东西使用选择:

    TYPE_CHOICES = (
        (0, 'Online'),
        (1, 'Physical'),
    )
    class Task(models.Model):
        type = models.CharField(
            choices=TYPE_CHOICES, default=0, max_length=100
        )
        objects = TaskQuerySet().as_manager()
    

    然后你就可以照常过滤了:

    Task.objects.filter(type=0).filter(...)
    

    为了更容易,您可以添加一个自定义查询集类:

    class TaskQuerySet(models.QuerySet):
        def get_online(self):
            return self.filter(type=0)
    
        def get_physical(self):
            return self.filter(type=1)
    

    这将允许您执行以下操作:

    Task.objects.get_online.filter(...)
    Task.objects.get_physical.filter(...)
    

    filters.py 中添加:

    type = django_filters.MultipleChoiceFilter(field_name='type', choices=CHOICES, widget=forms.CheckboxSelectMultiple)
    

    【讨论】:

    • 谢谢,但我正在尝试使用django-filter 库来解决这个问题,以通过表单合并前端过滤。从技术上讲,我可以使用django_filters.ModelMultipleChoiceFilter() 后面的选项,但理想情况下我会将布尔值转换为复选框
    【解决方案2】:

    过滤器接受一个小部件参数,所以如果你手动实例化过滤器,你可以使用:

    class TaskFilter(django_filters.FilterSet):
        online = django_filters.filters.BooleanFilter(widget=forms.CheckboxInput)
        class Meta:
            model = Task
            fields = ['online']
    

    但是,如果您使用元类来声明字段,那么您可以使用 filter_overrides 覆盖该行为

    class TaskFilter(django_filters.FilterSet):
        filter_overrides = {
            models.BooleanField: {
                'filter_class': filters.BooleanFilter,
                'extra': lambda f: {
                    widget: forms.CheckboxInput
                },
            }
        }
        class Meta:
            model = MyModel
            fields = ['online']
    

    经过大量测试,我得出的结论通常对default=False 模型字段很有帮助。

    refer: django-filter issue

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-13
      • 1970-01-01
      • 2018-07-03
      • 2019-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多