Django 1.0中国語ドキュメント---モデル構文


モデルの作成
 
1つのモデルは、必要なフィールドとデータストレージの動作を含む個別の明確なデータソースであり、通常、1つのモデルはデータベース内のテーブルに対応します.
 
基本的には:
  • 各モデルはdjango.db.models.Modelのサブクラス
  • である.
  • 各モデル属性は、データベースのフィールド
  • を記述する.
  • djangoは自動的なデータベース操作API
  • を提供する.

     
    この例では、first_があるPersonを定義します.nameとlast_nameの2つのフィールド
    from django.db import models
    
    class Person(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=30)
    

     
    Personは、次のようなデータベース・テーブルを作成します.
     
    CREATE TABLE myapp_person (
        "id" serial NOT NULL PRIMARY KEY,
        "first_name" varchar(30) NOT NULL,
        "last_name" varchar(30) NOT NULL
    );
    

     
     
    いくつかの注意
  • テーブル名デフォルト自動名前myapp_person、もちろんこれも私たち自身で
  • をカスタマイズすることができます.
  • IDフィールドは自動的に追加されたプライマリキーフィールドであり、これは
  • をカスタマイズすることもできる.
  • で生成されたSQLスクリプトは、使用するデータベースの不通によって異なります.
  • モデルの操作
     
    モデルを定義したらDJANGOにsettingsで彼を使うように伝える必要があります.pyのINSTALLED_APPS加入
     
     
    INSTALLED_APPS = (
        #...
        'mysite.myapp',
        #...
    )
    

     
    次にコマンドを実行します
     
     
     manage.py syncdb.
     
    フィールド
     
    これはモデルの最も重要な部分であり、フィールドは属性クラスとして定義されています.
     
     
    class Musician(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        instrument = models.CharField(max_length=100)
    
    class Album(models.Model):
        artist = models.ForeignKey(Musician)
        name = models.CharField(max_length=100)
        release_date = models.DateField()
        num_stars = models.IntegerField()
    

     
    フィールドタイプ
     
    各モデルのフィールドは適切なフィールドクラスをインスタンス化し、djangoはフィールドクラスを通じていくつかの情報を決定します.
     
  • データベースフィールドタイプ
  • Django管理インタフェースコンポーネント
  • 最小値検証
  • Djangoは多くのフィールドタイプを提供しています
     
    フィールドオプション
     
    各フィールドにはいくつかのパラメータがあります.たとえば、CharFieldは、データベースVARCHAR列のフィールド長を指定するためにmax_lengthを必要とします.
     
    null
    許可が空です.
    blank
    空白として許可
    choices
    集合を選択し、次のようにします.
             
    YEAR_IN_SCHOOL_CHOICES = (
        ('FR', 'Freshman'),
        ('SO', 'Sophomore'),
        ('JR', 'Junior'),
        ('SR', 'Senior'),
        ('GR', 'Graduate'),
    )

     
     
    default
    デフォルト
    help_text
    フォームフィールドの下に表示されるこのフィールドに関する説明情報(管理インタフェース)
    primary_key
    プライマリキー
      unique
    ユニークコンストレイント
     
    オートインクリメントプライマリ・キー
     
    各モデルのデフォルトはid=modelsである.AutoField(primary_key=True)
    詳細フィールド名
    first_name = models.CharField("Person's first name", max_length=30)
    ForeignKeyの場合、ManyToManyFieldの場合、OneToOneFieldのようなフィールドのラベル
     
    sites = models.ManyToManyField(Site, verbose_name="list of sites")
     
     
    関係
     
    リレーショナル・データベースの機能は、テーブル間のリレーションシップを確立することです.Djangoは、3つのフィールド・タイプのリレーションシップ、many-to-one、many-to-many、one-to-oneを提供します.
     
    many-to-one(多対一)関係
     
    複数対の関係を定義するには、ForeignKeyを使用する.使用方法は他のフィールドと同じです.
    ForeignKeyには、関連するクラスである位置決めパラメータが必要です.
    たとえば、1つのCarモデルにManufacturerがあり、多くのCarが1つのManufacturerから作成されている場合は、次のように定義します.
     
     
     
    class Manufacturer(models.Model):
        # ...
    
    class Car(models.Model):
        manufacturer = models.ForeignKey(Manufacturer)
        # ...

     
    Many-to-many(多対多)関係
     
    複数対の関係を定義するには、ManyToManyFieldを使用する.使用方法は他のフィールドと同じです.
    ManyToManyFieldには、関連するクラスである位置決めパラメータが必要です.
     
    例えば、pizzaは複数の配合物を含み、1つの配合物は複数のPIZZAに用いられ、以下のように表現することができる.
     
    class Topping(models.Model):
        # ...
    
    class Pizza(models.Model):
        # ...
        toppings = models.ManyToManyField(Topping)

     
    ForeignKeyと同様に再帰関係を築くこともできます.
    上のコードではtoppingが複数の情勢を提案しています.
    ManyToManyFieldはまた、他のパラメータオプションをサポートし、記述関係を定義する.
     
    追加のmany-to-manyフィールド関係
     
    pizzasと原料を混合してマッチングするなど、簡単な多対多関係だけを処理する場合は、標準的なManyToManyFieldが必要です.しかし、2つのモデル間のデータを関連付ける場合があります.
     
    例えば、バンドミュージシャンの帰属を追跡すると、1人とグループの多対多関係があり、ManyToManyFieldで説明することができますが、多くの会員(Membership)の詳細は、バンドに参加する時間などを収集する必要があります.これらの場合、Djangoでは、モデル制御のマルチペアマルチリレーションシップを指定できます.中間モデルに追加のフィールドを割り当て、throughパラメータを使用して仲介者を指すことができます.この例のコードは次のとおりです.
     
    class Person(models.Model):
        name = models.CharField(max_length=128)
    
        def __unicode__(self):
            return self.name
    
    class Group(models.Model):
        name = models.CharField(max_length=128)
        members = models.ManyToManyField(Person, through='Membership')
    
        def __unicode__(self):
            return self.name
    
    class Membership(models.Model):
        person = models.ForeignKey(Person)
        group = models.ForeignKey(Group)
        date_joined = models.DateField()
        invite_reason = models.CharField(max_length=64)
    

     
    中間モデルにはいくつかの制約があります
     
  • 中間モデルには、1つの外部キー関連付けで指定されたターゲットモデル(中間モデルの複数対のマルチフィールドのモデル、ここではperson)が含まれている必要があります.そうしないと、エラーが発生します.
  • 中間モデルには、指定されたソースモデル(ここではGroupモデル)を1つだけ外部キーで関連付ける必要があります.No者はエラーを報告します.
  • 中間モデルにより,自己多対多関係は例外である.この場合、2つの外部キーの同じモードは許容されるが、2つの(異なる)双方の多対多関係と見なされる.
  • マルチペアマルチリレーションシップを定義する場合は、中間モデルを使用してsymmetrical=False
  • を使用する必要があります.
    マルチペアマルチリレーションシップ中間モデルを使用して、マルチペアマルチリレーションシップを作成し、インスタンスを作成し始めました.
     
    >>> ringo = Person.objects.create(name="Ringo Starr")
    >>> paul = Person.objects.create(name="Paul McCartney")
    >>> beatles = Group.objects.create(name="The Beatles")
    >>> m1 = Membership(person=ringo, group=beatles,
    ...     date_joined=date(1962, 8, 16),
    ...     invite_reason= "Needed a new drummer.")
    >>> m1.save()
    >>> beatles.members.all()
    [<Person: Ringo Starr>]
    >>> ringo.group_set.all()
    [<Group: The Beatles>]
    >>> m2 = Membership.objects.create(person=paul, group=beatles,
    ...     date_joined=date(1960, 8, 1),
    ...     invite_reason= "Wanted to form a band.")
    >>> beatles.members.all()
    [<Person: Ringo Starr>, <Person: Paul McCartney>]
    

     
    通常のマルチペアマルチフィールドとは異なり、add、create、またはassignmentを使用して関係を作成することはできません.
     
    #     
    >>> beatles.members.add(john)
    #      
    >>> beatles.members.create(name="George Harrison")
    #     
    >>> beatles.members = [john, paul, ringo, george]

    どうしてですか.PersonとGroupの間に関係を作成することはできません.メンバーシップを確立するためにすべての詳細を指定する必要があります.add、create、assignmentは追加の情報を提供できません.したがって、中間モデルの多対多関係を使用する場合は使用できません.
     
    removeメソッドも使用できません.削除メソッドの代わりにclearを使用します.
     
     
    # Beatles have broken up
    >>> beatles.members.clear()

     
    中間モデルの多対多関係を決定したら、関係クエリーを実行できます.
     
     
    # Find all the groups with a member whose name starts with 'Paul'
    >>> Groups.objects.filter(members__name__startswith='Paul')
    [<Group: The Beatles>]

     
    中間モデルを使用すると、彼のプロパティを使用してクエリーできます.
     
    # Find all the members of the Beatles that joined after 1 Jan 1961
    >>> Person.objects.filter(
    ...     group__name='The Beatles',
    ...     membership__date_joined__gt=date(1961,1,1))
    [<Person: Ringo Starr]

     
    一対一の関係
     
    複数対の関係を定義するには、OneToOneFieldを使用する.使用方法は他のフィールドと同じです.
    OneToOneFieldには、関連するクラスである位置決めパラメータが必要です.
     
    例えば、場所データベースを構築する場合は、アドレス電話などのきれいな基準の資料を構築する必要があります.その後、レストランデータベースを地域の上に構築する場合は、重複するフィールドを交換し、場所と1対1の関係を構築する必要があります.
     
     
    モデルクロスファイル
     
    モデルの関連付けは、2つのアプリケーション間で使用できます.たとえば、次のような他のモデルを上部に入力できます.
     
    from mysite.geography.models import ZipCode
    
    class Restaurant(models.Model):
        # ...
        zip_code = models.ForeignKey(ZipCode)
    

     
    フィールド名規則
     
    djangoフィールドには2つのネーミングルールがあります.
     
       1.フィールド名はpython言語の事前定義キーではありません.「pass」などです.いいえ、コンパイルエラーが発生します.
         
    class Example(models.Model):
        pass = models.IntegerField() # 'pass' is a reserved word!

     
       2.フィールド名には、djangoのクエリー構文規則との競合を回避するために、1つ以上の下線を含めることはできません.
       
    class Example(models.Model):
        foo__bar = models.IntegerField() # 'foo__bar' has two underscores!
    

     
     
     
    カスタムフィールドタイプ
     
    新しいdjango 1.0バージョンでは、カスタムフィールドタイプドキュメントのセクションを詳細に参照できるモデルのフィールドタイプを自分で定義できます.
     
    メタオプション
     
    内部クラスでモデルにメタデータを提供します.
     
    class Ox(models.Model):
        horn_length = models.IntegerField()
    
        class Meta:
            ordering = ["horn_length"]
            verbose_name_plural = "oxen"
    

     
    モデルメタデータはフィールドではなく、命令オプション(ソート)、データテーブル名、読み取り可能な単数複素数などのパラメータは必要ありません.
     
    モデルメソッド
     
    モデルにカスタムメソッドを追加して、モデルの論理機能を比較的価値のあるものにすることができます.たとえば、次のモデルには独自のメソッドがあります.
     
    from django.contrib.localflavor.us.models import USStateField
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        birth_date = models.DateField()
        address = models.CharField(max_length=100)
        city = models.CharField(max_length=50)
        state = USStateField() # Yes, this is America-centric...
    
        def baby_boomer_status(self):
            "Returns the person's baby-boomer status."
            import datetime
            if datetime.date(1945, 8, 1) <= self.birth_date <= datetime.date(1964, 12, 31):
                return "Baby boomer"
            if self.birth_date < datetime.date(1945, 8, 1):
                return "Pre-boomer"
            return "Post-boomer"
    
        def is_midwestern(self):
            "Returns True if this person is from the Midwest."
            return self.state in ('IL', 'WI', 'MI', 'IN', 'OH', 'IA', 'MO')
    
        def _get_full_name(self):
            "Returns the person's full name."
            return '%s %s' % (self.first_name, self.last_name)
        full_name = property(_get_full_name)
    

     
    最後のメソッドはプロパティに設定され、プロパティのプロパティの説明については関連資料を表示できます.
     
    デフォルトのいくつかの方法を上書きすることもできます
     
    __unicode__() unicode方式戻り文字
    get_absolute_url()感じリンクを取得
     
     
    定義済みモデルメソッドの上書き
     
    save()やdelete()のようなモデルを再実装するいくつかの方法が必要になる場合があります.
     
    class Blog(models.Model):
        name = models.CharField(max_length=100)
        tagline = models.TextField()
    
        def save(self, force_insert=False, force_update=False):
            do_something()
            super(Blog, self).save(force_insert, force_update) # Call the "real" save() method.
            do_something_else()
    

     
     
    それでもいい
    class Blog(models.Model):
        name = models.CharField(max_length=100)
        tagline = models.TextField()
    
        def save(self, force_insert=False, force_update=False):
            if self.name == "Yoko Ono's blog":
                return # Yoko shall never have her own blog!
            else:
                super(Blog, self).save(force_insert, force_update) # Call the "real" save() method.
    

     
    カスタムSQLの実行
     
    カスタムSQLを実行する必要がある場合は、次のようにします.
    def my_custom_sql(self):
        from django.db import connection
        cursor = connection.cursor()
        cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
        row = cursor.fetchone()
        return row
    

     
    モデルの継承
     
    djangoのモデル継承はpythonの標準クラスの継承と同じであり、複数のモデルに同じ部分がある場合は、共通の部分を親として継承することができます.
     
    抽象クラス
     
    いくつかの共通情報をいくつかのモデルに追加したい場合は抽象クラスが重要です.基本クラスを作成しabstract=Trueを設定すると、このモデルはテーブルに作成されません.
     
    class CommonInfo(models.Model):
        name = models.CharField(max_length=100)
        age = models.PositiveIntegerField()
    
        class Meta:
            abstract = True
    
    class Student(CommonInfo):
        home_group = models.CharField(max_length=5)
    

     
    メタ継承
     
    class CommonInfo(models.Model):
        ...
        class Meta:
            abstract = True
            ordering = ['name']
    
    class Student(CommonInfo):
        ...
        class Meta(CommonInfo.Meta):
            db_table = 'student_info'
    

     
    注意related_name 
     
    ForeignKeyまたはManyToManyFieldを使用している場合はrelated_を使用します.nameプロパティ、唯一のreverse nameを指定する必要があります
     
    class Base(models.Model):
        m2m = models.ManyToMany(OtherModel, related_name="%(class)s_related")
    
        class Meta:
            abstract = True
    
    class ChildA(Base):
        pass
    
    class ChildB(Base):
        pass
    

     
     
    マルチテーブル継承
     
    class Place(models.Model):
        name = models.CharField(max_length=50)
        address = models.CharField(max_length=80)
    
    class Restaurant(Place):
        serves_hot_dogs = models.BooleanField()
        serves_pizza = models.BooleanField()
    

     
     
    >>> Place.objects.filter(name="Bob's Cafe")
    >>> Restaurant.objects.filter(name="Bob's Cafe")
    
    >>> p = Place.objects.filter(name="Bob's Cafe")
    # If Bob's Cafe is a Restaurant object, this will give the child class:
    >>> p.restaurant
    <Restaurant: ...>