質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.04%

【Django】views.pyにおいて、filterで絞り込んだクエリセットの合計値を算出したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 7,811

score 806

Djangoで工事台帳を作成しており、
工事ごとの請負金額を取りまとめる表を作成したいと考えています。

例えば、下記のように、当初、追加1、追加2を入力すると(Adminsiteで入力し、これはできています。)、計を計算して表示されるようにしたいです。
当初 10,000,000円
追加1 2,000,000円
追加2  1,000,000円
計  13,000,000円

model.pyは、下記の通りで問題ないと思います。
#models.py
# -*- coding: utf-8 -*-
from django.db import models
class ContractPrice(models.Model):
    site_id = models.ForeignKey(Site)    
    price = models.IntegerField(u'税込金額')
views.pyがうまくいっていないと思います。
#views.py
# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponse
from django.template import RequestContext
from cls.models import ContractPrice, Owner, Site

def site_detail(request, id):
    if id:
    site = get_object_or_404(Site, pk = id)
    else:
    id = Site()
    site = Site.objects.filter(id = id)
    prices = ContractPrice.objects.filter(site_id = id)
    totalsales = sum(prices.price)
    return render_to_response('cls/site_detail.html',
    {'site' : site, 'contractprice' : price, 'totalsales' : totalsales},
        context_instance = RequestContext(request)
    )
上記のように、
totalsales という変数に、請負金額の合計を代入するために、
totalsales = sum(prices.price)
としました。
pricesは、idで絞り込んだ要素を意味するので、そのpriceアトリビュートを合計すればよいと思ったためです。
しかし、
「AttributeError
'QuerySet' object has no attribute 'price'」
というエラーが出ます。
sumの使い方が誤っているのかと思い、外してみましたが、結果は同じでした。

ちなみに、annotateを使えば解決するのかと思い、
totalsales = prices.annotate(Sum('price'))
としてみましたが、
「NameError
global name 'Sum' is not defined」
というエラーが出ました。

私の考え方のどこかが誤っているのだと思いますが、お分かりの方、ご教示いただけないでしょうか。
お手数をお掛けしますが、よろしくお願いいたします。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

先ほどURLについて回答させていただいた者です。
また回答させていただきたいと思います。

今回のエラーは「QuerySetにはpriceという属性はありません」という事だと思います。
この「QuerySet」は簡単いうと「1つ1つのモデルインスタンス(データベースでいうレコードだと思ってください)をリストに格納したもの」だと思ってください。
「prices = ContractPrice.objects.filter(site_id = id)」という箇所で使用している「filter」メソッドがQuerySetを返すメソッドになります。

よって、そのまま変数pricesに「.price」と指定しても、リストに属性を指定しているようなものなので上記のエラーが発生したと思います。

修正箇所は以下のようになると思います。

totalsales = sum([p.price for p in prices])

for文を使用し、1つ1つモデルのインスタンスを取り出し、その属性であるpriceを格納したリストを元にsum関数で合計を出すようにすると大丈夫だと思います。

今回は少々説明が難しくになってしまい、わかりづらいかと思いますが、もし解決できなかった場合はまたコメントいただければと思います。

よろしくお願いいたします。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/06/28 19:27

    ありがとうございました。
    ご指摘頂いたとおりでうまくいきました。
    丁寧にご説明いただき助かりました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る