DjangoビューとURL配布器

11326 ワード

表示:
ビューは一般的にappviews.pyに書かれています.ビューの最初のパラメータは、常にrequest(HttpRequest)オブジェクトです.このオブジェクトには、要求されたすべての情報が格納され、携帯パラメータやヘッダ情報などが含まれます.ビューでは、一般的に論理関連の操作を完了します.たとえば、このリクエストがブログを追加する場合、requestでこれらのデータを受信し、データベースに格納し、最後に実行した結果をブラウザに返すことができます.ビュー関数の戻り結果は、HttpResponseBaseオブジェクトまたはサブクラスのオブジェクトでなければなりません.サンプルコードは次のとおりです.
from django.http import HttpResponse
def book_list(request):
    return HttpResponse("    !")

URLマッピング:
ビューが書き終わったら、URLにマッピングします.つまり、ユーザーがブラウザにurlと入力したときに、このビュー関数を要求することができます.ユーザーがurlを入力して、私たちのウェブサイトに要求したとき、djangoはプロジェクトのurls.pyファイルから対応するビューを探します.urls.pyファイルにはurlpatterns変数があり、その後djangoはこの変数からすべての一致規則を読み出す.一致規則は、django.urls.path関数を使用してラップされる必要があります.この関数は、入力されたパラメータに基づいてURLPatternまたはURLResolverのオブジェクトを返します.サンプルコードは次のとおりです.
from django.contrib import admin
from django.urls import path
from book import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('book/',views.book_list)
]

URLにパラメータを追加するには:urlには、いくつかのパラメータが動的に調整される必要がある場合があります.例えば、ある文章の詳細ページのurlが、https://www.jianshu.com/p/a5aab9c4978eの後ろのa5aab9c4978eがこの文章のidであれば、簡書の文章の詳細ページのurlはhttps://www.jianshu.com/p/と書くことができ、そのうちidは文章のidである.では、djangoでこのようなニーズをどのように実現するか.このとき、path関数で、カッコの形式を使用してパラメータを定義することができます.たとえば、私が今本の詳細を取得したい場合は、urlでこのパラメータを指定する必要があります.サンプルコードは次のとおりです.
from django.contrib import admin
from django.urls import path
from book import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('book/',views.book_list),
    path('book//',views.book_detail)
]
views.pyのコードは次のとおりです.
def book_detail(request,book_id):
    text = "       id :%s" % book_id
    return HttpResponse(text)

もちろん、文字列をクエリーすることでパラメータを渡すこともできます.サンプルコードは次のとおりです.
urlpatterns = [
    path('admin/', admin.site.urls),
    path('book/',views.book_list),
    path('book/detail/',views.book_detail)
]
views.pyのコードは次のとおりです.
def book_detail(request):
    book_id = request.GET.get("id")
    text = "      id :%s" % book_id
    return HttpResponse(text)

後でアクセスするときは/book/detail/?id=1でパラメータを渡すことができます.
 
URLには別のurlsモジュールが含まれています.
私たちのプロジェクトでは、appが1つしかないわけではありません.appviewsのすべてのビューをurls.pyに配置してマッピングすると、コードが非常に乱れているに違いありません.したがって、djangoは、appの内部に独自のurlマッチング規則を含めることができ、プロジェクトのurls.pyにこのappを含むurlsをさらに統一する方法を提供する.この技術を使用するには、include関数を使用する必要があります.サンプルコードは次のとおりです.
# first_project/urls.py  :

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('book/',include("book.urls"))
]
urls.pyファイルでは、bookというappに関連するすべてのurlapp/urls.pyに移動し、first_project/urls.pyでは、include関数を介してbook.urlsを含み、bookに関連するurlを要求するときにbookのプレフィックスを追加する必要があります.
# book/urls.py  :

from django.urls import path
from . import views

urlpatterns = [
    path('list/',views.book_list),
    path('detail//',views.book_detail)
]

以降、本のリストのurlにアクセスする場合は、/book/list/にアクセスし、本の詳細ページのurlにアクセスする場合はbook/detail/にアクセスします.
 
path関数:path関数の定義は、path(route,view,name=None,kwargs=None)です.以下、これらのパラメータについて説明します.
  • routeパラメータ:urlの一致規則.このパラメータでは、urlに伝達する必要があるパラメータを指定することができ、例えば、文書詳細ページにアクセスするときにidを伝達することができる.伝達パラメータは、<>の括弧で指定されます.また、パラメータを渡す際に、このパラメータのデータ型を指定することができ、例えば、文章のidint型であれば、と書くことができ、後で一致すると、idint型であるurlにのみ一致し、他のurlには一致せず、ビュー関数でこのパラメータを取得する場合、int型に変換されましたいくつかの一般的なタイプがあります.
  • str:空でない文字列タイプ.デフォルトのコンバータ.ただし、スラッシュは含まれません.
  • int:任意のゼロまたは正数の整形に一致する.ビュー関数にはintタイプがあります.
  • slug:英語の横棒-、または下線_によって英語の文字または数字が接続された文字列.
  • uuid:uuid文字列に一致します.
  • path:空でない英語文字列に一致し、スラッシュを含めることができます.

  • viewパラメータ:ビュー関数または .as_view()またはdjango.urls.include()関数の戻り値です.
  • nameパラメータ:このパラメータはこのurlに名前を付けたもので、これはプロジェクトが大きく、urlが多いときに役に立ちます.
  • kwargsパラメータ:ビュー関数に追加のパラメータを渡したい場合は、kwargsパラメータで渡すことができます.このパラメータは辞書を受信します.ビュー関数に渡すと、キーワードパラメータとして渡されます.例えば、urlのルール:
  • from django.urls import path
     from . import views
    
     urlpatterns = [
         path('blog//', views.year_archive, {'foo': 'bar'}),
     ]
    その後blog/1991/というurlにアクセスするときにfoo=barをキーワードパラメータとしてyear_archive関数
  • に渡す.
     
    re_path関数:
    urlマッチングを書くときに、正規表現を使って複雑なニーズを実現するために書く場合があります.この場合、re_pathを使って実現することができます.re_pathのパラメータはpathのパラメータとそっくりであるが、最初のパラメータ、すなわちrouteのパラメータは正規表現であってもよい.re_pathを使用するいくつかの例示的なコードは、以下の通りである.
     
    from django.urls import path, re_path
    
        from . import views
    
        urlpatterns = [
            path('articles/2003/', views.special_case_2003),
            re_path(r'articles/(?P[0-9]{4})/', views.year_archive),
            re_path(r'articles/(?P[0-9]{4})/(?P[0-9]{2})/', views.month_archive),
            re_path(r'articles/(?P[0-9]{4})/(?P[0-9]{2})/(?P[\w-_]+)/', views.article_detail),
        ]

    include関数:
    プロジェクトが大きくなった後、すべてのurlマッチングルールをプロジェクトのurls.pyファイルに置くことはよくありませんが、各appには独自のurls.pyファイルがあり、このファイルには現在のappのすべてのurlマッチングルールが格納されています.その後、プロジェクトのurls.pyファイルに統一的に登録します.include関数には様々な使い方がありますが、ここでは2つのよく使われる使い方を説明します.
  • include(pattern,namespace=None):他のappurlsを直接含んでいます.サンプルコードは次のとおりです:
  • from django.contrib import admin
     from django.urls import path,include
    
     urlpatterns = [
         path('admin/', admin.site.urls),
         path('book/',include("book.urls"))
     ]

    もちろん、namespaceパラメータを渡してインスタンスネーミングスペースを指定することもできますが、インスタンスネーミングスペースを使用する前に、アプリケーションネーミングスペースを指定する必要があります.サンプルコードは次のとおりです.
    #  urls.py  :
    from django.urls import path,include
    urlpatterns = [
        path('movie/',include('movie.urls',namespace='movie'))
    ]

    次に、アプリケーションネーミングスペースをmovie/urls.pyに指定します.インスタンスコードは次のとおりです.
    from django.urls import path
    from . import views
    
    #       
    app_name = 'movie'
    
    urlpatterns = [
        path('',views.movie,name='index'),
        path('list/',views.movie_list,name='list'),
    ]
  • include(pattern_list):pathまたはre_path関数を含むリストまたはメタグループを含むことができる.
  • include((pattern,app_namespace),namespace=None):あるappurlsが含まれている場合、ネーミングスペースを指定することができます.これは、異なるappの下で同じurlが現れるのを防止するためであり、この場合、ネーミングスペースによって区別することができます.サンプルコードは次のとおりです:
  • from django.contrib import admin
     from django.urls import path,include
    
     urlpatterns = [
         path('admin/', admin.site.urls),
         path('book/',include(("book.urls",'book')),namespace='book')
     ]
  • しかし、このような前提は、アプリケーションネーミングスペースが含まれていることです.すなわち、myapp.urls.pyurlpatternsと同レベルの変数app_nameが追加される.

  • デフォルトのパラメータを指定します.pathまたはre_pathを使用すると、routeにパラメータを含めることができますが、デフォルトのパラメータを指定したい場合があります.この場合は、以下の方法で完了できます.サンプルコードは次のとおりです.
    from django.urls import path
    
    from . import views
    
    urlpatterns = [
        path('blog/', views.page),
        path('blog/page/', views.page),
    ]
    
    # View (in blog/views.py)
    def page(request, num=1):
        # Output the appropriate page of blog entries, according to num.
        ...
    blog/にアクセスすると、numパラメータが渡されないため、最初のurlに一致し、view.pageというビュー関数が実行され、page関数にはnum=1というデフォルトパラメータがあります.したがって,このときパラメータを渡さなくてもよい.一方、blog/1にアクセスすると、パラメータを渡すときにnumが渡されるので、2番目のurlに一致し、views.pageも実行され、渡されたパラメータをpage関数のnumに渡す.
    url反転:
    以前はurlでビュー関数にアクセスしていました.時々私たちはこのビュー関数を知っていますが、彼のurlに戻りたいと思っています.この場合、reverseによって実現することができる.サンプルコードは次のとおりです.
    reverse("list")
    > /book/list/
    

    適用ネーミングスペースまたはインスタンスネーミングスペースがある場合は、反転時にネーミングスペースを追加する必要があります.サンプルコードは次のとおりです.
    reverse('book:list')
    > /book/list/
    

    このurlでパラメータを渡す必要がある場合は、kwargsを介してパラメータを渡すことができる.サンプルコードは次のとおりです.
    reverse("book:detail",kwargs={"book_id":1})
    > /book/detail/1
    
    djangoのうちreverseurlを反転しているときはGET要求とPOST要求とを区別しないため、反転しているときにクエリー文字列のパラメータを追加することはできません.クエリー文字列のパラメータを追加する場合は、手動で追加するしかありません.サンプルコードは次のとおりです.
    login_url = reverse('login') + "?next=/"

    カスタムURL変換器:urlintなどを含むdjango内蔵のuuid変換器をいくつか学んだことがあります.これらの内蔵url は、私たちのニーズを満たすことができない場合があります.そのため、djangoは私たちに自分のurl変換器を定義するインタフェースを提供しています.
    カスタムurl変換器は、次の5つの手順で行えます.
  • はクラスを定義します.
  • は、regex変換器規則を保存するための正規表現であるクラス内の属性urlを定義する.
  • は、to_python(self,value)の値を変換してビュー関数に渡すurlメソッドを実現する.
  • は、to_url(self,value)を反転するときに、伝達されたパラメータを変換して正しいurlに接合するurl方法を実現する.
  • は、定義された変換器をdjangoに登録する.

  • たとえば、4つのデジタル年に一致するurl変換器を書きます.サンプルコードは次のとおりです.
        # 1.      
        class FourDigitYearConverter:
            # 2.          
            regex = '[0-9]{4}'
    
            # 3.   to_python  
            def to_python(self, value):
                return int(value)
    
            # 4.   to_url  
            def to_url(self, value):
                return '%04d' % value     
    
        # 5.    django 
        from django.urls import register_converter
        register_converter(converters.FourDigitYearConverter, 'yyyy')
        urlpatterns = [
            path('articles/2003/', views.special_case_2003),
            #         
            path('articles//', views.year_archive),
            ...
        ]