0

私は次のような model.pyを持っています:

class Muestraonline(models.Model):
    accessionnumber = models.ForeignKey(Muestra, related_name='online_accessionnumber')
    muestraid = models.ForeignKey(Muestra)
    taxonid = models.ForeignKey(Taxon, null=True, blank=True)
    collectedby = models.ForeignKey(Person, null=True, blank=True)
    locality = models.ForeignKey(Localitymayor, null=True, blank=True)

私のviews.pyで:

def search(request):
    ...
        if genus:
           q &= Q(taxonid__genus__icontains = genus)
        if species:
           q &= (Q(taxonid__specificepithet__icontains = species | Q(taxonid__infraspecificepithet__icontains = species ))) 
        if island_group:
           q &= Q(locality__islandgroup__icontains = island_group)
        if island_name:
           q &= Q(locality__islandname__icontains = island_name)
        if collection_acronym:
           q &= Q(muestraid__collectionid__collectioncode__icontains = collection_acronym)
        if accession_number:
           q &= Q(muestraid__accessionnumber = accession_number)
        if last_name:
           q &= Q(collectedby__verbatimname__icontains = last_name)
        if collection_number:
           q &= Q(muestraid__collectionnumber = collection_number)

        query_set = Muestraonline.objects.filter(q).order_by('taxonid__genus', 'taxonid__specificepithet', 'muestraid') 

        query_set = list(query_set) 

私のテンプレートでは、次のようにします。

{% for specimen in items.object_list %}
 {{ specimen.taxonid.genus }} -- {{ specimen.taxonid.specificepithet }}
 {{ specimen.muestraid_id }}
 {{ specimen.accessionnumber_id }}
 {{ specimen.muestraid.localitymayorid.islandname }}
{% endfor %}

django デバッグ ツールバーを使用して結果を見ると、最初の検索クエリが db でかなり重いことがわかりますが、構造 (変更されない) を考えると避けられないと思います。ただし、テンプレートを反復処理すると、各オブジェクトもクエリを作成してデータを取得しtaxonますlocality

を使用するとこれを回避できると思いましたselect_related()が、実際には (最初のクエリに多数の結合を追加することで) リクエストが遅くなり、クエリの総数は変わりません。

私の質問は、データベースへのヒットを最小限に抑えるにはどうすればよいですか? たとえば、一度評価するようにクエリ セットを取得し、テンプレートでの反復中にこれから結果を取得することはできますか? ご覧のとおりquery_set、リストとしてキャストしようとしましたが、違いはありません。

ここでのガイダンスは大歓迎です。

4

1 に答える 1

1

select_related従うべき正確な関係を伝えてみることをお勧めします。追加select_relatedによってクエリが非常に遅くなったという事実は、不要な関係をたどっていたことが原因である可能性があります。次のことを試してください。

query_set = Muestraonline.objects.filter(q).order_by('taxonid__genus', 'taxonid__specificepithet', 'muestraid').select_related('taxonid', 'muestraid__localitymayorid')

クエリに追加した後も、各インスタンスのデータベースにヒットしているとは信じがたいselect_relatedです。正しいクエリセットを評価していると確信していますか?

また、ページネーターにフィードする前に QuerySet をリストに変換することは、最良のアイデアではありません。データベースからすべてを取得し、小さなサブセットのみを表示しているため、そのほとんどを破棄することになります。QuerySet を paginator に直接フィードすると、QuerySet 自体が必要なアイテムのみをフェッチするように制限されます。

于 2012-04-22T17:07:01.147 に答える