0

どのサイトにどの商品が表示されているかを簡単に管理したいのですが、商品が多いので、カテゴリー、生産者、タグで商品サイトも設定したいと考えています。したがって、製品または (そのカテゴリとその生産者とそのタグの 1 つ) がサイトにリンクされている場合、その製品をサイトに表示します。私が最終的に得たコードは次のとおりです(簡略化):

from django.db.models import Model, ManyToManyField, ForeignKey, BooleanField

class Site(Model):
    enabled = BooleanField()

class Producer(Model):
    sites = ManyToManyField(Site)

class Category(Model):
    sites = ManyToManyField(Site)

class Tag(Model):
    sites = ManyToManyField(Site)

class Product(Model):
    producer = ForeignKey(Producer)
    category = ForeignKey(Category)
    tags     = ManyToManyField(Tag)
    sites    = ManyToManyField(Site)

    def get_site_ids(self):
        if self.sites.exists():
            return list(self.sites.values_list('id', flat=True))
        else:
            p = list(self.producer.sites.values_list('id', flat=True))
            c = list(self.category.sites.values_list('id', flat=True))
            t = sum([list(tag.sites.values_list('id', flat=True)) for tag in self.tags.all()], [])
            ids = set.intersection(set(p), set(c), set(t))
            return ids

私の質問は、方法を最適化するにはどうすればよいget_sitesですか? 一部のクエリに参加することは可能ですか?


更新: 検索エンジンによってインデックスが作成され、保存されるサイト ID だけに興味があります。

4

2 に答える 2

1

可能であれば、データベース レベルでやりたいことをすべて試してみてください。このような何かがあなたを始めさせるはずです。

from django.db.models import Sum
self.objects.select_related("producer__sites",
                            "category__sites",
                            "tags__sites",
                            "sites").annotate(tag_count=Sum("tags__sites__id"))

select_relatedProductプロデューサー、カテゴリ、タグ、およびサイト参照が入力されたモデルを返します。これには、sitesプロデューサー、カテゴリー、およびタグの参照も含まれます。これにより、Django はデータベースへのクエリを減らすことができます。

annotateModel返されたインスタンス namedに属性を追加します。このインスタンスtag_countには、tags_ sites _id の合計が含まれています。

Django QuerySet Referenceは、あなたが返したいものの正確な性質がわからないため、良い助けになるかもしれません。

于 2012-10-01T16:51:48.613 に答える
1

select_relatedはい、および/またはを使用して、Django でクエリの数を減らすことができますprefetch_related

ただし、 はselect_related外部キーと 1 対 1 の関係に対してのみ機能します。Product モデルに ManyToMany があるprefetch_relatedため、Product.get_sites() でクエリを減らすために使用する必要があります。

于 2012-10-01T17:13:23.240 に答える