ホーム>source

私は初心者で、Djangoを使用してプロジェクトに取り組んできました。 同じコードを繰り返すのを避ける良い方法があるかどうか疑問に思っています。 また、いくつかの機能に同様のロジックがある場合、ロジックが編成されているかどうかをどのように判断できますか。

例えば、

def entry_list(request):
    entry_list = Entry.objects.all()
    #this part is repeated
    page = request.GET.get('page', 1)

    paginator = Paginator(entry_list, 10)
    try:
        entries = paginator.page(page)
    except PageNotAnInteger:
        entries = paginator.page(1)
    except EmptyPage:
        entries = paginator.page(paginator.num_pages)
    return render(request, 'blog/entry_list.html', {'entries': entries})

ページネーションのロジックは、他のいくつかの関数でも繰り返されます。

繰り返しコードをどこに置くべきか、コードを整理する必要があるかどうかを判断するにはどうすればよいですか

あなたの答え
  • 解決した方法 # 1

    を使用して機能ベース 景色

    あなたは出来るカプセル化する 別の関数で(たとえば、そのような関数を utils.py という名前のファイルに作成します) ):

    # in app/utils.py
    def get_page_entries(entry_list, page, per_page=10):
        paginator = Paginator(entry_list, per_page)
        try:
            return paginator.page(page)
        except PageNotAnInteger:
            return paginator.page(1)
        except EmptyPage:
            return paginator.page(paginator.num_pages)
    
    

    その後、次のように使用できます。

    # app/views.py
    from app.utils importget_page_entries
    def entry_list(request):
        entry_list = Entry.objects.all()
        entries=get_page_entries(entry_list, request.GET.get('page', 1))
        return render(request, 'blog/entry_list.html', {'entries': entries})
    
    

    オプションの3番目のパラメーターにページごとの要素数を指定できます。指定しない場合、デフォルトで10になります。

    または、 request.GET.get(..) をカプセル化できます  次のようなロジックも:

    # in app/utils.py
    def get_page_entries(entry_list,querydict, per_page=10, key='page', default_page=1):
       page = querydict.get(key, default_page)
        paginator = Paginator(entry_list, per_page)
        try:
            return paginator.page(page)
        except PageNotAnInteger:
            return paginator.page(default_page)
        except EmptyPage:
            return paginator.page(paginator.num_pages)
    
    

    したがって、次のように呼び出します。

    # app/views.py
    from app.utils import get_page_entries
    def entry_list(request):
        return render(request, 'blog/entry_list.html', {
            'entries': get_page_entries(Entry.objects.all(),request.GET)
        })
    
    
    を使用してクラスベース 景色

    ただし、あなたはじゃない 関数ベースのビューを使用する必要があります。このユースケースは、 ListView  クラス[Django-doc]:

    class EntryListView(ListView):
        model = Entry
        template_name = 'blog/entry_list.html'
        context_object_name = 'entries'
       paginate_by = 10
    
    

    そして、 urls.py で 、 EntryListView.as_view() を使用  関数の代わりに、そう:

    # app/urls.py
    from django.urls import path
    from app.views import EntryListView
    urlpatterns = [
        path('entries',EntryListView.as_view(), name='entry-list'),
    ]
    
    

    コードの行数を減らしただけであることに注意してください。宣言的 開発方法:指定する代わりにどうやって 私たちは何かをしたい、私たちは指定します やりたい。 Djangoの ListView の実装次第です。 。さらに、設定をクラスの属性として提供することにより、これらのパラメーターを考慮したツールを簡単に開発できます。

  • 解決した方法 # 2

    私は次のようないくつかのことについて同じ質問を自問しました。

    関数 私は自分の意見で何度も使うかもしれませんが、

    メッセージ ビューで何度も使用しますが、テストも行います(アプリの動作をテストするため)。

    例外 多くのモデルやビューで使用できますが、

    選択肢 値が特定の値のみになるCharfieldsを定義する場合、

    環境 多くのテンプレートで使用できる値、

    ここで私が例えばどのように働くか:

    関数utils.py  ウィレムが言ったように、このファイルは

    メッセージ:私は customMessages.py を持っています  そのために使用されるファイル、ここでは単純なメッセージを定義します(例: SUCCESS_M_CREATE_OBJECT=_("You created this object successfully.") 、次に customMessages.SUCCESS_M_CREATE_OBJECT を呼び出して使用  私のモデル、テスト、またはビューで)またはより複雑なもの、たとえば関数によって定義され、 lambda で呼び出される可変フィールド  私のテストでは、

    環境context_processors.py で専用関数を定義することにより  コンテキスト変数の辞書を返し、それらを私の settings.py に登録する  そして、テンプレートで何かを呼び出したい場合は大丈夫です、

    さて、PythonとDjangoで行うことを繰り返し行わない方法が常にあります。開発中はいつでもこれらの質問を自問するのが適切です。

関連記事

  • 前へ java - JPAクエリ:サブクエリをグループ化条件に結合する
  • 次へ python - 新しい結果を予測するときにモデル入力ケラスをチェックするときのエラー