読者です 読者をやめる 読者になる 読者になる

cloverrose's blog

Python, Machine learning, Emacs, CI/CD, Webアプリなど

Django Tips1

Django本の5章を読んでまとめる
本は、Django0.96が最新の時代のものなので、Django1系に通用しないところをそのまま紹介してしまうかもしれない。

リレーションについて

ForeignKeyは多対一の多側に書く

class Company(models.Model):
    pass

class Section(models.Model):
    company=models.ForeignKey(Campany)

ForeignKeyのField名はリレーションを張るモデル名を小文字にしたもの

Companyだからcompany

ForeignKeyでnull=Trueは自己参照する際に使用

class Section(models.Model):
    parent=models.ForeignKey(u'self',blank=True,null=True)

循環参照もできる

同じファイルmodels.pyの中で定義しているモデルはモデル名を表す文字列(ユニコード)を使って参照できる。
自己参照のu'self'はその特別バージョン

class A(models.Model):
    b=ForeignKey(u'b')
    # b=ForeignKey(b) これはクラスBを定義する前なのでエラー

class B(models.Model):
    a=ForeignKey(A)

related_nameについて

Companyクラスから逆参照する際の名前
省略すると'クラス名_set'になる

class Section(models.Model):
    parent=models.ForeignKey(u'self',blank=True,null=True,related_name='child_set')

ManyToManyFieldについて

片方で定義
自動生成されるテーブル名がデータベースのテーブル名の制限(MySQL:64文字等)を超えないように注意

DataTimeField,DateFieldについて

settings.pyのTIME_ZONEに従う

オプションについて

nullについて

null=Trueの場合、空の文字列はNULLとして登録される
null=Falseの場合、空の文字列は空の文字列として登録される
カラムによって空の文字列がNULLだったり空の文字列だったりすると良くないのでCharField,TextFieldについてはnull=Trueにしない

blankについて

blank=Falseの場合、入力が必須

uniqueについて

unique=Trueの場合、重複を許さない

editableについて

editable=Falseの場合、Adminサイトに表示されない

max_lenghthについて

CharFieldで必須
unique=Trueの時はMySQLでは255以下にしなければいけない

verify_existsについて

URLFieldでverify_exists=Trueにすると、実際にインターネット上に存在しているか調べる(すごい)

代理キーのススメ

PrimaryKeyの指定をしなければ、暗黙でidという名前の数値型プライマリキー=代理キーが定義される。

class Company(models.Model):
    code=models.CharField(max_length=4,unique=True)

について会社のcodeは必須かつ一意なのでプライマリキーに適してると思うかもしれない。
しかし、変更の可能性はゼロではない。
変更する際は、リレーションのあるテーブルのデータをすべて変更しなければならない

モデルのデフォルトのアクションを変更

from django.dispatch import dispatcher
dispacher.connect(関数,sender=モデル名,signal=シグナル)

関数
def 関数名(signal,sender,instance,**kwds)というシグネチャー
instance.id==None まだ保存されていない→最初の保存
instance.id!=None 更新
シグナル
signals.pre_save モデルが保存される前(saveが呼び出されたタイミング)
signals.post_syncdb syncdbされた後
signals.pre_delete/post_delete モデルが削除された前後

save,deleteメソッド

save 保存・更新する際に呼ばれる
delete 削除する際に呼ばれる

def save(self):
    self.date=datetime.now()
    # do someting
    super(Entry,self).save()
    # do someting

selfはモデルのインスタンス
signalと同様に、self.idで新規か更新かわかる

発展

メタデータクラス、Adminオプション
django.contrib.contenttypes