如何使用脆皮形式格式化 django-filters?
How to format django-filters using crispy forms?
是否可以使用 django-crispy-forms 格式化 django_filters 过滤器表单?我一直在尝试这样做,但 django_filters.FilterSet
似乎不接受脆皮格式(来自 DeviceFilter class)。它不会给出错误 either.The 唯一似乎能够给出格式的是 {{ filter.form|crispy }}
但我希望能够在 python 中使用 FormHelper()
.
filters.py
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit, Row, Column
import django_filters
class DeviceFilter(django_filters.FilterSet):
device_type = django_filters.ModelChoiceFilter(lookup_expr='exact', field_name='device_type__pk',
queryset=None)
device_group = django_filters.ModelChoiceFilter(lookup_expr='exact, field_name='device_group__pk',
queryset=None)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.filters['device_type'].queryset = DeviceType.objects.filter(owner=self.request.user)
self.filters['device_group'].queryset = DeviceGroup.objects.filter(owner=self.request.user)
self.helper = FormHelper()
self.helper.layout = Layout(
Row(
Column('device_type', css_class='form-group col-md-6 mb-0'),
Column('device_group', css_class='form-group col-md-4 mb-0'),
css_class='form-row'
),
Submit('submit', 'filter')
)
class Meta:
model = Device
fields = {}
模板
<!-- filter -->
{% if filter %}
<form method="get">
{{ filter.form|crispy }}
</form>
{% endif %}
更新
我分享我的最终解决方案。这呈现:
class DeviceForm(forms.ModelForm):
class Meta:
model = Device
fields = [
'device_id',
'device_type',
'device_group',
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
Row(
Column('device_created', css_class='form-group col-12'),
css_class='form-row'
),
Row(
Column('device_id', css_class='form-group col-12'),
css_class='form-row'
),
Row(
Column('device_type', css_class='form-group col-6 mb-0'),
Column('device_group', css_class='form-group col-6 mb-0'),
css_class='form-row'
),
)
class DeviceFilter(django_filters.FilterSet):
device_created = django_filters.DateTimeFromToRangeFilter(label='', widget=MyRangeWidget(
{
'class': 'datetimepicker form-control',
'placeholder': 'From'
}, {
'class': 'datetimepicker form-control',
'placeholder': 'To'
}
))
device_id = django_filters.CharFilter(label='', lookup_expr='icontains', widget=TextInput(attrs={
'placeholder': 'Enter Device Id'
}))
device_group = django_filters.ModelChoiceFilter(label='', lookup_expr='exact',
field_name='device_group__pk',
queryset=None, empty_label=('Select Group'))
device_type = django_filters.ModelChoiceFilter(label='', lookup_expr='exact',
field_name='device_type__pk',
queryset=None, empty_label=('Select Type'))
class Meta:
form = DeviceForm
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.filters['device_type'].queryset = DeviceType.objects.filter(owner=self.request.user)
self.filters['device_group'].queryset = DeviceGroup.objects.filter(owner=self.request.user)
尝试将助手设置为表单
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Your code
self.form.helper = FormHelper()
# Your code
或者尝试在 meta 中设置表单 class
class DeviceFilter(django_filters.FilterSet):
# Your code
class Meta:
form = YourCustomFormClass
这个 Github gist 有一个非常好的解决方案。关键部分是定义一个基础 class(作者称他们为 FilteredSingleTableView
),您的 table 视图将从中继承。基础 class 有一个 formhelper_class
class 属性,children 可以使用它指向定义布局的 Crispy Form 的 FormHelper
subclass =15=]
这是他们的那部分代码。我不会 re-post 剩下的,因为 link 更容易理解
from django_filters.views import FilterView
from django_tables2 import SingleTableMixin
class FilteredSingleTableView(SingleTableMixin, FilterView):
"""Base class for table filtering with crispy forms
Subclasses should override the formhelper_class
"""
formhelper_class = None
def get_filterset(self, filterset_class):
"""Where the magic happens
Add the helper class to the pre-existing form from django-filters
"""
kwargs = self.get_filterset_kwargs(filterset_class)
filterset = filterset_class(**kwargs)
filterset.form.helper = self.formhelper_class()
return filterset
是否可以使用 django-crispy-forms 格式化 django_filters 过滤器表单?我一直在尝试这样做,但 django_filters.FilterSet
似乎不接受脆皮格式(来自 DeviceFilter class)。它不会给出错误 either.The 唯一似乎能够给出格式的是 {{ filter.form|crispy }}
但我希望能够在 python 中使用 FormHelper()
.
filters.py
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit, Row, Column
import django_filters
class DeviceFilter(django_filters.FilterSet):
device_type = django_filters.ModelChoiceFilter(lookup_expr='exact', field_name='device_type__pk',
queryset=None)
device_group = django_filters.ModelChoiceFilter(lookup_expr='exact, field_name='device_group__pk',
queryset=None)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.filters['device_type'].queryset = DeviceType.objects.filter(owner=self.request.user)
self.filters['device_group'].queryset = DeviceGroup.objects.filter(owner=self.request.user)
self.helper = FormHelper()
self.helper.layout = Layout(
Row(
Column('device_type', css_class='form-group col-md-6 mb-0'),
Column('device_group', css_class='form-group col-md-4 mb-0'),
css_class='form-row'
),
Submit('submit', 'filter')
)
class Meta:
model = Device
fields = {}
模板
<!-- filter -->
{% if filter %}
<form method="get">
{{ filter.form|crispy }}
</form>
{% endif %}
更新
我分享我的最终解决方案。这呈现:
class DeviceForm(forms.ModelForm):
class Meta:
model = Device
fields = [
'device_id',
'device_type',
'device_group',
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
Row(
Column('device_created', css_class='form-group col-12'),
css_class='form-row'
),
Row(
Column('device_id', css_class='form-group col-12'),
css_class='form-row'
),
Row(
Column('device_type', css_class='form-group col-6 mb-0'),
Column('device_group', css_class='form-group col-6 mb-0'),
css_class='form-row'
),
)
class DeviceFilter(django_filters.FilterSet):
device_created = django_filters.DateTimeFromToRangeFilter(label='', widget=MyRangeWidget(
{
'class': 'datetimepicker form-control',
'placeholder': 'From'
}, {
'class': 'datetimepicker form-control',
'placeholder': 'To'
}
))
device_id = django_filters.CharFilter(label='', lookup_expr='icontains', widget=TextInput(attrs={
'placeholder': 'Enter Device Id'
}))
device_group = django_filters.ModelChoiceFilter(label='', lookup_expr='exact',
field_name='device_group__pk',
queryset=None, empty_label=('Select Group'))
device_type = django_filters.ModelChoiceFilter(label='', lookup_expr='exact',
field_name='device_type__pk',
queryset=None, empty_label=('Select Type'))
class Meta:
form = DeviceForm
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.filters['device_type'].queryset = DeviceType.objects.filter(owner=self.request.user)
self.filters['device_group'].queryset = DeviceGroup.objects.filter(owner=self.request.user)
尝试将助手设置为表单
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Your code
self.form.helper = FormHelper()
# Your code
或者尝试在 meta 中设置表单 class
class DeviceFilter(django_filters.FilterSet):
# Your code
class Meta:
form = YourCustomFormClass
这个 Github gist 有一个非常好的解决方案。关键部分是定义一个基础 class(作者称他们为 FilteredSingleTableView
),您的 table 视图将从中继承。基础 class 有一个 formhelper_class
class 属性,children 可以使用它指向定义布局的 Crispy Form 的 FormHelper
subclass =15=]
这是他们的那部分代码。我不会 re-post 剩下的,因为 link 更容易理解
from django_filters.views import FilterView
from django_tables2 import SingleTableMixin
class FilteredSingleTableView(SingleTableMixin, FilterView):
"""Base class for table filtering with crispy forms
Subclasses should override the formhelper_class
"""
formhelper_class = None
def get_filterset(self, filterset_class):
"""Where the magic happens
Add the helper class to the pre-existing form from django-filters
"""
kwargs = self.get_filterset_kwargs(filterset_class)
filterset = filterset_class(**kwargs)
filterset.form.helper = self.formhelper_class()
return filterset