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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

7582閲覧

modelで定義したメソッドを呼び出したい

shohei0718

総合スコア17

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/02/03 09:12

編集2019/02/03 09:14

###開発環境
Python 3.7.1
Django version 2.1.5

困っていること

models.pyに集計ロジックの関数を記述し、views.pyでその関数を呼び出すことで、データの集計作業をしたいと考えています。
しかし、models.pyで集計ロジックを定義したインスタンスメソッド(def total_price(self))をviews.pyで呼び出すとエラーが出てしまい、困っています。
何か良い方法があれば、ご教授頂けますと幸いです。

###出ているエラー内容
TypeError at /invoice_index
unsupported operand type(s) for +: 'function' and 'int'

Lovcal Vars
...
english_invoice <function BillingPriceCalculator.total_price at 0x1076cdd90>

コード

model

1class Lesson(models.Model): 2 name = models.CharField('ジャンル', max_length=255) 3 flat_price = models.PositiveIntegerField('基本料金', null=False, default=0) 4 5 def __str__(self): 6 return self.name 7 8 def calculate_measured_price(lesson_hour): 9 lesson_measured_price = LessonMeasuredPrice.objects.select(record, record.lesson_hour <= lesson_hour ).sort_by(lesson_hours).last 10 lesson_measured_price.price 11 12class LessonMeasuredPrice(models.Model): 13 lesson_id = models.ForeignKey(Lesson, on_delete=models.PROTECT) 14 price = models.PositiveIntegerField('金額', null=False, default=0) 15 threshold_hours = models.PositiveIntegerField('受講時間(h)', null=False, default=0) 16 17 18class CustomerLesson(models.Model): 19 customer = models.ForeignKey(Customer, verbose_name='顧客名', on_delete=models.PROTECT) 20 lesson = models.ForeignKey(Lesson,verbose_name='ジャンル', on_delete=models.PROTECT) 21 22 lesson_date = models.DateField('受講日') 23 lesson_hour = models.PositiveIntegerField( 24 '受講時間(h)', 25 default = 1, 26 validators=[ 27 MaxValueValidator(12), 28 MinValueValidator(1) 29 ] 30 ) 31 32 def __str__(self): 33 return self.lesson 34 35class BillingPriceCalculator: 36 37 def __init__(self, lesson, customer_lessons): 38 self.lesson = lesson 39 self.customer_lessons = customer_lessons 40 41 @staticmethod 42 def total_price(self): 43 flat_price + measured_price 44 45 46 def __flat_price(self): 47 lesson.flat_price 48 49 def __measured_price(self): 50 measured_price_unit * total_hours 51 52 def __total_hours(self): 53 customer_lessons.sum(lesson_hour) 54 55 def __measured_price_unit(self): 56 lesson.calculate_measured_price(total_hours)

views

1def invoice_index(request): 2 3 today = datetime.today() 4 5 #今月の月初日と月末日の算出 6 month_start = today.replace(day=1) 7 next_month_start = (today + relativedelta(months=1)).replace(day=1) 8 month_end = next_month_start - timedelta(days=1) 9 10 customers = Customer.objects.all() 11 sum_template = {'英語': 0, 'ファイナンス': 0, 'プログラミング': 0} 12 invoice_list = [] 13 14 for customer in customers: 15 columns = {} 16 english_invoice = 0 17 finance_invoice = 0 18 programing_invoice = 0 19 20 genre_sum = sum_template.copy() 21 lesson_hour_sum = sum_template.copy() 22 23 lessons = customer.customerlesson_set.all() 24 this_month_lessons = lessons.filter(lesson_date__range=(month_start, month_end)) 25 lesson_sum = this_month_lessons.count() 26 27 columns['id'] = customer.id 28 columns['name'] = customer.name 29 columns['lesson'] = lesson_sum 30 31 for lesson in this_month_lessons: 32 lesson_date = lesson.lesson_date 33 columns['lesson_date'] = lesson_date 34 35 genre = lesson.lesson.name 36 genre_sum[genre] += 1 37 columns['genre'] = genre_sum 38 39 lesson_hour = lesson.lesson_hour 40 lesson_hour_sum[genre] += lesson_hour 41 columns['lesson_hour'] = lesson_hour_sum 42 43 if genre == '英語': 44 english_invoice = BillingPriceCalculator(genre, this_month_lessons).total_price 45

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

total_priceをstaticmethodにするならselfを引数に取ってはいけませんし、インスタンスメソッドならstaticmethodデコレータを付けてはいけません。

english_invoice = BillingPriceCalculator(genre, this_month_lessons).total_pricetotal_priceを呼び出していないので、メソッドオブジェクトがenglish_invoice変数に代入されるだけです。呼び出したければ後ろにかっこをつけます。

total_priceを呼び出したとしてもreturn文がありませんので、Noneが返り無意味というか動きません。

ほかにもdjango以前におかしい気がする部分は多数あるので、pythonの基礎をやるのが先という感じがします。rubyに慣れている人かもしれませんが、文法違うので。

投稿2019/02/03 09:21

編集2019/02/03 09:24
hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shohei0718

2019/02/03 09:51

hayataka2049さん total_priceを呼び出すことができました。 まだPythonの学習を始めたばかりなので、改めて基礎文法から勉強し直します。
guest

0

関数の戻り値は、明示的にreturnで返す必要があります。

投稿2019/02/03 09:16

Meganezaru

総合スコア715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shohei0718

2019/02/03 09:50

Meganezaruさん有難うございます。 返り値がNoneではありましたが、returnで返ってきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問