我需要帮助提出一种基于M2M字段对一组对象进行搜索查询的有效方法。我的搜索表格看起来像Blue Cross Blue Shield的|例如:this image
现在,让我们假设我的模型如下:
# models.py
class Provider(models.Model)
title = models.CharField(max_length=150)
phone = PhoneNumberField()
services_offered = models.ManyToManyField(ServiceType)
def __unicode__(self):
return self.title
class ServiceCategory(models.Model):
service_category = models.CharField(max_length=30)
def __unicode__(self):
return self.service_category
class Meta(object):
verbose_name_plural = "Service Categories"
class ServiceType(models.Model):
service_type = models.CharField(max_length=30)
service_category = models.ForeignKey(ServiceCategory)
def __unicode__(self):
return u'%s | %s' % (self.service_category, self.service_type
此外,我们必须记住,我们选择的选项可能会发生变化,因为它们在表单上的显示方式是动态的(可以随时添加新的ServiceCategories和ServiceTypes)。 *如果使用搜索表单的人可以选择多个Services_Offered,我应该如何构建Provider对象的查询?*
这是我目前非常缺乏的方法:
#managers.py
from health.providers.models import *
from django.db.models import Q
class Query:
def __init__(self):
self.provider_objects=Provider.objects.all()
self.provider_object=Provider.objects
self.service_object=ServiceType.objects
self.category_objects=ServiceCategory.objects.all()
def simple_search_Q(self, **kwargs): #matt's learning note: **kwargs passes any dictionary
return self.provider_objects.filter(
Q(services_offered__service_type__icontains=kwargs['service']),
Q(title__icontains=kwargs['title']),
Q(state=kwargs['state']),
).distinct().order_by('title')
====================
#views.py
from django.shortcuts import render_to_response
from health.providers.models import *
from health.search.forms import *
from health.search.managers import Query #location of the query sets
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.template import RequestContext
def simple_search(request):
if request.method == 'POST':
SimpleSearch_form = SimpleSearch(request.POST)
if SimpleSearch_form.is_valid():
request.session["provider_list"] = None
kwargs = {'title': request.POST['title'],
'service': request.POST['service'], 'state': request.POST['state'] }
provider_list = Query().simple_search_Q(**kwargs)
return pagination_results(request, provider_list)
else:
SimpleSearch_form = SimpleSearch()
return render_to_response('../templates/index.html', { 'SimpleSearch_form': SimpleSearch_form},
context_instance=RequestContext(request))
如何查询:
根据选择多个request.POST ['service']
效率更高
感谢先进的任何帮助。
最诚挚的问候, 马特
答案 0 :(得分:1)
1:对于多个request.POST ['service'],我认为你的意思是这些是CheckBoxes。
我将CheckBox值设为ID,而不是名称,并进行PK查找。
'services_offered__pk__in': request.POST.getlist('service')
这将返回所有已选择所有服务的Provider
个对象。
PS:您也使用CapitalCase进行非常混乱的实例。如果您希望您的代码可读,我强烈建议您对样式进行一些更改(不要将CapitalCase用于实例或变量)并使您的变量更具描述性。
SimpleSearch_form = SimpleSearch() # what is SimpleSearch?
simplesearch_form = SimpleSearchForm() # now, it's very clear what the class SimpleSearchForm is
# and the form instance is clearly a for instance.
2:提高效率?通过删除整个Query
类,您可以摆脱大量代码和代码分离。另外,我不知道你为什么使用Q对象,因为你没有做任何需要它的东西(比如OR或OR + AND)。
def simple_search(request):
if request.method == 'POST':
searchform = SimpleSearchForm(request.POST)
if searchform.is_valid():
request.session['provider_list'] = None
post = request.POST
providers = Provider.objects.filter(services_offered__pk__in=post.getlist('services'),
title=post['title'], state=post['state'])
return pagination_results(request, provider_list)
else:
searchform = SimpleSearchForm()
return direct_to_template(request, '../templates/index.html', { 'searchform': searchform})