Я пытаюсь отобразить определенный набор объектов в моих моделях в ListView, и мне нужно создать набор запросов с соответствующими фильтрами. Я пытаюсь фильтровать протоколы по типам технологий, типам объектов и предметам. Все эти три фильтра имеют древовидную структуру, поэтому я импортировал модель MPTTM.
В models.py у меня есть такие модели:
from django.db import models
from mptt.models import MPTTModel
class BPSubject(MPTTModel, models.Model):
name = models.CharField(max_length=100, unique=False)
engname = models.CharField(max_length=100, unique=False)
parent = TreeForeignKey('self',null=True, blank=True, related_name='children', db_index=True)
scopenote = models.TextField(blank = True)
annotation = models.TextField(blank=True)
class BPTechnoType(MPTTModel, models.Model):
name = models.CharField(max_length=100)
engname = models.CharField(max_length=100)
parent = TreeForeignKey('self',null=True, blank=True, related_name='children', db_index=True)
class BPObjectType(MPTTModel, models.Model):
name = models.CharField(max_length=100)
engname = models.CharField(max_length=100)
parent = TreeForeignKey('self',null=True, blank=True, related_name='children', db_index=True)
bptechno = models.ManyToManyField(BPTechnoType, blank=True)
class Bioprotocol(models.Model):
Title = models.CharField(max_length=200)
TechnoType = models.ManyToManyField(BPTechnoType)
ObjectType = models.ManyToManyField(BPObjectType)
Abstract = models.TextField(blank=True)
Subject = models.ManyToManyField(BPSubject)
Затем я определил представление для своей индексной страницы, показывающее все категории (Subject, ObjectType и TechnoType):
В views.py:
class BPCategoryList(ListView):
model = BPSubject
context_object_name = "bpsubject_list"
template_name = 'index.html'
def get_context_data(self, **kwargs):
context = super(BPCategoryList, self).get_context_data(**kwargs)
context['bpobjecttype_list'] = BPObjectType.objects.all()
context['bptechnotype_list'] = BPTechnoType.objects.all()
context['bioprotocol_list'] = Bioprotocol.objects.all()
return context
Затем подключите это представление к моим URL-адресам:
urlpatterns = patterns('',
url(r'^index/', BPCategoryList.as_view()),
)
Шаблон для index.html выглядит следующим образом:
Примечания : В модели MPTT он автоматически генерирует поле «Уровень», указывающее уровень объекта в древовидной структуре, и я назначил название категории, например, «Тип технологии» / «Тип объекта» / «Тема» на уровне 0.
<div id="container">
<div id="sidebar">
<div class="mainNavs">
<div class="menu_box">
{% for bptechnotype in bptechnotype_list %}
{% if bptechnotype.level = 0 %} <!-- The Level 0 of the MPTT Model -->
<div class="menu_main">
<h2>{{ bptechnotype.name }}</h2>
</div>
<div class="menu_sub dn">
{% elif bptechnotype.level = 1 %}
<dl class="reset">
<dt><a href="/bptechnotype/{{ bptechnotype.name }}">{{ bptechnotype.name }}</a></dt>
<dd>
{% for children in bptechnotype.get_children %}
<a href="/bptechnotype/{{ children.name }}">{{ children.name }}</a>
{% endfor %}
</dd>
</dl>
{% endif %}
{% endfor %}
</div>
</div>
<div class="menu_box">
{% for bpobjecttype in bpobjecttype_list %}
{% if bpobjecttype.level = 0 %}
<div class="menu_main">
<h2>{{ bpobjecttype.name }}</h2>
</div>
<div class="menu_sub dn">
{% elif bpobjecttype.level = 1 %}
<dl class="reset">
<dt><a href="/bpobjecttype/{{ bpobjecttype.name }}">{{ bpobjecttype.name }}</a></dt>
<dd>
{% for children in bpobjecttype.get_children %}
<a href="/bpobjecttype/{{ children.name }}">{{ children.name }}</a>
{% endfor %}
</dd>
</dl>
{% endif %}
{% endfor %}
</div>
</div>
<div class="menu_box">
{% for bpsubject in bpsubject_list %}
{% if bpsubject.level = 0 %}
<div class="menu_main">
<h2>{{ bpsubject.name }}</h2>
</div>
<div class="menu_sub dn">
{% elif bpsubject.level = 1 %}
<dl class="reset">
<dt><a href="/bpsubject/{{ bpsubject.name }}">{{ bpsubject.name }}</a></dt>
<dd>
{% for children in bpsubject.get_children %}
<a href="/bpsubject/{{ children.name }}">{{ children.name }}</a>
{% endfor %}
</dd>
</dl>
{% endif %}
{% endfor %}
</div>
</div>
</div>
Вышеупомянутые скрипты работают очень хорошо, однако я могу использовать только один тип фильтра за раз, чтобы получить соответствующие протоколы. Но я хочу сделать больше после того, как получу вышеуказанные результаты. Я хочу, чтобы следующая страница с ListView позволяла пользователям сузить свой выбор, например, только некоторые протоколы в этом типе объекта с некоторыми конкретными предметами. Таким образом, я хочу создать фильтры на основе каждой из этих трех категорий. Я добавляю еще три ListView в свой views.py, здесь я просто выбираю один из них (BPTechnoTypeBioprotocolList), чтобы представить проблему:
class BPTechnoTypeBioprotocolList(ListView):
template_name = 'bioprotocol_list.html'
def get_queryset(self):
self.technotype = get_object_or_404(BPTechnoType, name=self.args[0])
bptechnotype_list = Bioprotocol.objects.filter(TechnoType__lft__gte=self.technotype.lft, TechnoType__rght__lte=self.technotype.rght)
return bptechnotype_list
def get_context_data(self, **kwargs):
context = super(BPTechnoTypeBioprotocolList, self).get_context_data(**kwargs)
bpobjecttype_list = []
bptechnotype_list = []
bpsubject_list = []
for item in self.get_queryset():
bpobjecttype = BPObjectType.objects.filter(bioprotocol__id=item.id)
bpsubject = BPSubject.objects.filter(bioprotocol__id=item.id)
bptechnotype = BPTechnoType.objects.filter(bioprotocol__id=item.id)
bpobjecttype_list += bpobjecttype
bpsubject_list += bpsubject
bptechnotype_list += bptechnotype
objecttypecount = Counter(bpobjecttype_list).most_common()
technotypecount = Counter(bptechnotype_list).most_common()
subjectcount = Counter(bpsubject_list).most_common()
# Add in the subject
context['bpobjecttype_list'] = objecttypecount
context['bptechnotype_list'] = technotypecount
context['bpsubject_list'] = subjectcount
context['bptechnotype'] = self.technotype
return context
И в моем urls.py я добавляю:
url(r'^bptechnotype/([\w-]+)/$', BPTechnoTypeBioprotocolList.as_view()),
Шаблон bioprotocol_list.html:
<div class="sidebar">
<div id="options" class="greybg">
<dl>
<dt>
"Object Type"
</dt>
<dd>
{% for objecttype in bpobjecttype_list %}
<div class="option">
<label>
<input type="checkbox" checked="" value="">{{ objecttype.0 }}</label> ({{ objecttype.1 }})
</div>
{% endfor %}
</dd>
</dl>
<dl>
<dt>
"Technology Type"
</dt>
<dd>
{% for technotype in bptechnotype_list %}
<div class="option">
<label>
<input type="checkbox" checked="" value="">{{ technotype.0 }}</label> ({{ technotype.1 }})
</div>
{% endfor %}
</dd>
</dl>
<dl>
<dt>
"Subject"
</dt>
<dd>
{% for subject in bpsubject_list %}
<div class="option">
<label>
<input type="checkbox" checked="" value="">{{ subject.0 }}</label> ({{ subject.1 }})
</div>
{% endfor %}
</dd>
</dl>
<button type="button" id="selectall">Select All</button>
<button type="button" id="cancelall">Cancel</button>
<button type="button" id="applyfilter">Filter</button>
<script type="text/javascript">
$(document).ready(function(){
$("#selectall").click(function(){
$("input").prop('checked', true)
});
$("#cancelall").click(function(){
$("input").prop('checked',false)
});
$("#applyfilter").click(function(){
SHOULD DO SOMETHING AND SEND THE QUERYSET TO THE LISTVIEW
});
});
})
</script>
</div>
</div>
Основная идея состоит в том, чтобы применить функцию jQuery ($ ("# applyfilter"). Click (function () {}), чтобы просмотреть каждый ввод флажка, получить весь отмеченный фильтр и отправить запрос в ListView и изменить get_queryset ( )
Скрипты должны содержать повторяющиеся коды. Я с нетерпением жду каких-то лаконичных методов для создания динамического списка объектов с фильтрами этих трех категорий на одной странице. Любые идеи приветствуются. Большое тебе спасибо!
1 ответ
Я исправил сам, добавив коды в
function getvalue(){
var objectchk = [];
var technochk = [];
var subjectchk = [];
$("input[name='objecttype']:checked").each(function(){
objectchk.push($(this).val());
});
$("input[name='technotype']:checked").each(function(){
technochk.push($(this).val());
});
$("input[name='subject']:checked").each(function(){
subjectchk.push($(this).val());
});
var dict = {
'ObjectType':objectchk, 'TechnoType':technochk, 'Subject':subjectchk
};
var params = $.param(dict);
$.ajax({
type: "GET",
data: {'ObjectType':objectchk, 'TechnoType':technochk, 'Subject':subjectchk},
});
window.location = "?" + params
}
Похожие вопросы
Новые вопросы
jquery
jQuery — это библиотека JavaScript. Также рассмотрите возможность добавления тега JavaScript. jQuery — это популярная кросс-браузерная библиотека JavaScript, которая упрощает обход объектной модели документа (DOM), обработку событий, анимацию и взаимодействие AJAX, сводя к минимуму расхождения между браузерами. Вопрос с тегом jQuery должен быть связан с jQuery, поэтому jQuery должен использоваться рассматриваемым кодом, и в вопросе должны быть как минимум элементы, связанные с использованием jQuery.