Blank?=False

ゆるゆる仕事したいフリーランスエンジニアの記事

【PHPUnit】RefreshDatabaseについて

LaravelのPHPUnit で「おまじない」として毎回入れているuse RefreshDatabase、 これはどのような動きをするか理解するため調べました。

readouble.com

RefleshDatabaseについて

テストケースの先頭にこんな感じで`use RefreshDatabase;'を記載している方は多いと思います。

この機能ですが、 テスト実行毎にデータベースを初期化するというものです。

RefreshDatabaseを使わない場合

カテゴリーというモデルがあったとして,それをテストメソッド内で5個のインスタンスを作る動きをします。

<?php
class sample_Test extends TestCase
{
    /**
     * サンプルテスト
     */
    public function test_Sample(): void
    {

        Category::factory(5)->create()->each( function ($cat){
            printf("ID: {$cat->id}\n");
        } );

        $this->assertTrue(true);
    }
}

1回目の実行結果

ID: 1
ID: 2
ID: 3
ID: 4
ID: 5

2回目の実行結果

ID: 6
ID: 7
ID: 8
ID: 9
ID: 10

説明

2回目の実行結果は前回5個作っているので、6から再度作られます。 つまり、テスト実行毎に処理内容が変わってしまうわけです。

RefreshDatabaseを使う場合

use RefreshDatabaseをテストケースクラス先頭に追加しました。

<?php
class sample_Test extends TestCase
{
    use RefreshDatabase;   //追加!

    /**
     * サンプルテスト
     */
    public function test_Sample(): void
    {

        Category::factory(5)->create()->each( function ($cat){
            printf("ID: {$cat->id}\n");
        } );

        $this->assertTrue(true);
    }
}

1回目の実行結果

ID: 1
ID: 2
ID: 3
ID: 4
ID: 5

2回目の実行結果

ID: 1
ID: 2
ID: 3
ID: 4
ID: 5

説明

2回目の実行結果は前回5個作っているので、6から再度作られます。 つまり、テスト実行毎に処理内容が変わってしまうわけです。

まとめ

テストケースは毎回不変であるべき(じゃないとテストの意味がない)ので、 DBを使用するテストならuse RefreshDatabaseを使用して毎回DBを空にしてテストを行うことが最低条件になります。

こういう「毎回入れるもの」は入門本ではよくおまじないと言われますが、 実際に業務に使うなら、しっかりどういった動きをするものか把握してから使うべきと考えています。

【Django】日本語を含むJsonを返す方法2つ

DjangoRest APIJsonを返そうと思ったら思いの外ハマったポイントがあるのでまとめます。

何にハマった?

DjangoAPIで商品モデル(Product)のデータを取得し、フロントのJavascriptで描画する、というものを作成していました。 そこで、jsonデータ自体は返せるもの、商品モデルのnameに日本語を使った文字列が入っているので、文字化けが発生。

Jsonの文字化けを防ぐため、色々と調べるとjson.dumpsJSON文字列を作るときにensure_asciiパラメータをFalseに設定すると良い、という情報が たくさん見つかりました。

qiita.com

これを参考に、以下のようなコードを組みましたが、今度はフロントエンド側でjson文字列がJSON.parce()で正常に配列化されない。 gist.github.com

ここでハマりました。

原因

一度Json.dumpsJson文字列を作っているのに、JsonResponseJson文字を再度Json化しようとしていたせいでした。

JsonResponseの実装を見ると

gist.github.com

data=json.dumps(...)json化しています。 ということは、JsonResponseを使うときはJson.dumpsしていない生のlistやdictを渡す必要があります。

公式DocにもdataはDictインスタンスを渡してね、って書いてありました。(・_・;) 悩んだら公式Docを読もう… docs.djangoproject.com

で、文字化けはどうするの?

JsonResponseを使う場合、JsonResposneの引数json_dumps_paramsにdump時のパラメータを渡せるので、 {"ensure_ascii"=False}をパラメータと渡せば意図した結果になります。

JSONデータを返す2つの実装方法

というわけで、JSONデータを返すための実装方法はjson.dumpsを使ってHttpResponseで返すか、JsonResponseを使うか、になります。

JsonResponse版

こっちがスマート。 gist.github.com

HttpResponse版

Content-Typeをつけ忘れそうな気もする gist.github.com

近況

最近、Djangoでとあるサービスを開発したのですがより使いやすく・自然な操作感のUXデザインを実現するべく、 フロントエンドフレームワークVue.jsを勉強しています。

フロントエンドフレームワークは初めて触るのでかなり手こずっていますが、勉強が一段落したら感想とか書いていきたいですね。

【Django】ModelFormのバリデーション処理の流れについて

Djangoでモデルクラスにカスタムバリデーションを実装し、 ModelFormのis_valid()でモデルクラス側のバリデータがうまく動かないというのに悩まされたので、 フォームでモデルクラスに実装したバリデータを動かす動作を追ってみました。

続きを読む

Djangoで連動するセレクタを作る

Djangoで連動するセレクタを作ってみました。 下記の3点を組み合わせます。

続きを読む

DjangoでManyToManyFieldの逆参照ができない(他フィールドで同じモデル使用)

どんな問題?

DjangoのモデルでManyToManyフィールドを作成(別フィールドで使っているモデルと同じモデルを使用)

ManyToManyフィールドを作ったモデル側からの参照なら正常にデータが取得できるのに、 逆参照すると正常に取得できない、という問題が発生しました。

かなりハマったので、書いていきます。

続きを読む

DockerでDjango+MariaDB開発環境を構築

最近、MacをやめてWindowsマシンで開発をするようになりました。

8年ぐらい前はWeb開発といえば、Mac(Bashがあるから)という印象でしたが、 今はDockerでコンテナを作ってVSCodeでAttach, Linux上でコードをサクサク書いていけるので便利になりました!

ただ、今までDocker-Composeを触っていなかったので、 Pythonイメージからコンテナを作って、execコマンドでコンテナに入ってpip install django 等で環境構築していたので、 Docker-Composeを使ってより楽に構築してしまおう!とComposeを触ってみることにしました。

続きを読む

ブログ再開のお知らせ

久しぶりに技術ブログを再開します。

前回の記事がもう5年前ですが…

5年前から、色々忙しくしていました。

  • 熊本移住
  • 外資系企業のBPOセンターでTechLeadをやっていました。
  • VBA、BluePrimeなどで業務改善ソリューションをガンガン作る傍ら、チームビルディングなどなどあれこれに携わってました。
  • 2021年7月に退職し、フリーランスとしての営業を始めることにし、今はその準備をしております。

このブログのこれから

今後、メインの言語はPython, Node.jsとして、Django, FlaskなどのWebフレームワーク、 Docker,LINE(Chatbot)などを扱っていきます。

Rubyは俺の中で死んだのだ。

読者がいれば、またよろしくお願いします。