| この記事の要点 |
|
エラー内容
get() returned more than one MynumberRegist -- it returned 2!
「MynumberRegist」の部分にはモデル名、「2」の部分には見つかった件数が入ります。例外クラスは MynumberRegist.MultipleObjectsReturned(共通の親は django.core.exceptions.MultipleObjectsReturned)です。件数が多い場合は「it returned more than 20!」のように上限付きで表示されます。
発生条件と原因
以下のように get を使用して、条件に合うレコードが複数存在すると発生するエラーです。
Users.objects.get(...)
get は「条件に合うレコードがちょうど 1 件」であることを前提にしたメソッドです。0 件でも 2 件以上でも例外になります。
| 該当件数 | get() の結果 |
|---|---|
| 0 件 | Model.DoesNotExist 例外 |
| 1 件 | そのモデルインスタンスを返す |
| 2 件以上 | Model.MultipleObjectsReturned 例外(このエラー) |
よくある原因は次の 2 つです。
- 条件が一意になっていない: 名前やメールアドレス、外部キーなど、重複しうる項目だけで get している
- 本来 1 件のはずのデータが重複している: DB にユニーク制約が無く、二重送信や同時実行で同じデータが 2 回登録された
対処法
1. 主キーやユニークキーで 1 件に絞る
get は主キー(pk)やユニーク制約のある項目を条件にして、1 レコードに絞り込んで使うのが基本です。
user = Users.objects.get(pk=user_id)
regist = MynumberRegist.objects.get(user=user, year=2026) # 組み合わせで一意になる条件
2. 複数件が正しいなら filter を使う
複数レコードがあり得る場合は filter などにすれば、QuerySet として全件を扱えます。
regists = MynumberRegist.objects.filter(user=user)
for r in regists:
print(r.id)
# 1 件だけ欲しい場合は並び順を決めて first()(0 件なら None)
latest = (MynumberRegist.objects
.filter(user=user)
.order_by('-created_at', '-id')
.first())
first() は並び順を指定しないと主キー順になりますが、「どれを取るか」を意図して order_by() を書いておくと安全です。
3. 例外を捕まえて処理を分ける
try:
regist = MynumberRegist.objects.get(user=user)
except MynumberRegist.DoesNotExist:
regist = None
except MynumberRegist.MultipleObjectsReturned:
# データ不整合としてログに残すなど
raise
例外を握りつぶして先頭の 1 件を使う、といった処理は重複データを放置することになるので、ログに残して原因を調べるようにします。
重複データの調べ方と再発防止
本来 1 件のはずなのに 2 件あった場合は、重複しているデータを特定します。
from django.db.models import Count
dups = (MynumberRegist.objects
.values('user_id')
.annotate(cnt=Count('id'))
.filter(cnt__gt=1))
print(list(dups))
重複を整理したら、モデルにユニーク制約を追加してマイグレーションし、DB 側で二重登録を防ぎます。
class MynumberRegist(models.Model):
user = models.ForeignKey(User, models.CASCADE) # 第 2 引数は削除時の動作
year = models.IntegerField()
class Meta:
constraints = [
models.UniqueConstraint(fields=['user', 'year'], name='uniq_regist_user_year'),
]
重複データが残ったままだと、制約を追加するマイグレーションが失敗します。先に重複を解消してから適用してください。
get_or_create でこのエラーが出る場合
get_or_create() も内部で get を使うため、すでに重複がある条件では同じエラーになります。また、ユニーク制約が無い状態で複数のリクエストが同時に get_or_create を実行すると、どちらも「無い」と判断して 2 件作ってしまい、次回以降このエラーが出ることがあります。get_or_create や update_or_create() の条件に使う項目には、ユニーク制約を付けておくのが Django の公式ドキュメントでも推奨されている使い方です。
確認方法
python manage.py shellでMynumberRegist.objects.filter(条件).count()を実行し、該当件数を確認する- 2 以上なら、条件を見直すか重複データを整理する
- 修正後、同じ処理を実行して例外が出ないことを確認する
関連
- Django ORM filter 完全ガイド(lookup 一覧・Q オブジェクト・F 式・annotate)
- Django でのデータベース接続と操作完全ガイド — ORM/QuerySet/トランザクション
- Django Model の定義方法完全ガイド — フィールド型と Meta
- Django マイグレーションファイル作成完全ガイド
子ページはありません
- Invalid HTTP_HOST header: '...'. You may need to add '...' to ALLOWED_HOSTS
- CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.
- django.utils.datastructures.MultiValueDictKeyError
- Forbidden (403) CSRF verification failed. Request aborted.
- ModuleNotFoundError: No module named 'MySQLdb'
- WARNINGS: ?: (mysql.W002) MySQL Strict Mode is not set for database connection
- Unknown column 'table_name.id' in 'field list'
- RuntimeError: Model class ~ doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
- get() returned more than one MynumberRegist -- it returned 2!
- django.db.utils.OperationalError: (2006, "Can't connect to MySQL server")
- 'include' is not defined
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Djangoテンプレートのif・elif・else|型・未定義と複合条件 2026-10-25 23:02:54
- DjangoのSQLite接続設定|DATABASES・dbshellとCLIエラーの確認 2026-10-25 22:56:56
- Django REST FrameworkでAPIを作る|URL接続・入力検証・所有者の認可 2026-10-25 21:03:21
- DjangoモデルをJSONで返す|型・公開フィールド・DRF認可 2026-10-25 20:46:35
- precompile standard library とは(Pythonインストール) 2026-10-25 20:30:17
- ANACONDA NAVIGATORの起動方法 2026-10-25 20:30:17
- DjangoのAjax POST|CSRF・JSON入力検証・DRFの認可 2026-10-25 20:30:16
- Django/MySQLのUnknown column ...id|主キー・実列・別名の確認 2026-10-25 20:08:53
- 【django】limit, offsetの指定方法 2026-10-25 20:08:51
- Djangoの本番で変更が反映されないとき|プロセス・テンプレート・静的配信の確認 2026-10-25 19:40:35
- Django のファイルアップロード|ファイル名と拡張子の取得 2026-10-25 19:40:35
- djangoにおけるHTTPステータスコードの返し方 2026-10-25 19:40:34
- PythonのResponseオブジェクトの中身の確認 2026-10-25 19:17:54
- Python で Cookie を扱う|requests の Session と http.cookies 2026-10-25 19:17:54
- Python で HTTP リクエスト|requests・urllib・httpx と curl の対応 2026-10-25 19:17:53