1. Route matching
1. Notes on route matching
urlpatterns = [ url(r'^admin/', admin.site.urls), # front page url(r'^$',views.home), # Route matching url(r'^test/$',views.test), url(r'^testadd/$',views.testadd), # Last page (understand): Use exception capture processing later. Such a last page makes Django's second slash APPEND_SLASH=True in the path meaningless, and the mechanism of appending slashes in the second redirect is invalid. url(r'',views.error), ] ''' 1. The first parameter of the url method is a regular expression. As long as the first parameter regular expression can match the content, the matching will stop immediately and the corresponding view function will be called directly. 2. There is no need to add a leading backslash since every URL has one. For example, it should be ^test instead of ^/test. 3. The 'r' in front of each regular expression is optional but recommended. r means raw to identify the native string and declare that all characters in the modified string are ordinary characters. 4. When the regular matching mechanism does not match the desired content for the first time, it will add a slash \ after the matched content, and then Django will help you redirect internally and start matching again. 5. Each parameter captured by the regular match is passed to the view as an ordinary Python string. '''
2. Cancel route matching. If the first match is unsuccessful, add a slash\ after the matching content and redirect to match again
# Cancel the automatic addition of slashes: write the following content in the settings.py file APPEND_SLASH = False # The default is True to automatically add a slash
2. Group naming matching
1. Unnamed group
# Unnamed group: no need to define a name Route writing: url('^index/(\d + )', views.index) Internal logic: The content matched by the regular expression in the brackets will be passed as a positional parameter to the view function index bound to it. View function: def index(request,xx): print(xx) return HttpResponse('index')
2. Famous groups
# Famous group: need to define a name Route writing: url('^index/(?P<year>\d + )', views.index) Internal logic: The content matched by the regular expression in the brackets will be passed as a keyword argument to the view function index bound to it. View function: def index(request,year): print(year) return HttpResponse('index')
3. Can unknown and famous names be mixed?
# Also known as nameless groups, they cannot be mixed, but they can be used multiple times. url('^index/(\d + )/(\d + )/', views.index) url('^index/(?P<year>\d + )/(?P<year>\d + )/', views.index) # If used multiple times, if it is an unnamed group, *args can be used in the view function to receive parameters. def index(request, *args): print(args) return HttpResponse('index') # If it is used multiple times, if it is a famous group, you can use **kwargs in the view function to receive parameters. def index(request, **kwargs): print(kwargs) return HttpResponse('index')
3. Pass additional parameters to the view function (understand)
URLconfs has a hook that lets you pass a Python dictionary as an extra argument to the view function.
The django.conf.urls.url()
function can accept an optional third parameter, which is a dictionary representing additional keyword arguments that you want to pass to the view function.
For example:
from django.conf.urls import url from .import views urlpatterns = [ url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}), ]
In this example, for the /blog/2005/ request, Django will call views.year_archive(request, year=’2005′, foo=’bar’).
This technique is used in the Syndication framework to pass metadata and options to views.
4. Reverse analysis
Reverse parsing is also called reverse URL matching, reverse URL query or simple URL reverse lookup.
1. What is reverse analysis?
Reverse parsing is to obtain a result through some methods. The result can directly access the corresponding URL to trigger the view function.
2. Basic use of reverse analysis
Step one: Give the routing and view functions an alias in urls.py (note: the alias cannot be repeated and must be unique) url('^index/', views.index, name='xxx') Step 2: Use reverse parsing Use at the template level: {% url 'xxx' %} <a href="{% url 'ooo' %}">111</a> Use in view layer: from django.shortcuts import reverse reverse('xxx')
3. Reverse analysis of unknown and famous groups
3.1 Unnamed group reverse analysis
# Routing layer configures reverse parsing of unnamed packets url(r'^index/(\d + )/',views.index,name='xxx') # The template layer uses reverse parsing {% url 'xxx' 123 %} #The view layer uses reverse parsing reverse('xxx', args=(1, )) """ The number of routing layer url group matching mechanism is not hard-coded. Generally, the primary key value of the data is placed. We can locate the data object by obtaining the primary key value of the data. This allows the data to be edited and deleted, as shown in the following example: """ # Routing layer configures reverse parsing of unnamed groups url(r'^edit/(\d + )/', views.edit, name='xxx') #The view layer uses reverse parsing def edit(request,edit_id): reverse('xxx', args=(edit_id,)) # The template layer uses reverse parsing {% for user_obj in user_queryset %} <a href="{% url 'xxx' user_obj.id %}">Edit</a> {% endfor %}
3.2 Reverse analysis of famous groups
# Reverse parsing of famous groups url(r'^func/(?P<year>\d + )/',views.func,name='ooo') # The template layer uses reverse parsing The first way to write: <a href="{% url 'ooo' year=123 %}">111</a> The second way of writing: recommended <a href="{% url 'ooo' 123 %}">222</a> #The view layer uses reverse parsing The first way to write: print(reverse('ooo',kwargs={'year':123})) The second way of writing: print(reverse('ooo',args=(111,)))
4. Route distribution
''' Each application of Django can have its own templates folder, urls.py file, and static folder. Only based on the above characteristics, Django can achieve group development very well, that is to say, everyone only writes Just use the functions in your own app. Therefore, as a team leader, you only need to copy all the apps written by you to a new Django project, register all the apps in the configuration file, and then use the routing distribution feature to integrate all the apps. Therefore, when there are a lot of URLs in a Django project, the overall routing urls.py code is very redundant and difficult to maintain. At this time, route distribution can also be used to reduce the pressure on the overall routing. After using routing distribution, the overall routing no longer directly corresponds to the routing and view functions, but performs a distribution process to identify the application to which the current URL belongs, and finally distributes it directly to the corresponding application for processing. '''
General route:
from django.conf.urls import url from django.conf.urls import include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), # method one: from app01 import urls as app01_urls from app02 import urls as app02_urls url(r'^app01/', include(app01_urls)) # As long as the url prefix starts with app01, all will be handled by app01 url(r'^app02/', include(app02_urls)) # Method 2: Ultimate writing method recommended url(r'^app02/', include('app01.urls')) url(r'^app01/', include('app02.urls')) ] # Note: Do not use the format `^app01/$` in the main route, otherwise it cannot be distributed to sub-routes
Subroute settings:
# Configuration of urls.py in app01 from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^index/', views.index), ] # Configuration of urls.py in app02 from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^index/', views.index), ]
5. Namespace
Why do you need namespaces?
""" When multiple applications set the same alias and use reverse resolution, if the results are the same after matching the routing matching rules, It will appear that the later one overwrites the previous one. If you want to trigger the previous view function, you will not be able to access it. Under normal circumstances, reverse parsing cannot automatically identify the prefix. Note!!!: What is mentioned here is that under normal circumstances, if the number of URL groups corresponding to the reverse analysis is the same, then it can be identified. """
Configure namespace in total route:
from django.conf.urls import url from django.conf.urls import include urlpatterns = [ url('^app01/', include('app01.urls', namespace='app01')), url('^app02/', include('app02.urls', namespace='app02')), ]
The matching rules in the sub-route are the same as the alias:
# Configuration of urls.py in app01 from django.conf.urls import url from app01 import views urlpatterns = [ url('^reg/', views.reg, name='reg'), ] # Configuration of urls.py in app02 from django.conf.urls import url from app02 import views urlpatterns = [ url('^reg/', views.reg, name='reg'), ]
The sub-path uses reverse parsing:
# The view layer uses namespace syntax for reverse parsing reverse('app01:reg') reverse('app02:reg') # The template layer uses namespace syntax for reverse parsing {% url 'app01:reg' %} {% url 'app02:reg' %}
Additional: In fact, as long as the names do not conflict, there is no need to use namespaces
""" Generally, when there are multiple apps, we will add the app prefix when making an alias. In this way, we can ensure that there is no name conflict between multiple apps. """ urlpatterns = [ url(r'^reg/',views.reg,name='app01_reg') ] urlpatterns = [ url(r'^reg/',views.reg,name='app02_reg') ]
6. Pseudo-static
# What is a static web page? Static web page data is hard-coded and remains unchanged for thousands of years. # What is Pseudo-Static state? Pseudo-static is to disguise a dynamic web page as a static web page. # Why do we need pseudo-static? https://www.cnblogs.com/Dominic-Ji/p/9234099.html The purpose of pseudo-static is to increase the SEO query strength of this website and increase the probability of search engines collecting this website. (SEO’s full name is Search Engine Optimization) In fact, a search engine is essentially a huge crawler program. Summarize: No matter how you optimize and deal with Still can’t defeat RMB players
The routing layer uses pseudo-static: reg.html
# Routing configuration urlpatterns = [ url(r'^register.html', views.register), ] # Browser url access http://127.0.0.1:8002/app01/register.html/
7. Virtual environment
In normal development, we will equip each project with an interpreter environment unique to the project. In this environment, only the modules used by this project are not installed unless they are used. linux: install whatever is missing virtual environment Every time you create a virtual environment, it is like re-downloading a pure python interpreter. But don’t create too many virtual environments, as this will consume hard disk space. Extension: Every project requires many modules, and the versions of each module may be different. So how do I install it? Do you look at each one and pretend to be different? ? ? During development, we will provide each project with a requirements.txt file All the modules or versions of the project are written in it. You only need to directly enter a command to install all modules and versions with one click
8. Django version differences
1. The django1.X routing layer uses the url method, while in the django2.Xhe3.X version, the routing layer uses the path method
url() first parameter supports regular expressions The first parameter of path() does not support regular expressions. Whatever you write will match If you are used to using path, we also provide you with another method. from django.urls import path, re_path from django.conf.urls import url re_path(r'^index/',index), url(r'^login/',login) Tip: re_path in 2.X and 3.X is equivalent to url in 1.X
2. Although path does not support regular expressions, it internally supports five converters
path('index/<int:id>/',index) # Convert the matched content in <int:id> to int type first, and then pass it to the index view function bound to it as keyword parameters. def index(request,id): print(id,type(id)) return HttpResponse('index') str, matches a non-empty string except the path separator (/), which is the default form int, matches positive integers, including 0. slug, matches a string consisting of letters, numbers, dashes, and underscores. uuid, matches formatted uuid, such as 075194d3-6885-417e-a8a8-6c931e272f00. path, matches any non-empty string, including the path separator (/) (cannot be used?)
3. In addition to the default five converters, it also supports custom converters (understand)
class MonthConverter: regex='\d{2}' #The attribute name must be regex def to_python(self, value): return int(value) def to_url(self, value): return value #The matching regex is two numbers, and the returned result must also be two numbers. from django.urls import path,register_converter from app01.path_converts import MonthConverter # Register the converter first register_converter(MonthConverter,'mon') from app01 import views urlpatterns = [ path('articles/<int:year>/<mon:month>/<slug:other>/', views.article_detail, name='aaa'), ]
4. The 1.X foreign keys in the model layer are deleted by cascade update by default, but in 2.X and 3.X, you need to manually configure the parameters yourself
models.ForeignKey(to='Publish') models.ForeignKey(on_delete=models.CASCADE, on_update=models.CASCADE)
Supplement: The third parameter {} in the url
def url(regex, view, kwargs=None, name=None) ... #urls.py url(r'^third_params/', views.third_params, {'username': 'egon'}, name='third_params'), # views.py # def third_params(request, path): # Note: Pass parameters in keyword form def third_params(request, username): return HttpResponse(username) # username returns to the front-end page which is ego
9. Summary
# Route matching 1. The first parameter of the url method in urls.py is regular 2. By default, Django helps you enable the first matching failure. Append a slash / to the end of the matching path, and then redirect and re-traverse the loop to match again. Configuration: There is nothing in the default settings.py and you don’t need to add it yourself. APPEND_SLASH = False/True 3. Define homepage url matching rules: url('^$', views.home) 4. Define the last page url matching rules: url('', views.error) Tip: This method is generally not used for last pages. This method will invalidate jango's default APPEND_SLASH mechanism. We can then use exception handling as the content of the last page. #Group # Unnamed group: no need to define a name Route writing: url('^index/(\d + )', views.index) Internal logic: The content matched by the regular expression in the brackets will be passed as a positional parameter to the view function index bound to it. View function: def index(request, xxx): pass # Named group: need to define a name Route writing: url('^index/(?P<year>\d + )', views.index) Internal logic: The content matched by the regular expression in the brackets will be passed as a keyword argument to the view function index bound to it. View function: def index(request, year): pass # Precautions: Also known as nameless groups, they cannot be mixed, but a single type can be used multiple times. url('^index/(\d + )/(\d + )/', views.index) url('^index/(?P<year>\d + )/(?P<year>\d + )/', views.index) If used multiple times, if it is an unnamed group, *args can be used in the view function to receive parameters. def index(request, *args): pass If it is used multiple times, if it is a named group, you can use **kwargs in the view function to receive parameters. def index(request, *kwargs): pass # Reverse analysis # What is reverse parsing? Reverse parsing is to obtain a result through some methods. The result can directly access the corresponding URL to trigger the view function. # Use reverse analysis Step one: Give the routing and view functions an alias in urls.py (note: the alias cannot be repeated and must be unique) url('^index/', views.index, name='xxx') Part 2: Using reverse parsing Use at the template level: {% url 'xxx' %} <a href="{% url 'ooo' %}">111</a> Use in view layer: from django.shortcuts import reverse reverse('xxx') # Reverse analysis of unknown and famous groups # Reverse analysis of unnamed groups # Routing layer definition url(r'^index/(\d + ), views.index, name='index') # Template layer usage: {% url 'index' number %} # View layer usage: from django.shortcuts import reverse def index(request, xxx) reverse('index', agrs=(xxx, ) # Reverse parsing of famous groups # Routing layer definition url(r'^index/(?P<year>\d + ), views.index, name='index') # Template layer usage: {% url 'index' year=number %} {% url 'index' number %} # View layer usage: from django.shortcuts import reverse def index(request, year) reverse('index', kwagrs=({'year': number}) reverse('index', agrs=(number, ) # Unknown and named group reverse parsing usage scenarios Application: Generally used as primary key value Template layer application: reverse parsing by binding groups to the HTMl page, and when waiting for user submission, the primary key value of the user data is also carried. The view layer obtains the dynamic primary key values that are fed back from different operations, and models can use this primary key value to modify the current operation. Other data of the user for positioning. View layer application: redirection operation through reverse resolution # Note: The reverse parsing of unknown and named groups is the parsing of a single situation. For the parameters in reverse parsing, As long as the regular matching rules for routing are met. # Route distribution: # Parts that should be distributed: templates, urls.py, models.py #Advantages of route distribution: Routes do not conflict between multiple applications, reducing the pressure on the overall route and the problem of poor maintenance. Decoupling can better realize group development # General routing settings: from django.conf.urls import url from django.conf.urls import include urlpatterns = [ url(r'^admin/', admin.site.urls), # method one: from app01 import urls as app01_urls from app02 import urls as app02_urls url(r'^app01/', include(app01_urls)) # As long as the url prefix starts with app01, all will be handled by app01 url(r'^app02/', include(app02_urls)) # Method 2: Ultimate writing method recommended url(r'^app02/', include('app01.urls')) url(r'^app01/', include('app02.urls')) ] # Note: Do not use the format `^app01/$` in the main route, otherwise it will not be distributed to sub-routes. # Subrouting settings: # Configuration of urls.py in app01 from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^index/', views.index), ] # Configuration of urls.py in app02 from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^index/', views.index), ] # namespace # Why do we need namespaces? When the same alias is set for routes in multiple applications and reverse parsing is used, the latter one will overwrite the previous one. If you want to trigger the previous view function, you will not be able to access it. # Configure the namespace in the total route from django.conf.urls import url from django.conf.urls import include urlpatterns = [ url('^app01/', include('app01.urls', namespace='app01')), url('^app02/', include('app02.urls', namespace='app02')), ] # The matching rules in sub-routes are the same as the aliases # Configuration of urls.py in app01 from django.conf.urls import url from app01 import views urlpatterns = [ url('^reg/', views.reg, name='reg'), ] # Configuration of urls.py in app02 from django.conf.urls import url from app02 import views urlpatterns = [ url('^reg/', views.reg, name='reg'), ] # Subroutes use namespace syntax for reverse resolution # The view layer uses namespace syntax for reverse parsing reverse('app01:reg') reverse('app02:reg') # The template layer uses namespace syntax for reverse parsing {% url 'app01:reg' %} {% url 'app02:reg' %} # Supplement: In fact, as long as the names do not conflict, there is no need to use namespaces urlpatterns = [ url('^reg/', views.reg, name='app01_reg'), ] urlpatterns = [ url('^reg/', views.reg, name='app02_reg'), ] # Pseudo-static Static web page: web page data written to death Pseudo-static: Disguise dynamic web pages as static web pages Function: Improve the SEO query strength of the website and increase the probability of collecting web pages. -> Crawler search engine The routing layer uses pseudo-static: urlpatterns = [ url('^reg.html/', views.reg, name='app01_reg'), ] # Virtual environment deployment #django version difference 1. The routing layer of django1.x version uses the url method, while the routing layer of django2.x and 3.x uses the path method. 1.x version routing matching supports regular expressions Path in versions 2.x and 3.x does not support regular expressions. If you want to support regular expressions, import re_path. Although the url method is retained, its use is not recommended. 2. Although django2.x and 3.x versions do not support regular expressions, they internally support five converters. from django.urls import path path('index/<int:id>', views.index) Convert the matched content in <int:id> to int type first, and then pass it to the index view function bound to it as keyword parameters. 3. The converter supports customization 4. The 1.x default cascade update and cascade delete in the model layer, while the 2.x and 3.x versions need to be specified manually. publish = models.ForeignKey(to='Publish', on_update=models.CASCADE, on_delete=models.CASCADE)