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 と ServiceType はいつでも追加できます)。*検索フォームを使用する人が複数の 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'] の場合、これらは CheckBox であることを意味していると思います。

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 など) を行っていないため、なぜ Q オブジェクトを使用しているのかわかりません。

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 に答える