2016-10-06 9 views
0

私はこの問題を抱えています:私は2つのモデル、製品とカテゴリを持っています。カテゴリはフィクスチャで定義されています(変更されません)。 1つのテンプレート内のカテゴリをグリッドとして表示します。モデルはかなりシンプルですが、重要なのは、製品にカテゴリ・モデルを指す外部キーと、ユーザー・モデル(所有者)を指す別のキーがあることです。Django:外来キーで辞書内のオブジェクトを整理する

私は(CSSは、私はちょうどそれらを起動できるようにする必要があり、重要ではありません)が、私がこれまで持っているソリューションは、この

ビューある各カテゴリのブロック内のすべての製品を表示する必要が

def index(request): 
    user_products = [] 
    if request.user.is_authenticated(): 
     user_products = Product.objects.filter(owner=request.user) 
    categories = Category.objects.all() 
    return render(request, 'index.html', {'user_products': user_products, 'categories': categories}) 

テンプレート私は、コンテキスト何かリクに送信したい

<!-- This goes for each category, 12 in total --> 
<div> 
    <h3>Category (name hardcoded)</h3> 
    {% for category in categories %} 
     {% if category.pk == 3 %} 
      <ul class="product_list"> 
      {% for product in category.product_set.all %} 
       {% if product.owner == request.user %} 
       <li> 
        <div class="product"> 
         <h2 class="title">{{ product.title }} </h2> 
         <p class="text">{{ product.text }}</p> 
        </div> 
       </li> 
       {% endif %} 
      {% empty %} 
      {% endfor %} 
      </ul> 
     {% endif %} 
    {% endfor %} 
</div> 

E:

user_products = {<category.pk>: [list of Product objects in category]} 

はので、私は毎回からrequest.userによってそれらをフィルタリングのループを定義することなく、各カテゴリの製品リストにアクセスすることができます。あなたはこれを行うためのよりよい方法を考えることができますか?彼らは特定の順序を持​​っているので、私は各カテゴリをハードコードしなければならなかったが、その順序を維持しながらそれらを動的に表示する方法を知っていれば、それは素晴らしいだろう。ありがとう!

答えて

2

これを行うより良い方法があります。 Prefetchオブジェクトを使用してください。プリフェッチには、各カテゴリのデータのみがフィルタリングされます。

from django.db.models.query import Prefetch 

def index(request): 
    user_products = [] 
    if request.user.is_authenticated(): 
     user_products = Product.objects.filter(owner=request.user) 
    else: 
     # answering comment 
     user_products = Product.objects.none() 
    prefetch = Prefetch('product_set', queryset=user_products) 
    categories = Category.objects.all().prefetch_related(prefetch) 

    return render(request, 'index.html', {'categories': categories}) 

そしてテンプレート

<!-- You need to do this only once. No need to copy this for each category --> 
<div> 
    {% for category in categories %} 
    <h3>Category {{ category.name }}</h3> 
     <ul class="product_list"> 
     {% for product in category.product_set.all %} 
      <li> 
       <div class="product"> 
        <h2 class="title">{{ product.title }} </h2> 
        <p class="text">{{ product.text }}</p> 
       </div> 
      </li> 
     {% endfor %} 
     </ul> 
    {% endfor %} 
</div> 
+0

ニースでこれを行うことができます!ハードコードされたHTMLは、カテゴリに特定の順序を付ける必要があるためですが、モデルに何かを追加することができます。ユーザーが認証されていない場合はカテゴリを表示したいが、製品は表示したくないのですが、どのようにプリフェッチを使用すればいいですか? –

+0

@JuliánBonillaは 'Product.objects.none()'をやってみてください。更新された回答を参照 –

+0

私は多くのコードを改善しました、ありがとう! –

関連する問題