djangoでupdate_or_createを使ってみる

2022年5月3日

djangoでupdate_or_createを使ってみる

ORMについてはチートシートを作っていなかったので少しずつ増やしていきたいと思います。

モデル

モデルは下の通り。


from django.db import models
class Writer(models.Model):
    name = models.CharField(max_length=128)
class Article(models.Model):
    writer = models.ForeignKey(Writer, on_delete=models.CASCADE , related_name='articles')
    title = models.CharField(max_length=512)
    contents = models.TextField()

データベース

データベースは下の通り。


MariaDB [djangodatabase]> select * from myapp_writer;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | satoh     |
|  2 | suzuki    |
|  3 | takahashi |
|  4 | furukawa  |
+----+-----------+
MariaDB [djangodatabase]> select * from myapp_article;
+----+--------+------------------------+-----------+
| id | title  | contents               | writer_id |
+----+--------+------------------------+-----------+
|  1 | java   | java for beginner      |         1 |
|  2 | python | python for beginner    |         1 |
|  3 | R      | R for datascientist    |         2 |
|  4 | ruby   | practice ruby on rails |         3 |
|  5 | php    | web engineer for php   |         3 |
|  6 | go     | go for beginner        |         1 |
+----+--------+------------------------+-----------+

プログラム

プログラムは下の通りです。
update_or_createの第一引数に条件指定します。第二引数のdefaultsに辞書を渡すとフィールド名と一致した値をUPDATEまたはINSERTしてくれます。
返値の一つ目にはUPDATEまたはINSERTされたオブジェクトが返ってきます。返値の二つ目にはUPDATEなら「True」INSERTなら「False」が返ってきます。


>>> from myapp.models import Writer, Article>>> selected_writer = Writer.objects.get(id=4)
>>> obj, created = Article.objects.update_or_create(writer=selected_writer, defaults={'title': 'css', 'contents': 'css'})
>>> print(obj, created)
Article object (11) True

対象となる「furukawa(writer_id=4)」の人物はまだ本(article)のデータを持っていないので、データが新しく生成されているのが確認できました。
※色々いじくっていたのでidが11ですが...


MariaDB [djangodatabase]> select * from myapp_article;
+----+--------+------------------------+-----------+
| id | title  | contents               | writer_id |
+----+--------+------------------------+-----------+
|  1 | java   | java for beginner      |         1 |
|  2 | python | python for beginner    |         1 |
|  3 | R      | R for datascientist    |         2 |
|  4 | ruby   | practice ruby on rails |         3 |
|  5 | php    | web engineer for php   |         3 |
|  6 | go     | go for beginner        |         1 |
| 11 | css    | css                    |         4 |
+----+--------+------------------------+-----------+

今度は下の通りcontentのデータを「css」から「css for designer」に変えてもう一度同じプログラムを実行してみました。createdがFalseになっているのが確認取れました。


>>> obj, created = Article.objects.update_or_create(writer=selected_writer, defaults={'title': 'css', 'contents': 'css for designer'})
>>> print(obj, created)Article object (11) False

データベースもしっかり修正されているます。


MariaDB [djangodatabase]> select * from myapp_article;
+----+--------+------------------------+-----------+
| id | title  | contents               | writer_id |
+----+--------+------------------------+-----------+
|  1 | java   | java for beginner      |         1 |
|  2 | python | python for beginner    |         1 |
|  3 | R      | R for datascientist    |         2 |
|  4 | ruby   | practice ruby on rails |         3 |
|  5 | php    | web engineer for php   |         3 |
|  6 | go     | go for beginner        |         1 |
| 11 | css    | css for designer       |         4 |
+----+--------+------------------------+-----------+

2022年5月3日