7

ぶっちゃけ質問タイム。NOT NULL として定義された列を省略しても、Django モデルのオブジェクトを作成できるようで、その理由がわかりません。これが私のモデルです:

class Movie(models.Model):
    name = models.CharField(max_length=256)
    length_minutes = models.IntegerField()
    rating = models.CharField(max_length=2)

    class Meta:
        db_table = 'movies'

python manage.pySQLを実行すると、次のように表示されます。

BEGIN;
CREATE TABLE "movies" (
  "id" serial NOT NULL PRIMARY KEY,
  "name" varchar(256) NOT NULL,
  "length_minutes" integer NOT NULL,
  "rating" varchar(2) NOT NULL
);
COMMIT;

\d moviesまた、からコマンドを実行するとpsql、すべての列が に指定されていることがわかりますNOT NULL

しかし、ここで私が理解していないことがあります。Python シェルを実行すると、次のコマンドを発行できます。空の「名前」列を持つ新しい行が作成されます。

Movie.objects.create(length_minutes=120, rating='PG')

ただし、同等の SQL コマンド (と思われるもの) を発行すると、次のようになります。

INSERT INTO movies(length_minutes, rating) VALUES(120, 'PG');

...私が期待するエラーが表示されます:「エラー: null 値... null 以外の制約に違反しています。」

NOT NULLDjango の ORM を使用すると、 CharField 列のパラメーターを持たないオブジェクトを作成できるのはなぜですか? モデルバリデーターを使用していることを前提としていますか? もしそうなら、それはかなり愚かで信頼できるORMのようです.

Python 2.7.1、Django 1.4、および PostgreSQL 9.1.4 を使用しています。

ご協力いただきありがとうございます。

4

2 に答える 2

12

たくさんのオンライン調査と実験の結果、私が見つけたのは、上記の動作が通常のDjangoの動作であることを示しています。どうやら、Djangoはデフォルトでモデルを検証しません。さらに、CharFieldのデフォルト値は空の文字列です。NOT NULLで指定されたCharFieldパラメータを省略した場合に、Djangoが期待されるIntegrityErrorを確実に発生させるために、署名宣言に「default=None」を追加する必要がありました。

name = models.CharField(max_length=256, default=None)

自分の質問に答えたクレジットをもらえますか?

于 2012-10-14T22:25:00.007 に答える
2

空の文字列''は ではなくNULL、空の文字列です。''完全に有効な null 以外の値です。''アプリケーションで許容できる値でない場合は、次のCHECKような制約を追加します。

ALTER TABLE movies
ADD CONSTRAINT movie_name_length 
CHECK (length(name) > 0);

Django、またはあなたのアプリケーションは、名前を指定しない場合''、 ではなく空の名前が必要であると想定しているようですNULLのDjangoドキュメントをField.null参照してください。これは、私が呼ぶものではありません...クリア...しかし、デフォルトではが扱われないことを示唆しているよう''です。

于 2012-10-14T05:18:09.320 に答える