django_table2 ν
μ΄λΈμ λ λλ§νλ €κ³ νλ AccountList
λ·°κ° μμ΅λλ€. 보기μ μμ€ μ½λ:
class AccountList(SingleTableMixin, FilterView):
model = Account
table_class = AccountTable
template_name = 'accounts/account_list.html'
context_table_name = 'object_list'
ordering = ['vps']
filterset_class = AccountFilter
μ΄ λ³΄κΈ°λ νμ¬ μ΄ νν° μΈνΈ(django_filtersμμ)λ₯Ό μ¬μ©νκ³ μμ΅λλ€.
import django_filters
from accounts.models import Account
class AccountFilter(django_filters.FilterSet):
class Meta:
model = Account
fields = ['is_suspended', 'is_abandoned']
is_suspended = django_filters.BooleanFilter(name='is_suspended', initial='False')
is_abandoned = django_filters.BooleanFilter(name='is_abandoned', initial='False')
def __init__(self, data=None, *args, **kwargs):
# if filterset is bound, use initial values as defaults
if data is not None:
# get a mutable copy of the QueryDict
data = data.copy()
for name, f in self.base_filters.items():
initial = f.extra.get('initial')
# filter param is either missing or empty, use initial as default
if not data.get(name) and initial:
data[name] = initial
super().__init__(data, *args, **kwargs)
μ΄ ν νλ¦Ώ μ¬μ©:
{% if filter %}
<form action="" method="get" class="form form-inline">
{{ filter.form.as_p }}
<input type="submit" />
</form>
{% endif %}
{% render_table object_list %}
{% endblock %}
μ΄κ²μ λ΄ urls.pyμμ κ°μ Έμ¨ κ²μ λλ€.
path('', login_required(AccountList.as_view())),
λ΄ νμ΄μ§ 127.0.0.1:8000
λ°©λ¬Ένλ©΄ νν°κ° μ€μ λμ§ μμ κ²μ λ³Ό μ μμ΅λλ€.
νμ§λ§ 127.0.0.1:8000?page=1
νλ©΄ νν°κ° μ λλ‘ μ΄κΈ°νλλ κ²μ λ³Ό μ μμ΅λλ€.
λ¬Έμμ΄ κ° 'False'
λμ μ€μ False
λΆμΈ κ°μ μ¬μ©ν΄ 보μμμ€.
κ·Έλμ λ€μμ μλνμ λ :
is_suspended = django_filters.BooleanFilter(name='is_suspended', initial=False)
is_abandoned = django_filters.BooleanFilter(name='is_abandoned', initial=False)
127.0.0.1:8000/
μμ νν°κ° λ λλ§λλ λ°©μμ
λλ€.
νν°κ° μ¬λ°λ₯Έ κ°μΌλ‘ λ λλ§λμμ§λ§ μΌμ μ€μ§λκ±°λ μ€λ¨λ κ³μ μ κ³μ λ³Ό μ μμΌλ―λ‘ νν°κ° ν¨κ³Όκ° μμμ΅λλ€.
λν νλ¨μ 2
λ²νΌμ λλ¬ 2νμ΄μ§λ₯Ό λ°©λ¬Ένλ©΄ νν°κ° Unknown
μ¬μ€μ λ μνμμ http://127.0.0.1:8000/?page=2
λλ¬ν©λλ€.
μ΄μ κ° μλ€κ³ 보μλκΉ?
μ£μ‘ν©λλ€. λμ λλ κ²μ΄ μμ΅λλ€.
첫 λ²μ§Έ λ¬Έμ μ κ²½μ° κ²°κ³Ό SQL 쿼리λ₯Ό μ΄ν΄λ³΄λ κ²μ΄ μ’μ΅λλ€. suspended
λ° abandoned
νν°κ° μ€μ λ‘ μ μ©λκ³ μλμ§ νμΈνμμμ€.
λ λ²μ§Έ λ¬Έμ μ κ²½μ° μμ λ°μ΄ν°λ₯Ό νμΈνκ² μ΅λλ€. νμ΄μ§λ₯Ό λ³κ²½ν λ suspended
λ° abandoned
νν°μ μλͺ»λ κ°μ΄ μ 곡λ μ μμ΅λλ€.
λͺ κ°μ§ μΈμ λ¬Έμ μ½μ νκ³ λ€μμ μ°Ύμμ΅λλ€.
def __init__(self, data=None, *args, **kwargs):
if data is not None: # 1
data = data.copy()
for name, f in self.base_filters.items():
initial = f.extra.get('initial')
# filter param is either missing or empty, use initial as default
if not data.get(name) and initial:
data[name] = initial
super(BaseFilterSet, self).__init__(data, *args, **kwargs)
λ°λΌμ data
λ None
. λ΄ ν΄λμ€ κΈ°λ° λ³΄κΈ°κ° data
λ₯Ό AccountFilter
μ λ¬νμ§ μλ μ΄μ λ₯Ό μκ² λ κΉμ?
ν . data
μΈμλ νμ FilterView
μ 곡ν΄μΌ ν©λλ€.
data
λ 첫 λ²μ§Έ νμ΄μ§μ λ λ²μ§Έ νμ΄μ§ λͺ¨λμ λΉμ΄ μμ΅λκΉ?
μ΄κ²μ μλ κ·Έλλ‘ μ²λ¦¬ν μ μμ΅λλ€. λ¬Έμ λ₯Ό μλ³νκΈ°μ μΆ©λΆν μ λ³΄κ° λ³΄λ₯ μ€μ λλ€.
2.0μΌλ‘ μ κ·Έλ μ΄λν νμλ λμΌν λ¬Έμ κ° λ°μν©λλ€. κ²°κ³Όλ₯Ό μ»μΌλ €λ©΄ κΈ°λ³Έ νμ΄μ§ λλ λΉ νν°κ° URLμ μμ΄μΌ ν©λλ€. μ΄κ²μ μ μ΄λ μ΄λκ°μ λ¬Έμνλμ΄ μμ΅λκΉ?
μ¬ννλ €λ©΄ μμ§ λ λ§μ μ λ³΄κ° νμν©λλ€...
page
? μ΄κ²μ Django Filterκ° μλλΌ νμ΄μ§ 맀κΉκ³Ό κ΄λ ¨μ΄ μμ§ μμ΅λκΉ?
μ νν μ΄λ€ μ λ³΄κ° νμνκ°μ? 2.0μΌλ‘ μ κ·Έλ μ΄λνλ©΄ μ€λͺ λ λμμ΄ λ°μν©λλ€. 1.1.0μΌλ‘ λ€μ΄κ·Έλ μ΄λνλ©΄ λͺ¨λ κ²μ΄ μ μμΌλ‘ λμμ΅λλ€. κ°λ₯ν ν μ΅μνμΌλ‘ 보기μ ββνν° μΈνΈλ₯Ό λ¨μννλ €κ³ μλνμ§λ§ λμμ΄ μ§μλλ―λ‘ μ¬ννκΈ°κ° μλΉν μ¬μμΌ ν©λλ€.
@moorchegue , λ¬Έμ λ₯Ό 보μ¬μ£Όλ μ΅μνμ μμ ν μ€νΈ μΌμ΄μ€ λλ ν μ€νΈ νλ‘μ νΈκ° λμμ΄ λ κ²μ λλ€.
λν νμ΄μ§ λ§€κΉ λ Όλ¦¬λ₯Ό μ 곡νλ λͺ¨λ νλͺ©μ λ¬Έμ κ° μλ κ² κ°μ΅λλ€. μ, μ λ²μ κ³Ό μ½κ°μ λΉνΈνμ±μ΄ μμ μ μμ§λ§ λ€λ₯Έ ν¨ν€μ§μ λλ²κΉ λ¬Έμ λ λ²μλ₯Ό λ²μ΄λ©λλ€. μ¬κΈ°μ ν μ μλ λͺ¨λ μμ μ μννλ €λ©΄ Django Filterμμ λ²κ·Έλ₯Ό μμ°ν΄μΌ ν©λλ€.
μ, μ¬κΈ°μ λ¬Έμ λ #788μ μΌλΆλ‘ λμ
λ is_valid()
λ°©λ²μ μμ΅λλ€.
data
μ΄ None
λ μλμΌλ‘ False
λ°νν©λλ€.
λ·°μμ object_list
λ₯Ό qs.none()
ν©λλ€.
λ°λΌμ κ΄μ°° λ νλ.
μ΄μ λν ν
μ€νΈλ ν
μ€νΈ ν
νλ¦Ώμ μ¬μ©νκ³ μκΈ° λλ¬Έμ μ€ν¨νμ§ μλ filter.qs
보λ€λ object_list
.
μ¦κ°μ μΈ ν΄κ²° λ°©λ²μ νν° μΈνΈμ strict = False
μ€μ νλ κ²μ
λλ€. μ΄λ‘ μΈν΄ μ€μ μ ν¨νμ§ μμ νν° λ§€κ°λ³μκ° λΉ κ²°κ³Όλ₯Ό νμνλ λμ λΆλΆ νν°λ§μΌλ‘ μ΄μ΄μ§μ§λ§ νμ¬λ‘μλ μλν μ μμ΄μΌ ν©λλ€. (λ¬Όλ‘ λ·° get
λ
Όλ¦¬λ₯Ό μ¬μ μνλ κ²μ΄ λ μ’μ΅λλ€...)
ꡬμλμ§ μμ μΌμ΄μ€μ λν μ²λ¦¬λ₯Ό κ°μ νκ³ μκ°νκ² μ΅λλ€.
ν . μ¬κΈ°μ μ£Όμ κ²°ν¨μ Viewμ object_list
μ FilterSetμ .qs
μ¬μ΄μ λΆμΌμΉμ
λλ€. μ격ν λμμ FilterSet.qs
λ€μ μ΄λνλ©΄ λ¬Έμ κ° ν΄κ²°λ©λλ€.
λν DRF λ°±μλμ λν μ격/λΉμ격 μ²λ¦¬κ° μμ΅λλ€.
λλ μ΄κ²μ λ¦μ κ²μ΄λ€.
@rpkilby μ΄ λ¬Έμ μ μ§μ μ΄ μμ΅λκΉ?
μ - PRμ μμνμ§λ§ λ΄ μ€ν μμ€ μμ μ 보λ₯ν΄μΌ νμ΅λλ€. λλ λ΄κ° μ€λ¨ν κ³³μμ κ½€ 빨리 λ€μ μμν μ μμ΄μΌ νλ€.
ν΄κ²° λ°©λ²μ FilterMixin
νμ νλͺ©(μλ§λ View
strict = False
μ μ€μ νλ κ²μ
λλ€.
무ν νμμ κ²½μ° qsλ₯Ό λ°ννλλ‘ μ‘°κ±΄μ λ³κ²½ν μ μμ΅λκΉ?
μ
- if self.filterset.is_valid() or not self.get_strict():
+ if not self.filterset.is_bound or self.filterset.is_valid() or not self.get_strict():
https://github.com/carltongibson/django-filter/pull/1007
κ°μ¬ ν΄μ.
κ°μ₯ μ μ©ν λκΈ
μ - PRμ μμνμ§λ§ λ΄ μ€ν μμ€ μμ μ 보λ₯ν΄μΌ νμ΅λλ€. λλ λ΄κ° μ€λ¨ν κ³³μμ κ½€ 빨리 λ€μ μμν μ μμ΄μΌ νλ€.