catalogue
- preface
- Tips – Django version differences
- Route matching
- Anonymous group & named group
- Anonymous grouping
- Named grouping
- Tips
- Reverse parsing
- Routing does not involve reverse parsing of packets
- Reverse parsing of named group & nameless group
- Routing distribution
preface
When the client browser accesses the Django backend, it will first perform route matching in the routing layer through the gateway and middleware. Only after the route matching is successful can the logic in the corresponding view function be executed for data processing. This paper introduces how the routing layer (taking diango1. X version as an example) performs route matching?
Tips – Django version differences
There are some differences between django1. X and django2. X and later versions. One of the differences is the routing expression of the routing layer. The differences between the routing expressions are shown in the following table:
difference | django1.x | django2.x or 3.x |
---|---|---|
method | URL methodfrom django.conf.urls import url |
Path methodfrom django.urls import path |
URL parameter | The first argument supports regular expressions | The first argument does not support regular expressions |
If URL parameters are used to regular expressions, Django in versions 2. X and 3. X also provides another method re_ Path, which is equivalent to the path in Django 1. X.
#Urls.py for django2. X
from django.contrib import admin
from django.urls import path,re_path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index',views.index),
re_path('^index/\d+',views.index),
]
Route matching
Here, we use Django 1. X to explain how Django performs route matching? In Django 1. X, the correspondence between the route and the view is realized through the URL method, and the regular expression of the first parameter URL of the URL method. As long as the URL accessed by the client browser can successfully match a route, it will immediately stop the route after matching and directly execute the first matched view function, which will cause a problem, Such as the following code:
urlpatterns = [
url(r'test',views.test),
url(r'testadd',views.testadd),
]
#127.0.0.1:8080 / testadd will match the first route directly and will never run the following testadd page
How to solve the above problems? You can specify what the regular expression of the route must start and end with, and the regular expression cannot be empty. Otherwise, it will match all URLs and make subsequent pages inaccessible. Therefore, the following solutions can be adopted when using the URL of the regular expression:
urlpatterns = [
#For the first page, the regular expression cannot be blank, otherwise it will match all URL suffixes, resulting in the inaccessibility of the following pages
url(r'^$',views.home),
#^ refers to what the matching character must start with and $refers to what the matching character must end with
url(r'^test/$',views.test),
url(r'testadd/',views.testadd),
]
Anonymous group & named group
First, what group? Grouping simply means to enclose a regular expression in parentheses. Nameless grouping simply means that the regular expression after grouping has no name, while famous grouping means that the regular expression after grouping has a name~ What a deep understanding…
Anonymous grouping
Anonymous grouping will pass the content matched by the regular expression in parentheses after grouping to the corresponding view function as a location parameter.
# urls.py
urlpatterns = [
URL (r'test / (\ D +) ', views. Test), # \ D + indicates a matching number
]
# views.py
Def test (request, XX): # parameter XX can be arbitrary
print(xx)
return HttpResponse('test')
If 127.0.0.1:8000 / test / 100 is accessed in the browser (the number can be arbitrary), 100 will be output in the pycharm terminal. If the formal parameter XX is not added to the view function test, an error will be reported. The error information is as follows:
TypeError: test() takes 1 positional argument but 2 were given
The test function has only one formal parameter, but it gives two arguments, so you must add one formal parameter to receive another argument. The other argument is what the regular expression in the nameless group matches.
Named grouping
This is to give an alias to the grouped regular expression, and pass the content matched by the regular expression in parentheses to the corresponding view function as a keyword parameter.
# urls.py
urlpatterns = [
URL (r'test / (? P < ID > \ D +) ', views. Test), # \ D + represents the matching number, and ID is the name of the grouped regular expression
]
# views.py
Def test (request, ID): # when using a named group, the name of the formal parameter of the view function must be consistent with the name of the named group
print(id)
return HttpResponse('xx')
If you access 127.0.0.1:8000 / test / 100 in the browser (the number can be arbitrary), 100 will be output in the pycharm terminal. If the name of the formal parameter in the view function test is inconsistent with the name of the famous group, an error will be reported. The error information is as follows:
TypeError: test() got an unexpected keyword argument ‘id’
The test function gets a keyword parameter ID that it doesn’t need. Therefore, when using a named group, the formal parameters of the view function must be consistent with the name of the named group.
Tips
Famous and nameless packets cannot be used at the same time, but each packet can be reused multiple times. At the same time, there must be a corresponding number of formal parameters in the view function to receive values.
url(r'test/(\d+)/(\d+)/(\d+)',views.test)
url(r'test/(?P<id1>\d+)/(?P<id2>\d+)/(?P<id3>\d+)', views.test)
Reverse parsing
The front-end browser sends a URL request. The URL will match to a view function responsible for the request (some parameters may be provided to the view function at the same time). This is a positive match.
Starting from the alias of the view function binding relationship (some parameters may be required), the process of finding a complete URL is the reverse. The so-called resolution is to obtain a complete URL by adding some parameters to the alias (or the alias of the URL matching relationship or the alias of the URL pattern).
Forward match: URL ——————————–> View function (+ parameter)
Reverse resolution: alias (parameter) ———————————-> url
The purpose of using reverse parsing is to obtain a URL in the front-end HTML page more conveniently, avoid hard coding and reduce the complexity of program maintenance. So how to use reverse parsing? Using reverse parsing is divided into two steps:
① Set an alias for the route in the route matching file urls.py;
② Use aliases in view functions or in HTML pages.
The use of reverse resolution can also be divided into two cases: one is when the routing does not involve packets, and the other is the reverse resolution of famous packets and nameless packets.
Routing does not involve reverse parsing of packets
First, you need to set an alias for the correspondence between routing and view functions in urls.py. The code is as follows:
urlpatterns = [
re_path('index/', views.index, name='index'),
re_ The path ('test / ', views. Test, name ='test') # route corresponds to the view function. The alias name is test. It can be arbitrary but must be unique
]
After setting the alias of the corresponding relationship between the route and the view function, you can reverse parse it on the back-end or front-end HTML page and obtain the URL through the alias.
#Views.py - reverse parsing in the back-end view function. Dynamic parsing needs to be realized with the help of modules
from django.shortcuts import render, redirect, HttpResponse, reverse
# Create your views here.
def index(request):
return HttpResponse('index')
def test(request):
return redirect(reverse('index'))
When the above code accesses 127.0.0.1:8000 / test /, it will be redirected through the test function, and the redirected URL is the index / route obtained by reverse parsing through the reverse method.
Of course, on the front-end HTML page, you can also perform reverse parsing through the template syntax. Similarly, you can find the corresponding relationship through the alias, parse the URL, and then execute the corresponding view function.
# views.py
from django.shortcuts import render, redirect, HttpResponse
# Create your views here.
def index(request):
return HttpResponse('index')
def test(request):
return render(request, 'render_html.html')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href={% url 'index' %}>click me</a> <!-- Resolve the back-end alias through the syntax format of {% URL 'alias'%}, and click to jump to index / route -- >
</body>
</html>
Reverse parsing of named group & nameless group
The reverse resolution of famous and nameless packets is somewhat different from that without grouping. The settings of the reverse resolution of famous and nameless packets in url.py are the same as those without grouping. They both use the parameter name to alias the corresponding relationship between routing and view functions, However, in the case of packets, not only the alias but also the data required in the regular expression packets need to be routed during reverse parsing. In the case of named packets, there are two ways to provide data during reverse parsing, both at the front end and at the back end, one of which is the common way of named packets and nameless packets.
Let’s first look at the reverse parsing of anonymous groups:
# urls.py
urlpatterns = [
re_path('index/(\d+)', views.index, name='index'),
re_path('test/', views.test, name='test')
]
-----------------------------------------Anonymous packet back-end reverse parsing-------------------------------
#Views.py - back end reverse parsing
def index(request, x):
return HttpResponse('index')
def test(request):
#The parameter must be in the form of tuple, and the parameter must be able to match the grouping part in the regular expression, otherwise an error will be reported. Reverse for 'func' with no arguments not found. 1 pattern (s) tried: ['index / (\ \ D +)']
return redirect(reverse(viewname='index', args=(1,)))
-----------------------------------------Anonymous packet front end reverse parsing--------------------------------
# views.py
def index(request, x):
return HttpResponse('index')
def test(request):
return render(request, 'render_html.html')
# render_html.html
<body>
< a href = {% URL 'index' 1%} > Click me < / a > #{% URL alias grouping matching parameter%}
</body>
Next, let’s look at the direction resolution of famous groups. There are two ways to implement the reverse resolution of famous groups. The first is consistent with the nameless group, and the other code is as follows:
# urls.py
urlpatterns = [
re_path('index/(?P<id>\d+)', views.index, name='index'),
re_path('test/', views.test, name='test')
]
----------------------------------------Name group reverse parsing - back end reverse parsing-----------------------
# views.py
def index(request, id):
return HttpResponse('index')
def test(request):
#The parameter matching the name group is the format of the dictionary. The key of the dictionary is the name of the name group
return redirect(reverse(viewname='index', kwargs={'id': 2}))
--------------------------------------Name group reverse parsing - front end reverse parsing-------------------------
# views.py
def index(request, id):
return HttpResponse('index')
def test(request):
return render(request, 'render_html.html')
# render_html.html
<body>
< a href = {% URL 'index' id = 2%} > Click me < / a > #{% URL alias name group name = group matching parameter%}
</body>
Routing distribution
Each application of Django can have its own urls.py/templates folder / static folder. Based on this, Django can achieve group development very well. Everyone can only write the application part they are responsible for. So how can different applications be integrated together? You only need to copy all applications to a new Django project (we’ll talk about it later in Git collaborative development…) then register all applications in the configuration file, and finally integrate all applications with routing distribution, * * routing distribution is to identify which application the current URL belongs to, and then directly distribute it to the corresponding application for further processing** To use route distribution, you need to create urls.py under each application, which is called sub route. The original urls.py is called general route. For example, two applications are created in a Django project, first and second. Route distribution can be realized in the following ways:
----------------------------Sub route file---------------------------------------------------
#Urls.py under first application - first_ django/first/urls.py
from django.conf.urls import url
from first import views
urlpatterns = [
url(r'^index/', views.index),
url(r'^test/', views.test),
]
#Urls.py under second application - first_ django/second/urls.py
from django.conf.urls import url
from second import views
urlpatterns = [
url(r'^index/', views.index),
url(r'^test/', views.test),
]
-----------------------------------------Total routing file--------------------------------------
# first_django/first_django/urls.py
from django.conf.urls import url,include
from django.contrib import admin
from firstp import urls as first_url
from second import urls as second_url
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^first/',include(first_url)),
url(r'^second/',include(second_url))
]
After using route distribution, access the URL under different applications. The route must indicate which application the route belongs to. For example, access 127.0.0.1:8000 / first / test, which means to reach the general route through the first for route distribution, and then match the test / part in the first application. When the total route is used for route distribution, the regular expression parameter of URL () cannot end with $, but must end with /.
The above general routing file also has a simplified version of code, which directly includes the sub route string without importing the sub route, as follows:
-----------------------------------------Total routing file--------------------------------------
# first_django/first_django/urls.py
from django.conf.urls import url,include
from django.contrib import admin
# from firstp import urls as first_url
# from second import urls as second_url
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^first/',include('first.urls')),
url(r'^second/',include('first.urls'))
]
This is the end of this article on how to get the correct URL for Django routing layer. For more information about how to get the URL for Django routing layer, please search the previous articles of developeppaer or continue to browse the relevant articles below. I hope you will support developeppaer in the future!