Django - routing configuration

Routing is simply to judge the corresponding handler according to the URL link requested by the user and return the processing result, that is, the URL establishes a mapping relationship with the view of Django, and the root routing file of Django is specified in the setting.py file

ROOT_URLCONF = 'demo.urls'

Django1.x version

url() method: both normal path and regular path can be used. You need to add regular restriction symbols manually

from django.conf.urls import url
from . import views

urlpatterns = [
    # Normal path http://127.0.0.1:8888/index
    url(r'^index/$', views.index), 
    # Regular path http://127.0.0.1:8888/re_test/1234/
    url(r'^re_test/([0-9]{4})/$', views.re_test), 
]

Django version after 2.2. X

path() method: it is used for ordinary paths. You do not need to manually add regular first limit symbols. The bottom layer has been added

re_path() method: used for regular paths. You need to manually add regular first limit symbols

from django.urls import path, re_path
from . import views

urlpatterns = [
    # Normal path http://127.0.0.1:8888/index
    path('index/', views.index),
    # Regular path http://127.0.0.1:8888/re_test/2021/
    re_path(r'^re_test/([0-9]{4})/$', views.re_test),
]

Summary: url in Django 1.1. X and re in Django 2.2.x_ Path is used in the same way

"/" at the end of the route

URL  http://127.0.0.1:8000/blog
 On the server side xxx Call file, xxx/Called directory(Or path)
When you don't add a backslash at the end,this URL Point to/blog,That's 127.0.0.1:8000 Lower blog file
 At this time, the browser works in 127.0.0.1:8000 Next look blog file,If the file does not exist, look for a directory with the same name as the file,Namely blog/(That explains why there is a 301 redirect to http://127.0.0.1:8000/blo/)
When we add a backslash at the end,Just leave out the search blog File this step,Direct search blog/Directory, much more efficient

Extract URL

Regular path anonymous grouping: anonymous grouping passes parameters by location. In the views function, except for request, the number of other formal parameters should be consistent with the number of packets in urls, one-to-one correspondence

# In urls.py file
from django.conf.urls import re_path
from . import views

# re_ Path (path, view function name)
urlpatterns = [
    # http://127.0.0.1:8000/re_test_1/shanghai/2019/
    re_path(r'^re_test_1/([a-z]+)/(\d{4})/$', views.re_test_1),
]

# In views.py file
from django.http import HttpResponse
def re_test_1(request, city, year):  # City - > ([A-Z] +) extracted parameter year - > (\ D {4}) extracted parameter
    return HttpResponse(f"re_test_1: {city} {year}")

Regular path name grouping: in Python regular expressions, the syntax for naming regular expression groups (? P < name > pattern), where name is the group name,   Pattern is the pattern to match

# In urls.py file
from django.conf.urls import re_path
from . import views

# re_ Path (path, view function name)
urlpatterns = [
    # http://127.0.0.1:8000/re_test_2/guangzhou/2021/
    re_path(r'^re_test_2/(?P<city>[a-z]+)/(?P<year>\d{4})/$', views.re_test_2),
]

# In views.py file
from django.http import HttpResponse
def re_test_2(request, city, year): # City - > (? P < City > [A-Z] +) extracted parameter year - > (? P < year > \ D {4}) extracted parameter
    return HttpResponse(f"re_test_2: {city} {year}")

Nested parameters:   Regular expressions allow nested parameters, which Django will process and pass to the view; When converting, Django will try to populate all external snap parameters, ignoring any nested snap parameters

# In urls.py file
from django.conf.urls import re_path
from . import views

urlpatterns = [
    # http://127.0.0.1:8000/re_test_1/city-shanghai/2019/
    re_path(r'^re_test_1/(city-([a-z]+))/(year-(\d{4}))/$', views.re_test_1),

    # http://127.0.0.1:8000/re_test_2/city-guangzhou/year-2021/
    re_path(r'^re_test_2/(?P<citys>city-(?P<city>[a-z]+))/(?P<years>year-(?P<year>\d{4}))/$',views.re_test_2)
]

# In views.py file
from django.http import HttpResponse

# City - > (city - [A-Z] +) extracted parameter year - > (\ D {4}) extracted parameter
# Parameters extracted by cities - > (city - ([A-Z] +)) parameters extracted by year - > (year - (\ D {4}))
def re_test_1(request, citys, city, years, year): 
    return HttpResponse(f"re_test_1: {citys}  {city}  {years}  {year}")


# City - > (? P < City > [A-Z] +) extracted parameter year - > (? P < year > \ D {4}) extracted parameter
# Cities - > (? P < cities > City - (? P < City > [A-Z] +)) extracted parameters years - > (? P < years > year - (? P < year > \ D {4})) extracted parameters
def re_test_2(request, city, citys, year, years): 
    return HttpResponse(f"re_test_2: {city} {citys} {year} {years}")

Note: each nested parameter regularly matches two parameters captured by each

Route distribution (include)

Multiple app directories in Django project share one urls, which is easy to cause confusion and inconvenient for later maintenance. Use route distribution (include) to make each app directory have its own urls

1. Create a urls.py in each app directory

two   In the urls file under the project name directory, uniformly distribute the path to each app directory.

# In urls.py
from django.contrib import admin
from django.urls import path,include # Introduce include from django.urls
urlpatterns = [
    path('admin/', admin.site.urls),
    path("users/", include("users.urls")),
    path("blog/", include("blog.urls")),
]

In their respective app directories, write their own urls.py file to jump the path.

users Directory:

# In users.urls.py
from django.urls import path, re_path 
from users import views # Import views from your app directory 
urlpatterns = [ 
    re_path(r'^login/(?P<m>[0-9]{2})/$', views.index),
] 

blog Directory:

# In blog.urls.py
from django.urls import path, re_path
from blog import views   # Import views from your app directory 
urlpatterns = [ 
    re_path("^xxx/(?P[0-9]{4})/$", views.xxx), 
]

When Django meets   include() It cuts out any part of the URLconf that matches that point and sends the remaining string to the included URLconf for further processing.

through the use of   path()   A list of instances to include other URL patterns

from django.urls import include, path

from users import views as blog_views
from apps.blog import views as users_views

extra_patterns = [
    path('login/', users_views.login),
    path('logout/', users_views.logout),
    path('user_info/', users_views.user_info),
]

urlpatterns = [
    path('users/', include(extra_patterns)),
    path('blog/', include('blog.urls')),
]

In the example above, / users/login/URL will be handled by the Django view users.views.login()

This method can be used to remove redundancy in URLconf, where a schema prefix is reused

from django.urls import path
from . import views

urlpatterns = [
    path('<page_slug>-<page_id>/login/', views.login),
    path('<page_slug>-<page_id>/logout/', views.logout),
    path('<page_slug>-<page_id>/user_info/', views.user_info),
    path('<page_slug>-<page_id>/history/', views.history),
]

We can improve it by declaring the common path prefix only once and grouping the following parts:

from django.urls import include, path
from . import views

urlpatterns = [
    path(
        '<page_slug>-<page_id>/', 
        include(
            [
                path('login/', views.login),
                path('logout/', views.logout),
                path('user_info/', views.user_info),
                path('history/', views.history),
            ]
        )
    ),
]

Captured parameters

The included URLconf will receive any parameters captured from the parent URLconf, so the following example is legal:

# In settings/urls/main.py
from django.urls import include, path

urlpatterns = [
    path('<username>/blog/', include('foo.urls.blog')),
]

# In foo/urls/blog.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.blog.index),
    path('archive/', views.blog.archive),
]

In the above example, the captured   "username"   The variable will be passed as expected to the URLconf pointed to by include()

Reverse resolution of URL

In Django project, a common requirement is to obtain the final form of URL, such as embedded in the generated content (view and resource URL, showing the URL to users, etc.) or user server-side navigation processing (redirection, etc.). It is strongly recommended not to hard code URLs (this is a laborious, non extensible, error prone idea)

# In urls.py
from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # URL (path, include ((application path, application name), namespace = routing namespace)
    url(r'^users/', include(('users.urls', "Users"), namespace="users")),
]


# In users.urls.py
from django.conf.urls import url, re_path
from . import views

# Re_path (path, view function name, name = alias for route)
urlpatterns = [
    # http://127.0.0.1:8000/users/query_test/
    re_path(r'^get_query_params/$', views.query_test, name="query"),
    # http://127.0.0.1:8000/users/redirect_test/
    re_path(r'^redirect_test/$', views.redirect_test),
]


# In users.views.py
def query_test(request):
    return HttpResponse(f"query_test")

# redirect
def redirect_test(request):
    # Redirect to the query_test view through the applied namespace + function alias reverse resolution
    print("reverse:  ",  reverse("users:query"))
    return redirect("users:query")

Code above, access http://127.0.0.1:8000/users/redirect_test/ Redirect to http://127.0.0.1:8000/users/query_test/

Tags: Django

Posted on Mon, 20 Sep 2021 19:36:31 -0400 by dv_evan