【Django(日報アプリ開発)】自前のフォルダから関数、クラスをインポート pyファイルをまとめてモジュール化 する方法を解説!

Django

(最終更新月:2021年9月)

前回の記事では、OneToOneFieldを使い、ユーザーモデルを拡張「Profile」クラスを作成しました

プロファイルクラスは「アカウント情報」を保持するため、誰でも自由にアクセスできては困ります

そのため、新たにアクセス制限クラスを作成する必要があります

ただ、コードが複雑になればなるほどこんなことはありませんか?

「どのファイルに特定のクラスや関数が書かれているかわからない!」

「変更したいけどどこに何を書いたかわからない!」

当アプリでもすでにnippoに関するアクセス制限クラスが定義されており、今回のクラスはaccountsに関するものです

今後何かしら変更する可能性があることも考えると、あっちにもこっちにもアクセス制限クラスがあるとどこに書いたかをきちんと把握できるか不安です

ですので、当記事を通じて、新たなアクセス制限クラスを作成するのはもちろんですが、

  • 散らばったクラスを一つのファイルにまとめて、インポートする方法
  • 複数のファイルをまとめてモジュール化する方法

について解説していきます

アクセス制限クラスを一つにまとめる

新たなアクセス制限クラス

まずは「ProfileUpdateView」(アカウント設定ビュー)に使用するアクセス制限クラスを作りました

class OwnProfileOnly(UserPassesTestMixin):
    def test_func(self):
        profile_obj = self.get_object()
        return profile_obj == self.request.user.profile

これと、以前作成した「OwnerOnly」というアクセス制限クラスを一つにまとめていきましょう

クラスを一つにまとめる

プロジェクト直下に

utils(フォルダ) > access_restrictions.py(ファイル)

を作ります

先程作成した、「OwnProfileOnly」と、以前作成した「OwnerOnly」クラスをaccess_restriction.py内へ

(ファイル内のコードはこんな感じです)

from django.contrib.auth.mixins import UserPassesTestMixin

class OwnerOnly(UserPassesTestMixin):
    def test_func(self):
        nippo_instance = self.get_object()
        return nippo_instance.user == self.request.user

class OwnProfileOnly(UserPassesTestMixin):
    def test_func(self):
        profile_obj = self.get_object()
        return profile_obj == self.request.user.profile

インポート方法

nippoのviews.pyと、accountsのviews.pyそれぞれで必要なクラスをインポート

nippo > views.py

from utils.access_restrictions import OwnerOnly

accounts > views.py

from utils.access_restrictions import OwnProfileOnly

以上でファイルをまとめ、インポートまで完了しました!

スポンサーリンク

複数のformsファイルをモジュール化

ついでにもう一つ整理していきたいものがあります

accountsフォルダ内のフォームに関するファイル2つです

  • forms.py
  • profile_forms.py

この2つをまとめてモジュール化してみましょう

モジュール化のメリット

一つの「forms.py」というファイルに記述せず、複数のファイルをモジュール化することで下記のメリットがあります

  1. 目的別にファイルを分けることができ、どこに記述をしたか探すのがカンタン
  2. インポートの際は、モジュールからインポートできるのでいちいちファイル名を覚えてなくても良い

ちょっとまだ実感が湧かないかもしれません…

下記より実例でご覧ください

フォルダ、ファイルの作成

まずはaccountsフォルダ内に「forms」というフォルダを作成します

その中に、既存の「forms.py」と「profile_forms.py」を移動します

さらに、同列に「__init__.py」を作成します

フォルダ内は↓の通りです

forms #新たに作成したフォルダ
├── __init__.py #新たに作成したファイル
├── forms.py #既存のファイル
└── profile_forms.py #既存のファイル

__init__.pyに追記する

__init__.pyに下記を追記します

from .forms import *
from .profile_forms import *

「forms.py」、「profile_forms.py」からすべて( * )をインポートしています

これを行うことで、他のファイルからは

from .forms import クラス名

として全てのクラスをインポートできるようになります

既存ファイルを編集する

forms.py、profile_forms.pyは、「forms」フォルダ内に入り、階層が一つ下がったため、それぞれの記述を下記の通り変更します

【forms.py】

from .models import User

from accounts.models import User

にします

【profile_forms.py】

from .models import Profile

from accounts.models import Profile

にします

これでモジュール化の完成です!

インポート先のファイルでの変更

最後に、モジュール化したため、views.py でのインポートも変更します

from .profile_forms import ProfileUpdateForm

from .forms import ProfileUpdateForm

にする

これで、目的別にファイルは分かれているため、探すのに時間がかかることもありません

また、インポートの際は「forms」から取得できるので、どのファイルに保存しているか記憶しておく必要はなくなりました

おわりに

いかがでしょうか?

今回お伝えしたかったのは、

  • 複数のクラスを一つのファイルにまとめる方法
  • 複数のファイルをモジュール化する方法
  • それぞれのインポート方法

についてです

今後もよりコードが複雑になる可能性があります

「どのファイルに特定のクラスや関数が書かれているかわからない!」「変更したいけどどこにあるんだっけ?」と探し回る時間が少しでも短くなればと、ファイル構成をスッキリさせる方法をご紹介しました

参考になれば幸いです

ただ、当アプリにはまだ問題が残っています

ログインしたユーザーのProfileが保存されていないと下記のエラーが出てしまいます

これはナビゲーションバーで設定しているリンクによって、エラーが発生しています

既存のユーザーについては、AdminページでProfileクラスを追加すればエラーは発生しませんが、今後新たにユーザー登録する場合はいかがでしょうか?

いちいち、AdminページでProfileを作成するわけにもいきません

この問題の解決策として、次回の記事では、シグナルを使ってProfileを自動作成する方法について解説していきます

タイトルとURLをコピーしました