今回もタイトル通りですが、ネットで検索しても多段・複数チェックボックスを用いての例がほとんどみつかりませんでした。チェックボックスについては一段の例はあったのですが、やってみたところ、簡易的に多段かつ複数の絞り込みができたので、備忘録として挙げてみました。
早速ですが以下models.pyです。
つづいて、views.pyです。
さらに今回は、チェックボックスの状態を保持させたいので、カスタムテンプレートフィルタを作成します。まず、フォルダーを作成しその中に、空の__init__.pyも作成しておきます。
最後はurls.pyです。以下を追加します。
早速ですが以下models.pyです。
class mb_basic_spec(models.Model):
class Meta:
managed = False
db_table = 'mb_basic_spec'
art_id = models.BigIntegerField(primary_key=True, db_column='art_id')
art_name = models.TextField()
chipset_vendor = models.CharField(max_length=128)
chipset = models.CharField(max_length=128)
vendor = models.CharField(max_length=128)
cpu_socket = models.CharField(max_length=128)
form_factor = models.CharField(max_length=128)
memory_form = models.CharField(max_length=128)
memory_type = models.CharField(max_length=128)
class v_vendor(models.Model):
class Meta:
managed = False
db_table = 'view_vendor'
vendor_id = models.IntegerField(primary_key=True, db_column='vendor_id')
vendor = models.CharField(max_length=128)
class v_chipset(models.Model):
class Meta:
managed = False
db_table = 'view_chipset'
chipset_id = models.IntegerField(primary_key=True, db_column='chipset_id')
chipset_vendor = models.CharField(max_length=128)
chipset = models.CharField(max_length=128)
実は上記はすべてviewですが、managed=Falseとすることでpython manage.py migrateしてもデータベースに変更は入りませんので手動でviewをメンテする必要がありますが、今回はそれには触れません。つづいて、views.pyです。
...
from .models import mb_basic_spec, v_vendor, v_chipset
class mb_basic_specListView(ListView):
model = mb_basic_spec
template_name = 'myapp/mb_basic_spec_list.html'
def get_context_data(self, **kwargs):
context = super(mb_basic_specListView, self).get_context_data(**kwargs)
vendors = v_vendor.objects.all()
chipsets = v_chipset.objects.all()
context['vendors'] = vendors
context['chipsets'] = chipsets
return context
def get_queryset(self):
results = mb_basic_spec.objects.all()
q_vendors = self.request.GET.getlist('vendor', None)
q_chipsets = self.request.GET.getlist('chipset', None)
if len(q_vendors) != 0:
results = results.filter(vendor__in=q_vendors)
if len(q_chipsets) != 0:
results = results.filter(chipset__in=q_chipsets)
return results
get_context_dataでは、contextにvendorsとchipsetsをそれぞれセットしておきます。そうしないとcheckboxが表示されません。また、get_querysetでも、それぞれ self.request.GET.getlistにて絞り込みするようにしておきます。絞り込みは記述通り resultsを上書きすることで多段絞り込み出来るようにしています。さらに今回は、チェックボックスの状態を保持させたいので、カスタムテンプレートフィルタを作成します。まず、フォルダーを作成しその中に、空の__init__.pyも作成しておきます。
mkdir myapp/templatetags touch myapp/templatetags/__init__.pyつづいてカスタムフィルターを作成します。名前は myapp/templatetags/mb_basic_spec_list_filters.py としてみました。
from django import template
register = template.Library()
@register.filter
def vendor_checked(value, querydict):
vendors = querydict.getlist('vendor')
if str(value) in vendors:
return "checked"
return ""
@register.filter
def chipset_checked(value, querydict):
chipsets = querydict.getlist('chipset')
if str(value) in chipsets:
return "checked"
return ""
つづいてtemplateを作成します。名称はmb_basic_spec_list.htmlとしました。
{% extends "base/base.html" %}
{% load mb_basic_spec_list_filters %}
{% block content %}
<form method="get" action="" name="myapp_filter">
<div>
<span>vendor: </span>
{% for vendor in vendors %}
<input type="checkbox" id="filter_vendor_{{ vendor.pk }}"
name="vendor"
value="{{ vendor.vendor }}"
{{ vendor.vendor | vendor_checked:request.GET }}/>
{{ vendor.vendor}}
</input>
{% endfor %}
<br/>
<span>chiset: </span>
{% for chipset in chipsets %}
<input type="checkbox" id="filter_chipset_{{ chipset.pk }}"
name="chipset"
value="{{ chipset.chipset }}"
{{ chipset.chipset | chipset_checked:request.GET }}/>
{{ chipset.chipset }}
</input>
{% endfor %}
<br/>
<button id="filter">絞り込み</button>
</div>
<table class="ui celled table" style='width:1000px;overflow-x:scroll'>
<thead>
<tr>
<th>name</th>
<th>chipset vendor</th>
<th>chipset</th>
<th>vendor</th>
<th>cpu socket</th>
<th>form factor</th>
<th>memory form</th>
<th>memory type</th>
</tr>
</thead>
<tbody>
{% for prop in mb_basic_spec_list %}
<tr>
<td>{{ prop.art_name }}</td>
<td>{{ prop.chipset_vendor }}</td>
<td>{{ prop.chipset }}</td>
<td>{{ prop.vendor }}</td>
<td>{{ prop.cpu_socket }}</td>
<td>{{ prop.form_factor }}</td>
<td>{{ prop.memory_form }}</td>
<td>{{ prop.memory_type }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</form>
{% endblock %}
カスタムテンプレートは2行目でロードしています。なおcssにはsemantic uiを使っています。最後はurls.pyです。以下を追加します。
from django.urls import path, include
from . import views
app_name = 'myapp'
urlpatterns = [
...
path('plane_mb_basic_spec/', views.mb_basic_speckListView.as_view(), name='mb_basic_spec_list'),
]
今回は以上です。それでは。
コメント
コメントを投稿