知識の枝

"All is well"

Django モデルを生成する方法

約257日前 2021年5月11日23:04
デジタル
Django

改訂履歴


2021/5/11 投稿

1. 背景


Djangoを使った開発中に覚えたことを備忘録として残します。

今回はビュー内でモデルを生成する方法を解説します。


2. ゴール


views.py内でモデルを生成&DBに保存する方法を覚える


3. はじめに


今回やりたいことは単純です。
views.pyの中でモデルを新たに生成します。

Djangoを学習し始めた頃の私の考えでは、

・既に存在するモデルをテンプレートに渡す
・既に存在するモデルを操作して扱いやすい形に変える
・POSTされたデータを元にモデルを新しく作る

といったこともできる便利な役割を担うのがviews.pyと初心者ながらに思っていました。


モデルを作るときはDjangoのadminサイトで登録するか、ウェブページからPOSTするしか無いと考えていましたので、「views.pyの中でモデルを1つ作りたい」となったときにやり方が分かりませんでした。


実は簡単に実装する方法がありましたので紹介します。


4. create


Djangoにはモデルを扱うメソッドの中に「create()」というものが存在します。
これを今回使用したいと思います。


create()メソッドの引数にはキーワード引数(**kwargs)が入ります。
これは生成するモデルのフィールドと対応しており、下記のような"Note"モデルの場合を例に説明します。
models.py
class Note(models.Model):
text = models.CharField(verbose_name='text', max_length=255)

def __str__(self):
return self.text
このNoteモデルは「Note.objects.create(text=’本文をここに書く')」という一文で生成可能です。

モデル名.objects.(フィールド名=内容) という書き方です。


仮に全てのフィールドが「blank=True, null=True」又はデフォルト値の設定がある場合は、括弧内に引数を与えなくてもモデルが生成されます。


create()で生成されたモデルは、生成時にDBに保存されますのでsave()しなくてもOKです。



では、このメソッドを使用した一例を紹介します。

ここ のお気に入り管理アプリは、初期画面でURLを入力してボタンを押す(POSTする)と2つのモデルが生成されます。



生成されるモデルは下記2つです。
models.py
class RandomURL(models.Model):
"""URL PAGE MODEL"""
delete_date = timezone.now() + relativedelta(hours=48)

page_title = models.CharField(verbose_name='title', max_length=255, default="new title")
random_url = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
will_delete_at = models.DateTimeField(verbose_name='will_be_deleted_at', default=delete_date)

def __str__(self):
return str(self.random_url)


class Star(models.Model):
"""Star model"""

url = models.CharField(verbose_name='url', max_length=255) #ここを上記のページで入力している
random_url = models.ForeignKey(RandomURL, verbose_name='onetime_url', on_delete=models.CASCADE)
opened = models.DateTimeField(verbose_name='update', auto_now=True)
unique_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)


def __str__(self):
return self.title
ランダムなURLで生成されるページを管理する「RandomURL」モデルとお気に入りページを管理する「Star」モデルです。

トップページではURL1つしか入力しませんが、「Create Now」のワンクリック(1つのPOST)で合計7つのフィールドが決まり、2つのモデルが生成されます。

views.pyの中身は下記のようになっています。
views.py
def IndexView(request):
template = 'star_index.html'
create_star_form = CreateStarForm

if request.method == "POST":
create_star_form = CreateStarForm(request.POST)
if create_star_form.is_valid():
random_page = RandomURL.objects.create() #ここでcreateメソッドを使っています
new_star = create_star_form.save(commit=False)
new_star.random_url = random_page
new_star.save()
return redirect('ots:star', star_id=new_star.random_url)

context = {
'create_star_form': create_star_form,
}

return render(request, template, context)
is_valid()後の1行目でRandomURLモデルを生成しています。
random_page = RandomURL.objects.create()
このモデルは3つのフィールド全てがデフォルト値を持つ為、引数が空でも問題ありません。

その後、POST内容を保存する処理に入ります。
StarモデルにはForeignKeyでRandomURLモデルを1つ選択するフィールドがあります。
random_url = models.ForeignKey(RandomURL, verbose_name='onetime_url', on_delete=models.CASCADE)
こうすることで1つのページに複数のお気に入りを紐づけることができるようになります。


ForeignKeyのフィールドに先ほどcreateで生成したRandomURLモデルを割り当てます。
 new_star.random_url = random_page
ここが今回のミソです。

「Create Now」を押しただけで
・2つのモデルを生成
・片方のモデルをもう一方のモデルの外部キーとして割り当てる
これらの一連の処理を同じタイミングで実行することができました。

create()メソッドの便利さが伝わりましたか?


5. さいごに


新しいことに挑戦すると新しいことを学ぶことができますね。
このcreate()を使えば、これまで以上にアイデアが湧いてくるのではないでしょうか?

Djangoで楽しく開発しましょう!