Web制作、Web開発の歩き方

初心者のためのDjango入門

■第9話:Modelにおける制約の作成

(最終更新日:2023.07.30)

Djangoフレームワークのイメージ
この記事は5分で読めます!
(絵が小さい場合はスマホを横に)

「重複を防ぎたい!」

データベースを扱う際、同一フィールド内で重複(同じ値の登録)を防ぐにはユニークキーを設定する。 ただし、「苗字と名前の両方が一致した場合の重複を阻止する」「部屋の番号と予約時間の両方が一致した場合の重複を阻止する」といった、 複数フィールドにまたがる重複の制御は対応できない。 そんなときに役立つ機能がDjangoのConstraint(制約)である。 今回はそれを可能にする、DjangoのConstraint機能について紹介していこう。


1.CheckConstraint

CheckConstraintはDjangoのQオブジェクトを使用して、特定の条件を満たしているかをチェックする機能である。 以下の例では、6歳と7歳のみ登録が可能となっており、5歳を入力するとエラーが発生する。条件を変更することで、 18歳以上のみ登録可能にしたり、12歳以下の登録を禁止することもできる。

Djangoには、MinValueValidatorやMaxValueValidatorといった最大値・最小値を設定する制約機能も存在するが、 記述が長くなり見づらくなる上、制約できる内容が限定される。 しかし、CheckConstraintとQオブジェクトを組み合わせることで、簡潔にかつ高い自由度で条件を設定できる。 見た目と機能の両面から、こちらの方法を利用することが推奨される。

CheckConstraintによる年齢のチェック
5歳は失敗(右上)、6歳で入力した際は成功(右下)


2.UniqueConstraint

今回の主題であるUniqueConstraintは、複数の項目における重複を防ぐ制約機能である。 以下の例では、姓と名の重複を防止している。 コードの記述方法としては、fieldsに重複を避けたい項目を複数指定するだけで実現できる。

姓と名の重複を防ぐ例は実際にはあまり現実的ではないが、 例えばホテルの部屋予約システムで日程と部屋を組み合わせて重複をチェックするケースなどでは、 この機能が非常に役立つだろう。複数条件における入力の重複を防止する機能として、UniqueConstraintは非常に便利である。

UniqueConstraintの使用例

UniqueConstraintによる複数入力の重複チェック

3.ExclusionConstraint(PostgreSQLのみ)

最後に、ExclusionConstraintについて説明する。 この機能は、データベースにPostgreSQLを使用している場合のみ有効だ。 PostgreSQL限定の機能である、本機能のコードを示す。以下は、Django公式ドキュメントで紹介されているコードだ。

ExclusionConstraintでは、expressions部分に記述することで重複を防ぐ条件を指定できる。 UniqueConstraintとの違いは、timespanの部分で時間帯のオーバーラップを防ぐことができる点だ。 この機能により、時間範囲内での重複がある場合にエラーを発生させることができる。

また、conditionの部分はUniqueConstraintでも使用可能だが、 ExclusionConstraintの例では、キャンセルされたものを除いて重複を防ぐ制約を設定している。 普段からPostgreSQLを使用している方にとっては、便利な機能だから、ぜひ活用してみよう。

ExclusionConstraintの使用例


4.まとめ

今回は、Djangoの制約機能(Constraint)を紹介した。データベースの入力制約はとても便利だ。 DjangoのConstraintを使うことで、 「複数条件によるチェックを行う」「2つの入力情報が一致した時のみエラーを出す」「ある時間範囲の重複を除く」などの制約を簡単に設定できる。

ただ、実際のサイトでは、ホテルや美容院の予約画面で埋まっている時間には×ボタンが表示されるため、 重複した時間に予約することはない。しかし、2人がほぼ同時刻にアクセスした場合、どちらのユーザーにも〇ボタンが表示されることがある。 そんな時の重複予約を防ぐことができる。 例えば、HotpepperBeautyで予約しようとして送信ボタンを押したものの、「既に埋まってしまいました」というメッセージが出るような状況だ。

この制約機能を使うことで、間違いを防ぐ安心設計を実現できる。ぜひ実際のモデルでも活用してみよう。


▼参考図書、サイト

Constraints reference  django公式ドキュメント
【Django】複数フィールドにユニーク制約(複合ユニーク)をつける方法  DjangoBrothers BLOG
PostgreSQL固有のデータベースの制約  Djangoのドキュメント


Django Tutorial for Beginners ■ Episode 9: Creating Constraints in Models (Last updated: 2023.07.30) Image of Django framework This article takes about 5 minutes to read! (Turn your phone sideways if the image is too small) "I want to prevent duplicates!" When working with databases, to prevent duplicate entries in a single field, you can set a unique key. However, if you want to prevent duplicates across multiple fields—like both last name and first name being the same, or a room number and reservation time both matching—standard unique constraints won’t suffice. That’s where Django’s **Constraints** come in handy. In this article, we’ll introduce how to use Django's constraint features to achieve this. [Table of Contents] CheckConstraint UniqueConstraint ExclusionConstraint Summary 1. CheckConstraint A CheckConstraint uses Django’s Q objects to validate whether specific conditions are met. In the example below, only ages 6 and 7 can be registered; entering 5 results in an error. By changing the condition, you could, for example, allow only those 18 and older or prohibit those under 12. While Django also provides `MinValueValidator` and `MaxValueValidator`, these can become verbose and limited in scope. By combining `CheckConstraint` with Q objects, you can define concise and flexible constraints. For both clarity and functionality, this method is often recommended. Age check with CheckConstraint Age 5 fails (top right), age 6 passes (bottom right) 2. UniqueConstraint The main topic of this article, `UniqueConstraint`, is used to prevent duplicates across multiple fields. In the example below, it prevents duplication of both last name and first name. You simply specify multiple fields in the `fields` parameter to apply the constraint. While avoiding duplication of full names might not be common in real scenarios, this is very useful for cases like hotel room bookings, where you want to ensure the same room and date aren't reserved more than once. `UniqueConstraint` is a powerful tool for preventing duplicate entries across multiple fields. Example of UniqueConstraint Duplicate entry check using UniqueConstraint 3. ExclusionConstraint (PostgreSQL only) Lastly, let’s talk about `ExclusionConstraint`. This feature is available **only** when using PostgreSQL as the database. Below is a code snippet featured in the official Django documentation. `ExclusionConstraint` allows you to define conditions in the `expressions` part to prevent duplicates. Unlike `UniqueConstraint`, this can prevent overlaps in time spans, making it ideal for reservations. You can also use the `condition` parameter to exclude certain cases—like canceled reservations—from the constraint. If you regularly use PostgreSQL, this is a powerful feature worth integrating. Example usage of ExclusionConstraint 4. Summary This time, we introduced Django’s constraint features. These database-level validations are extremely useful. With Django Constraints, you can easily set rules like: “Check based on multiple fields,” “Trigger an error only when two specific fields match,” or “Avoid overlaps in time ranges.” In real applications—like hotel or salon bookings—interfaces usually prevent overlapping reservations with an 'X' mark. However, if two users attempt to book at nearly the same time, they might both see the slot as available. That’s when this constraint becomes vital. For example, on sites like Hotpepper Beauty, when two people try to book simultaneously, you may see a message like “The slot has just been taken.” This constraint feature helps prevent such issues and adds an extra layer of safety. Be sure to incorporate it into your actual models. ▼ References   Constraints reference - Official Django documentation   [Django] How to Apply Unique Constraints to Multiple Fields - DjangoBrothers Blog   PostgreSQL-Specific Constraints - Django documentation