クエリパラメータのURLで使用されているフィールド名の名前を変更できるかどうか疑問に思いました。
現在
class TransactionFilter(django_filters.FilterSet):
created = django_filters.DateFromToRangeFilter()
class Meta:
model = models.Transaction
fields = ('created', )
リクエストは次のようになります
/api/transaction?created_0=2015-01-01&created_1=2015-01-02
これは正しく機能していますが、あまり直感的ではありません。 たとえば、範囲フィールドに別の名前を使用できる方法があるかどうか疑問に思いました。
/api/transaction?created_since=2015-01-01&created_until=2015-01-02
ありがとう、ハキ。
うーん。 ここでの答えは_実際には_ではないと思います—手を汚したくないのでなければ...
_0, _1
付属物のロジックは、$# django.forms.widgets.MultiWidget.render
からずっと来ています。 ( RangeFilter
は$ MultiWidget
サブクラスであるRangeWidget
を使用するRangeField
を使用します。)
render
を自由に実装して、必要な名前を付けることができます。 一致するvalue_from_datadict
も必要です。
これを行うためにMultiWidget
をサブクラス化する例を次に示します。 フィールド名としてstart
とend
を使用しました。
from django.utils.safestring import mark_safe
from django_filters.fields import DateRangeField
from django_filters.filters import RangeFilter
from django_filters.widgets import RangeWidget
class StartEndRangeWidget(RangeWidget):
"""
A range widget that uses 'start' and 'end' instead of '0' and '1'.
"""
attr_names = ('start', 'end')
def render(self, name, value, attrs=None):
if self.is_localized:
for widget in self.widgets:
widget.is_localized = self.is_localized
# value is a list of values, each corresponding to a widget
# in self.widgets.
if not isinstance(value, list):
value = self.decompress(value)
output = []
final_attrs = self.build_attrs(attrs)
id_ = final_attrs.get('id')
for i, widget in enumerate(self.widgets):
try:
widget_value = value[i]
except IndexError:
widget_value = None
if id_:
final_attrs = dict(final_attrs,
id='%s_%s' % (id_, self.attr_names[i]))
output.append(widget.render(name + '_%s' % self.attr_names[i],
widget_value, final_attrs))
return mark_safe(self.format_output(output))
def value_from_datadict(self, data, files, name):
return [widget.value_from_datadict(data, files,
name + '_%s' % self.attr_names[i])
for i, widget in enumerate(self.widgets)]
class StartEndDateRangeField(DateRangeField):
"""
A DateRangeField that uses 'start' and 'end'.
"""
widget = StartEndRangeWidget
class StartEndDateFromToRangeFilter(RangeFilter):
"""
A RangeFilter that uses 'start' and 'end'.
"""
field_class = StartEndDateRangeField
ねえ@beaugunderson 、場合によっては(私のような)、lt / gtで2つの日付フィールドを使用する方が簡単であることを言及する価値があります。
最も参考になるコメント
これを行うために
MultiWidget
をサブクラス化する例を次に示します。 フィールド名としてstart
とend
を使用しました。