2013-08-07 43 views
0

我想過濾Django中的一個對象,並將其與任何結果爲ForeignKey的對象一起返回。我不確定註釋是否是我需要的,或其他。用foreignkey註釋結果

這是我的模型:

class Dress(models.Model): 
    name = models.CharField(...) 
    price = models.FloatField(...) 

class ClothingSize(models.Model): 
    code = models.CharField(...) 

class DressSizeAvailable(models.Model): 
    dress = models.ForeignKey(Dress) 
    size = models.ForeignKey(ClothingSize) 

說我要過濾所有的禮服在50 $,然後與現有的尺寸顯示。做這個的最好方式是什麼?

我得儘可能的:

# In view 
results = Dress.objects.filter(price__lt=50) 
# How to annotate with available sizes? 

# In template 
{% for result in results %} 
    {{ result.name }}, ${{ result.price }} 
    Sizes: {{ ??? }} 
{% endfor %} 

回答

1
### 1st solution (similar to Daniel Rosenthal's answer but with performances concern) 
results = DressSizeAvailable.objects.filter(dress__price__lt=50).select_related('dress', 'size') 
# then you can browse your DressSizeAvailables as you wish in your template. The select related allows you NOT TO query the database again when you generate your template 

### 2nd solution 
results = Dress.objects.filter(price__lt=50).prefetch_related('dresssizeavailable_set__dress') 

{% for dress in results %} 
    {{ dress.name }}, ${{ dress }} 
    Sizes: <ul> 
     {% for dsa in dress.dresssizeavailable_set %} 
      <!-- Thanks to the prefetch_related, we do not query the base again here --> 
      <li>{{ dsa.size.code }}</li> 
     {% endfor %} 
    </ul> 
{% endfor %} 
+0

謝謝!我只需要在'{%for dsa in dress.dresssizeavailable_set.all%}'末尾加上'all'就可以工作。 – Richard

0

你需要給你的模板查詢集(或類似的東西)DressSizeAvailable對象。因此,首先你需要把所有的Dress對象你有興趣,然後根據這些禮服

所以在您的視圖篩選DressSizeAvailable

dresses = Dress.objects.filter(price__lt=50) 
dress_size_available = [] 
for dress in dresses: 
    available = DressSizeAvailable.objects.filter(dress=dress) 
    dress_size_available.append(available) 

然後渲染你的模板,它傳遞變量dress_size_available

您的模板可以很簡單。

{% for dsa in dress_size_available %} 
    {{ dsa.dress.name }}, ${{ dsa.dress.price }} 
    Size: {{ dsa.size }} 
{% endfor %} 
+0

__in views.py:__在第1行一個DB查詢,anothor對於每次迭代=> N + 1 DB查詢。 __在template.html:__ 3查詢for循環的每個迭代=> 3N DB查詢。 __Total:__ 1 + 4N查詢您的數據庫!我猜你的數據庫與你的應用服務器在同一主機上,否則你的演出將會很差:) – Ricola3D

+0

是的,我要問 - 是不是迭代查詢集效率低下? – Richard

+0

爲了在迭代查詢集時高效,請確保爲直接外鍵添加__select_related()__,爲反向外鍵和m2m關係添加__prefetch_related()__。在這裏查看他們的文檔:https://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related。每當你從一個查詢集的對象中調用「。」時,如果你沒有使用這兩個函數將它們包含在查詢集中,那麼Django將爲它們重新獲取數據庫。 – Ricola3D