Khi phát triển website, autocomplete (lọc dần dữ liệu) là một trong những tính năng thường xuyên được sử dụng. Đặc biệt là trong các website dữ liệu lớn, autocomplete giúp website chúng ta load được nhanh hơn.
Table of Contents
Giả thiết bài toán
Model DcaDetail có 100,000 bản ghi về sinh viên thuộc 1000 city khác nhau. Chúng ta cần lọc sinh viên theo city áp dụng autocomplete dropdownlist
Công nghệ sử dụng
- Django
- Django-filter
- Django-tables2
- Django-autocomplete-light
Cài đặt và cấu hình các gói
Cài đặt
1 2 3 |
pip install django-tables2 pip install django-filter pip install django-autocomplete-light |
Cấu hình thêm vào INSTALLED_APPS
1 2 3 4 5 6 7 8 |
INSTALLED_APPS = [ .. 'django_tables2', 'dal', 'dal_select2', 'django_filters', ... ] |
Tạo autocomplete base view
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from dal import autocomplete class CityAutocomplete(autocomplete.Select2ListView): def get_list(self): qs = DcaDetail.objects.all() if self.q: qs = qs.filter(city__istartswith=self.q).values('city').order_by('city').distinct() cities = qs.values('city').order_by('city').distinct() city_choices = [] for item in cities: city_choices.append(item['city']) return city_choices |
Đăng kí url cho autocomplete view
1 2 3 4 5 6 |
from django.urls import path, include, re_path re_path( r'^city-autocomplete/$', views.CityAutocomplete.as_view(), name='city-autocomplete', ), |
Kiểm tra view hoạt động hay không
Sử dụng autocomplete widget trong filters
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
from dal import autocomplete # Filter by city all_cities = DcaDetail.objects.values('city').order_by('city').distinct() city_choices = [] for item in all_cities: city_choices.append((item['city'], item['city'])) city = django_filters.ChoiceFilter( label="City", choices= city_choices, method='filter_by_city', widget=autocomplete.Select2( url='backend:city-autocomplete', attrs={ # Set some placeholder 'data-placeholder': 'City ...', # Only trigger autocompletion after 2 characters have been typed 'data-minimum-input-length': 2, 'style': 'height:34px !important;' }, ) ) def filter_by_city(self, queryset, name, value): return queryset.filter(city__contains=value) |
Render filter trong template
1 2 3 4 5 6 7 |
<div class="form-group col-sm-4 col-md-4"> {{ filter.form.city.label_tag }} {% render_field filter.form.city class="form-control" style="height:34px !important;"%} </div> {{ filter.form.media }} |
Tùy chỉnh css nếu cần thiết
1 2 3 4 5 6 7 |
.select2-container--default .select2-selection--single { border: 1px solid #ddd !important; } .select2-container .select2-selection--single { height: 34px !important; padding: 2px 10px !important; } |
Mình là một lập trình viên tự do với hơn 10 năm kinh nghiệm. Mình chuyên về Web scraping, Web automation, Python, Django