1

我需要帮助想出一种基于 M2M 字段对一组对象进行搜索查询的有效方法。我的搜索表单将类似于 Blue Cross Blue Shield 的 | 例如:这张图片

现在,假设我的模型如下所示:

# 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))

如何进行查询:

  1. 根据选择多个request.POST['service']获取Provider对象

  2. 更高效

感谢您在高级方面的任何帮助。

最好的问候,马特

4

1 回答 1

1

1:对于多个 request.POST['service'],我假设您的意思是这些是 CheckBoxes。

我会制作 CheckBox 值 ID,而不是名称,并进行 PK 查找。

'services_offered__pk__in': request.POST.getlist('service') 这将返回Provider选择了所有服务的所有对象。

PS:您也在使用 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})
于 2010-12-23T20:03:00.870 回答