Django: как сделать запрос для объекта на основе поля M2M (несколько вариантов выбора для поля в форме поиска) - PullRequest
1 голос
/ 23 декабря 2010

Мне нужна помощь в поиске эффективного способа выполнения поискового запроса для набора объектов на основе поля M2M.Моя поисковая форма будет выглядеть примерно как Blue Cross Blue Shield's |Например: это изображение

Теперь предположим, что моя модель выглядит следующим образом:

# 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? *

В настоящее время это мой крайне неэффективный метод:

#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. Получение объектов провайдера на основе выбора нескольких запросов.POST ['service']

  2. Более эффективный

Спасибо за любую помощь в продвинутом.

С наилучшими пожеланиями, Мэтт

1 Ответ

1 голос
/ 23 декабря 2010

1: для множественного запроса. POST ['service'], я полагаю, вы имеете в виду, что это CheckBoxes.

Я бы сделал идентификаторы значений CheckBox, а не имена, и выполнил бы поиск по 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})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...