🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Django

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

Python 3.x

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

861閲覧

django-rest-frameworkでgroup_byしたい

jomaboy

総合スコア4

Django

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

Python 3.x

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/11/05 13:06

django-rest-frameworkを使ってリクエストパラメーターで駅テーブルのnameカラムを取得して、それに部分一致した駅名のリストをjsonで返したいです。
部分一致した駅名のリストは返せたのですが、同じ値が出力されており、(駅名を改札口の数の分insertしたので)これをgroup_byやらdistinctやらでnameごとにグループ化したいのですが、どう書けばわからない状況です
なのでその書き方を教えていただきたいです。よろしくお願い申し上げます。

station_api.py

from ..models import station from ..serializers import stationSerializer from django.shortcuts import render from rest_framework import generics from rest_framework.response import Response from ..models import station class stationList(generics.ListCreateAPIView): queryset = station.objects.all() serializer_class = stationSerializer def get_queryset(self): queryset = station.objects.all() name = self.request.query_params.get('name', None) if name is not None: queryset = queryset.filter(name__icontains=name) return queryset

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

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

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

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

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

nerianighthawk

2019/11/06 00:20

出来ていることとやりたいことをもう少し詳しくお聞きしたいのですが、 今出来ているものだと「原」で部分一致をかけて ["原宿", "原宿", "秋葉原", "秋葉原", "秋葉原", …] のように改札の数分出てしまうと言ったイメージでいいですか? そしてそれを1つずつにするもしくは2重のリストにしたいということでしょうか?
jomaboy

2019/11/06 01:00 編集

そうです! なので["原宿", "秋葉原"]のように1つずつにしたいです! お手数ですが、よろしくお願いします
guest

回答2

0

上記やり方ではquerysetで取得しているものはモデルのため、setのコンストラクタでは一致判定してくれませんでした。忘れてください。
querysetでdistinct関数を使うことで重複削除できるようです。
実際に書くと以下のようになるかと思います。

def get_queryset(self): queryset = station.objects.all() name = self.request.query_params.get('name', None) if name is not None: queryset = queryset.filter(name__icontains=name).distinct('name') return queryset

このように書くことでnameが一致しているモデルは重複削除して返してくれるかと思います。

投稿2019/11/06 08:31

nerianighthawk

総合スコア544

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

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

jomaboy

2019/11/06 08:39

やってみたのですが、 'stationSerializer' object is not callableというエラーが出ました、、、
jomaboy

2019/11/06 08:40

``` def get_queryset(self): queryset = station.objects.all() name = self.request.query_params.get('name', None) if name is not None: queryset = queryset.filter(name__icontains=name).distinct('name') return queryset ```
nerianighthawk

2019/11/06 11:39

私の環境で試そうとしたところ、DBが対応していないと言われました。 どうやら distinct の引数に入れて distinct on として使えるのは Postgres だけのようです。 全く同じではないですが、ちょっと似たような物を作成して、私の環境で検証したところ ``` queryset = queryset.filter(name__icontains=name).values('name').distinct() ``` でできましたが、どうですか? エラー内容が私と違うので、もしかしたら別の要因かもしれませんが…
nerianighthawk

2019/11/06 11:40

紛らわしい書き方をした気がするので、補足ですが、`distinct`は引数無しであれば Postgres ではなくても扱えます。
jomaboy

2019/11/06 23:33

変わらず、同じエラーがでました、、、 お手数おかけしてすみません、、
nerianighthawk

2019/11/06 23:58

こちらこそ、ちゃんと解決出来ずすみません。 エラーは何行目で出た等わかりますか?
jomaboy

2019/11/07 08:19

get_querysetメソッドを消しても同じエラー出ちゃいました、、 どこもいじったつもりはないのですが、、 stationSerializerはちゃんと定義してあるしimportもしているのですが、、
nerianighthawk

2019/11/08 00:35

エラーメッセージの上に行数とか書いてないですか? ``` Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'stationSerializer' object is not callable ``` こんな感じじゃないですか?
jomaboy

2019/11/08 06:47

書いてないです、、、 Internal Server Error: /api/v1/station_api/station_list/ Traceback (most recent call last): File "/Users/imaijoma/.local/share/virtualenvs/nomad-cafe-backend-ZlR-gHYT/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner response = get_response(request) File "/Users/imaijoma/.local/share/virtualenvs/nomad-cafe-backend-ZlR-gHYT/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response response = self.process_exception_by_middleware(e, request) File "/Users/imaijoma/.local/share/virtualenvs/nomad-cafe-backend-ZlR-gHYT/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/Users/imaijoma/.local/share/virtualenvs/nomad-cafe-backend-ZlR-gHYT/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view return view_func(*args, **kwargs) File "/Users/imaijoma/.local/share/virtualenvs/nomad-cafe-backend-ZlR-gHYT/lib/python3.7/site-packages/django/views/generic/base.py", line 71, in view return self.dispatch(request, *args, **kwargs) File "/Users/imaijoma/.local/share/virtualenvs/nomad-cafe-backend-ZlR-gHYT/lib/python3.7/site-packages/rest_framework/views.py", line 505, in dispatch response = self.handle_exception(exc) File "/Users/imaijoma/.local/share/virtualenvs/nomad-cafe-backend-ZlR-gHYT/lib/python3.7/site-packages/rest_framework/views.py", line 465, in handle_exception self.raise_uncaught_exception(exc) File "/Users/imaijoma/.local/share/virtualenvs/nomad-cafe-backend-ZlR-gHYT/lib/python3.7/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception raise exc File "/Users/imaijoma/.local/share/virtualenvs/nomad-cafe-backend-ZlR-gHYT/lib/python3.7/site-packages/rest_framework/views.py", line 502, in dispatch response = handler(request, *args, **kwargs) File "/Users/imaijoma/.local/share/virtualenvs/nomad-cafe-backend-ZlR-gHYT/lib/python3.7/site-packages/rest_framework/generics.py", line 239, in get return self.list(request, *args, **kwargs) File "/Users/imaijoma/.local/share/virtualenvs/nomad-cafe-backend-ZlR-gHYT/lib/python3.7/site-packages/rest_framework/mixins.py", line 45, in list serializer = self.get_serializer(queryset, many=True) File "/Users/imaijoma/.local/share/virtualenvs/nomad-cafe-backend-ZlR-gHYT/lib/python3.7/site-packages/rest_framework/generics.py", line 110, in get_serializer return serializer_class(*args, **kwargs) TypeError: 'stationSerializer' object is not callable
nerianighthawk

2019/11/08 07:25

generics.py の 110行目ですね。 ``` return serializer_class(*args, **kwargs) ``` という記載がダメだと書いてありますが… serializer_class っていうのは stationSerializer クラスのインスタンスですかね? インスタンスに引数を渡すことは出来なさそうな気がします。
jomaboy

2019/11/08 08:23

generics.pyというファイルを作成していないのですがデフォルトで入っているのでしょうか?
guest

0

Djangoのクエリセットでやるやり方もあるかもしれませんが、Pythonのリスト処理でできるので、その方法を記載します。
Pythonにはsetというデータ構造が存在します。
このデータ構造は重複を許さないリストのような構造になっています。
したがって、listsetのコンストラクタに入れると重複する要素を消したsetが取得できます。
さらにそれをlistのコンストラクタに入れることで、重複要素の無いlistを生成できます。

Python

1l = ["原宿", "原宿", "秋葉原", "秋葉原", "秋葉原"] 2 3print(set(l)) 4# {"原宿", "秋葉原"} 5 6print(list(set(l))) 7# ["原宿", "秋葉原"]

投稿2019/11/06 01:03

nerianighthawk

総合スコア544

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

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

jomaboy

2019/11/06 01:13 編集

このようにやってみたのですが、なにも変わりませんでした。どのように書けばいいのでしょうか? ``` def get_queryset(self): queryset = station.objects.all() name = self.request.query_params.get('name', None) if name is not None: queryset = queryset.filter(name__icontains=name) return list(set(queryset)) ```
nerianighthawk

2019/11/06 01:20

`queryset = queryset.filter(name__icontains=name)` この記載だとクエリセットになってしまっていて、リストになっていないような気がします。 Djangoは関数がreturnで返すタイミングでクエリセットのものは勝手にリスト化してくれますが、それはあくまでクエリセットなので、setのコンストラクタに入れてもリストだと判定してくれません。 `queryset = queryset.filter(name__icontains=name).all()` とすることで、queryset にリストが入ると思うので(変数名は変えた方がいいかもしれません)、出来ると思うのですが…(これで出来ない場合はバージョン等での仕様の違いが発生しているかもしれません)
jomaboy

2019/11/06 01:42

.all()をつけて変数名も変えてみたのですが、変化なしです、、、
nerianighthawk

2019/11/06 02:17

そうですか… print を使って、queryset の出力を教えていただくことは可能ですか?
jomaboy

2019/11/06 02:31

こんな感じです! <QuerySet [<station: 新宿>, <station: 新宿>, <station: 新宿>, <station: 新宿>, <station: 新宿>, <station: 新宿>, <station: 新宿>, <station: 新宿>, <station: 新宿三丁目>, <station: 新宿御苑前>, <station: 西新宿>, <station: 西新宿五丁目>]> <QuerySet [<station: 新宿>, <station: 新宿>, <station: 新宿>, <station: 新宿>, <station: 新宿>, <station: 新宿>, <station: 新宿>, <station: 新宿>, <station: 新宿三丁目>, <station: 新宿御苑前>, <station: 西新宿>, <station: 西新宿五丁目>]>
nerianighthawk

2019/11/06 08:27

すみません、querysetから取得できるのはモデルなので、setのコンストラクタでは一致判定してくれませんでした。 querysetでやるやり方を見つけたので、新しく解答を書きますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問