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

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

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

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

Python 3.x

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

Q&A

解決済

2回答

6943閲覧

Django 親モデルから子モデル(複数)のfieldを参考するには?(order_byとfilter)

yuki1010

総合スコア43

Django

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

Python 3.x

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

0グッド

1クリップ

投稿2017/06/29 02:56

いつもご回答誠にありがとうございます。
Djangoのモデルについて質問させて下さい。
Customerモデル(親:1)とReportモデル(子:多)があり、Customerモデルの一覧を作る際に、Order_by機能を使いソートしたいのですが、条件として子のReportのfieldにあるday(日時)の新しい日時を見て、各Customerモデルの並び順をして表示したいと思っているのですが、上手くいきません。

それとこれも、Customerモデルから一番新しいReportを参照してCustomerモデル側のfilter(Q)機能を使いたいと思っているのですが、これも上手くいきません。
どなたかご指南してくだされば、幸いです。

画像イメージです。
イメージ説明

親モデル(Customer)

python

1class Customer(TimeStampedModel): 2 """ 3 顧客情報 4 """ 5 name = models.CharField( 6 verbose_name="顧客名", max_length=30, blank=True) 7 post = models.CharField( 8 verbose_name="〒", max_length=8, blank=True) 9 add1 = models.CharField( 10 verbose_name="住所1", max_length=50, blank=True) 11 add2 = models.CharField( 12 verbose_name="住所2", max_length=50, blank=True) 13 tel = models.CharField( 14 verbose_name="TEL", max_length=15, blank=True) 15##中略 16 17 18 def __str__(self): 19 return self.name 20 21 def get_absolute_url(self, *args, **kwargs): 22 num = 0 23 if kwargs.get('num'): 24 num = int(kwargs.get('num')) 25 return reverse('customer:single', kwargs={'pk': self.pk, 'param': num})

子モデル(Report)

python

1from customer.models import Customer 2from django.contrib.auth.models import User 3 4##中略 5 6class Report(TimeStampedModel): 7 customer = models.ForeignKey( 8 Customer, on_delete=models.CASCADE, verbose_name="顧客", 9 related_name="report_customer", null=True, blank=True 10 ) 11 staff = models.ForeignKey( 12 User, on_delete=models.CASCADE, verbose_name="スタッフ", 13 related_name="customer_staff", null=True, blank=True) 14 15 rank = models.CharField( 16 choices=RANK_CHOICE, 17 verbose_name="ランク", max_length=2, blank=True) 18 19 day = models.DateField( 20 verbose_name="実行日時", blank=True, null=True) 21 22 report = models.TextField( 23 blank=True, verbose_name="日報") 24##中略 25 26 class Meta: 27 ordering = ['-day']

Customer側で検索フォームから条件を付けて一覧表示(cusmoter.views.py)

python

1from django.views.generic.list import ListView 2 3class CustomerIndextView(ListView): 4 template_name = 'customer/index.html' 5 model = Customer 6 form_class = CustomerSearchForm 7 8 def get_queryset(self, *args, **kwargs): 9 qs = super(CustomerIndextView, self).get_queryset( 10 *args, **kwargs).order_by('ここの部分の書き方がわまりません.') 11 12 if self.request.GET.get('staff'): 13 #サーチフォームからUser情報がくる 14 staff = self.request.GET.get('staff') 15 staff_obj = User.objects.get(pk=int(staff)) 16 17 #↓Q()のカッコの中身の書き方が分かりません.first()が使えるといいのですが、、、 18 qs = qs.filter(Q(report_customer__staff=staff_obj)).distinct() 19 20 return qs

余分なコード箇所を省いたため少しインデントがおかしくなっていますが、インデント自体に問題は無いと思います.どなたかご教授の方、よろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

条件として子のReportのfieldにあるday(日時)の新しい日時を見て、各Customerモデルの並び順を

して表示したいと思っているのですが、上手くいきません。

こちらは下記のようにするといけるはずです。

python

1from django.db.models import Max 2from django.views.generic.list import ListView 3 4class CustomerIndextView(ListView): 5 template_name = 'customer/index.html' 6 model = Customer 7 form_class = CustomerSearchForm 8 9 def get_queryset(self, *args, **kwargs): 10 qs = Customer.objects.annotate( 11 latest_day=Max('report_customer__day') 12 ).order_by('-latest_day') 13 return qs

Customerモデルから一番新しいReportを参照してCustomerモデル側のfilter(Q)機能を使いたいと思っているのですが、これも上手くいきません。

こちらはイマイチどういった処理をされたいのかがわかりません。

投稿2017/06/29 11:17

toritoritorina

総合スコア972

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

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

yuki1010

2017/07/03 07:40

ご回答ありがとうございます。実際にコードを書き確認したら出来ていました!ありがとうございます。 ただfilter機能を使う際に、どうしても上手くいかなかったので、不本意ながら親モデル(Customer)に子モデル(Report)の最新のフィールドが入るものを幾つか設置して、この問題を回避しました。
guest

0

自己解決

並び順は、アドバイスいただいたコードで上手くいきました。
ただfilter機能を使う際に、どうしても上手くいかなかったので、不本意ながら親モデル(Customer)に子モデル(Report)の最新のフィールドが入るものを幾つか設置して、この問題を回避しました。

・親クラス(Customer)に、子クラス(Report)の最新の日時(day)が、入れれるフィールド(latest_day)を追加
・子クラスのmodels.pyに、post_saveを使い、子クラス(Report)がSaveされた後のタイミングで、その紐付いた親クラスの子クラス一覧の中から最新の日時(day)を選び、その情報を親クラスのlatest_dayに追加

投稿2017/07/03 07:51

yuki1010

総合スコア43

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問