.. _tutorial-part-2: Part 2: 高度な変更 ================== .. Part 2: Advanced Changes ======================== .. Now you've done a simple change to the model, let's look at some of the more advanced changes you can do with South. モデルに簡単な変更を加えてきましたが、次は South を使った、もう少し高度な変更をしてみましょう。 .. _tutorial-part-2-defaults: デフォルト指定 -------------- .. Defaults -------- .. Firstly, let's deal with more tricky column types. In the previous part, we added a ``BooleanField`` to the table - this is easy for a database to handle, as it has a default value (of ``False``) specified, so that's the value that gets used for the column in all of the existing rows. まず初めに、もう少しトリッキーなカラムの型について見てみましょう。 前の章では、テーブルに ``BooleanField`` を追加しました - このフィールドはデフォルト値 (``False``) を持っているため、 既存のレコードを取得した際の該当カラムの値として使われます。 このため、データベースにとっては扱いやすいものとなります。 .. However, some columns don't have a default defined. If the column is nullable - that is, ``null=True`` - then the existing rows will have NULL in the new column. Otherwise, if you've given no default, but the column is ``NOT NULL`` (i.e. ``null=False``, the default), there's no value the database can put in the new column, and so you won't be able to reliably add the column [#]_. しかしながら、いくつかのカラムにはデフォルト値が定義されていません。 カラムがヌル許容ならば - つまり ``null=True`` ならば - 既存レコードの新しいカラムには NULL が指定されることになります。 もしデフォルト値を指定しない場合には、そのカラムは ``NOT NULL`` に (すなわちデフォルトが ``null=False`` に) なり、 データベースは、新しいカラムに値を指定することができなくなるため、信頼性のあるカラム追加処理ができません [#]_ 。 .. .. [#] Some database backends will let you add the column anyway if the table is empty, while some will refuse outright in this scenario. .. [#] いくつかのデータベースバックエンドでは、テーブルが空であってもカラムを追加しようとするものがありますが、 このチュートリアルでは遠慮せずに無視させてもらいます。 .. If South detects such a situation, it will pop up and ask you what to do; let's make it do so. South がこのような状況を見つけると、ポップアップを出して、どのように処理するかを問い合わせてきます; この動作を見てみましょう。 .. First, change your model to add a new field that has no default, but is also not nullable:: まず、デフォルト値を持たずに、ヌル許容でもないフィールドを新しく追加して、モデルを変更しましょう:: from django.db import models class Knight(models.Model): name = models.CharField(max_length=100) of_the_round_table = models.BooleanField() dances_whenever_able = models.BooleanField() shrubberies = models.IntegerField(null=False) .. Now, let's try and get South to automatically generate a migration for that:: では次のように、この変更のマイグレーションを South に自動生成させましょう:: ./manage.py schemamigration southtut --auto ? The field 'Knight.shrubberies' does not have a default specified, yet is NOT NULL. ? Since you are adding or removing this field, you MUST specify a default ? value to use for existing rows. Would you like to: ? 1. Quit now, and add a default to the field in models.py ? 2. Specify a one-off value to use for existing columns now ? Please select a choice: .. South presents you with two options; if you select choice one, the command will quit without doing anything, and you should edit your ``models.py`` and add a default to the new field. South は二つの選択肢を提供してきます; 1番目を選択すると、コマンドは何もせずに終了するので、 ``models.py`` を編集して、新しく追加したフィールドにデフォルト値を設定しましょう。 .. If you select choice two, you'll get a Python prompt, where you should enter the default value you want to use for this migration. The default you enter will only ever be used for the currently-existing rows - this is a good option if you don't want the field on your model to have a default value. 2番目を選択した場合、このマイグレーションに適用するデフォルト値を入力するための Python プロンプトが表示されます。 入力したデフォルト値は、現在の既存レコードだけに使用されます - これは、そのモデルフィールドにデフォルト値を持たせたくない場合に有用な選択肢です。 .. We'll select choice two, and use ``0`` as our default (it is an IntegerField, after all):: ここでは2番目を選択して、デフォルト値に ``0`` を入力してみましょう (IntegerField ですからね) :: ? Please select a choice: 2 ? Please enter Python code for your one-off default value. ? The datetime module is available, so you can do e.g. datetime.date.today() >>> 0 + Added field shrubberies on southtut.Knight Created 0003_auto__add_field_knight_shrubberies.py. You can now apply this migration with: ./manage.py migrate southtut .. If you look at the generated migration, you'll see that there's a default specified for the new field, so your database won't cry. Finish off by running the migration:: 生成されたマイグレーションを見ると、新しいフィールドにデフォルト値が指定されていることがわかります。 これでデータベースが困ることはないでしょう。最後にマイグレーションを実行ます:: $ ./manage.py migrate southtut Running migrations for southtut: - Migrating forwards to 0003_auto__add_field_knight_shrubberies. > southtut:0003_auto__add_field_knight_shrubberies - Loading initial data for southtut. ユニーク指定 ------------ .. Uniques ------- .. As well as detecting new fields (and also ones you've removed), South also detects most changes to fields, including changing their ``unique`` attributes. South は新しいフィールド (または削除したフィールド) だけでなく、 ``unique`` 属性の変更を含めた、ほとんどのフィールド変更を発見することができます。 .. First, let's make our Knights have unique names:: それでは Knight モデルにユニークな名前を持たせましょう:: from django.db import models class Knight(models.Model): name = models.CharField(max_length=100, unique=True) of_the_round_table = models.BooleanField() dances_whenever_able = models.BooleanField() shrubberies = models.IntegerField(null=False) .. Run the automatic migration creator:: 自動マイグレーション生成を実行します:: $ ./manage.py schemamigration --auto southtut + Added unique constraint for ['name'] on southtut.Knight Created 0004_auto__add_unique_knight_name.py. You can now apply this migration with: ./manage.py migrate southtut .. As you can see, it's detected the change in ``unique``; you can now apply it:: ご欄のように ``unique`` の変更を発見しました; このマイグレーションを適用しましょう:: $ ./manage.py migrate southtut Running migrations for southtut: - Migrating forwards to 0004_auto__add_unique_knight_name. > southtut:0004_auto__add_unique_knight_name - Loading initial data for southtut. .. South also detects changes to ``unique_together`` in your model's ``Meta`` in the same way. 同様に South はモデルの ``Meta`` に指定された ``unique_together`` の変更も発見できます。 ManyToMany フィールド --------------------- .. ManyToMany fields ----------------- .. South should automatically detect ManyToMany fields; when you add the field, South will create the table the ManyToMany represents, and when you remove the field, the table will be deleted. South はまた自動的に ManyToMany フィールドを見つけます; フィールドを追加した時に、South は ManyToMany で表されるテーブルを生成し、 フィールドを削除した時にはそのテーブルを削除します。 .. The one exception to this is when you have a 'through model' (i.e. you're using the ``through=`` option) - since the table for the model is already created when the model is detected, South does nothing with these types of ManyToMany fields. ただひとつの例外は 'through モデル' を持っていた場合 (``through=`` オプションを指定した場合) です - モデルが検知された時点で、そのモデルのテーブルが既に作成されているため、 South はその ManyToMany フィールドに対して何の処理もしません。 カスタムフィールド ------------------ .. Custom fields ------------- .. If you've looked closely at the migration files, you'll see that South stores field definitions by storing their class, and the arguments that need to be passed to the field's constructor. マイグレーションファイルをよく見てみると、South はクラスにフィールドの定義と、 フィールドのコンストラクタに渡す引数を保存していることがわかります。 .. Since Python offers no way to get the arguments used in a class' constructor directly, South uses something called the *model introspector* to work out what arguments fields were passed. This knows what variables the arguments are stored into on the field, and using this knowledge, can reconstruct the arguments directly. Python には、クラスのコンストラクタで使用される引数を直接取得する方法が無いため、 South は *モデルイントロスペクション* を使って、フィールドにどんな引数が渡されたのかを導き出します。 これによって、渡された引数がフィールド内のどの変数に保持されているのかを知ることができ、 この情報を使って引数を直接再構築できるのです。 .. Because custom fields (either those written by you, or included with third-party apps) are all different, South can't work out how to get their arguments without extra help, so if you try to add, change or remove custom fields, South will bail out and say that you need to give it rules for your custom fields; this topic is covered in detail in :ref:`custom-fields`. カスタムフィールド (自分で書いたものでも、サードパーティ製アプリに含まれるものでも) はそれぞれ種々様々なため、 South は追加ヘルプテキスト以外の引数を、どのように取得するか解決することができません。 このためカスタムフィールドを追加、変更、削除した場合、 South は処理を諦め、各カスタムフィールドのルールを渡すように表示します; このトピックについては :ref:`custom-fields` において詳しくカバーします。 もっと? -------- .. More? ----- .. South supports most operations you'll do on your models day-to-day; if you're interested, there's a :ref:`full list of what the autodetector supports `. South はモデルに対する、日々の操作のほとんどをサポートします; もし興味があるならば :ref:`自動検出をサポートしているアクション一覧 ` を参照して下さい。 .. You'll probably want to read :ref:`tutorial-part-3` next. さて次は :ref:`tutorial-part-3` に進みましょう。