Catalog
- How to establish orm table relationship
- django request lifecycle flowchart
- url.py routing layer
- Route matching
- Anonymous group
- Named grouping
- Backward analysis
- Routing dissemination
- Namespace (namespace)
- Pseudo static
- virtual environment
- django version difference
- django backend get file object
How to establish orm table relationship
One-on-one
There are too many field information in a table. You can manually separate a table
One to many
The foreign key field is built on the side of many
Many to many
Many to many foreign key relationships need a third table for special processing
Take the library system as an example to create the book list, author list and publishing house list
Taking the book management system as an example, establish table relationships in django orm:
- For a one-to-one table relationship, foreign key fields can be built on either side, but it is recommended to build on the side with higher query frequency
- The book and publishing house are one to many relationships, and the book is one side of many, so the foreign key field is built in the book table
- The relationship between the book and the author is many to many. The foreign key field can be built on either side. It is recommended to build on the side with high query frequency
class Book(models.Model): title = models.CharField(max_length=32) # Eight decimal places in total, two decimal places price = models.DecimalField(max_digits=8, decimal_places=2) # The book and publishing house are one to many relationships, and the book is one side of many, so the foreign key field is built in the book table publish = models.ForeignKey(to='Publish') # To is used to indicate which table is related to. By default, the primary key field is associated # The relationship between the book and the author is many to many. The foreign key field can be built on either side. It is recommended to build on the side with high query frequency author = models.ManyToManyField(to='Author') # django orm will automatically help you create the third relationship table between the book and the author # The author field is a virtual field that can't be displayed in the table. It just tells orm to establish the third table relationship class Publish(models.Model): title = models.CharField(max_length=32) email = models.EmailField() class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() # For a one-to-one table relationship, foreign key fields can be built on either side, but it is recommended to build on the side with higher query frequency author_detail = models.OneToOneField(to='Author_detail') class Author_detail(models.Model): phone = models.BigIntegerField() addr = models.CharField(max_length=32)
Note:
- When one to many foreign key fields are created, they will be synchronized to the database, and the table fields will be automatically suffixed with "u id"; if you add "u id", another "u id" will be added later
- publish = models.ForeignKey(to='Publish ') the primary key id is associated by default. If the primary key is not an id, you can associate it yourself by adding to field = to the specified field
django request lifecycle flowchart
url.py routing layer
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'test/', views.test), url(r'testadd/', views.testadd) ]
If url.py is written in this way, the access path of test and testadd suffixes will return the same content for the following reasons:
- The first parameter of url is a regular expression
- Once it is ending immediately, the expression can match the content. It will immediately end the matching relationship and directly execute the subsequent corresponding function
Route matching
Start django, enter 127.0.0.1:8000/test in the browser, django will automatically add slash.
django matching routing law
Without slash (127.0.0.1:8000/test), first try to match. If it doesn't match, the browser will be redirected. Add a slash (127.0.0.1:8000/test /) to match again. If it doesn't match, an error will be reported.
Cancel the function of django to automatically slash the browser
In the configuration file, add:
APPEND_SLASH = False # This parameter defaults to True
Restrict the url of the specified input
urlpatterns = [ url(r'^admin/', admin.site.urls), # The first parameter of url is a regular expression url(r'^test/$', views.test), # Once it is ending immediately, the expression can match the content. It will immediately end the matching relationship and directly execute the subsequent corresponding function url(r'^testadd/$', views.testadd) ]
In this way, only 127.0.0.1:8000/test / or 127.0.0.1:8000/testadd can be entered/
Note: route matching only matches the URL part, and does not match the parameter after the parameter carried by get
Anonymous group
Anonymous grouping of regular expressions
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^test/([0-9]{4})', views.test), # Four numbers after test url(r'^testadd/', views.testadd) ]
When there is a regular expression in a packet in your route, when matching to the content to execute the view function, the content matched by the regular expression in the packet will be passed to the view function as a location parameter.
# In view function def test(request, xxx): print('Redundant parameters:', xxx) return HttpResponse('test view')
Named grouping
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^test/(\d+)/', views.test), url(r'^testadd/(?P<year>\d+)/', views.testadd) # Regular expression name grouping ]
When there are packets in your route and the packets are aliased, when matching the contents, the contents matched by regular expressions in the packets will be passed to the view function as key parameters
# In view function def test(request, year): print('Redundant parameters:', year) return HttpResponse('test view')
In this way, we can take advantage of the grouping of name and nameless, and we can pass additional parameters to the function before calling the view function
Note: name grouping and nameless grouping cannot be mixed, but in the same case, nameless grouping can be used multiple times, also known as namegrouping can also be used multiple times
Backward analysis
for instance:
# urls.py urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^test/(\d+)/', views.test), url(r'^testadd/(?P<year>\d+)/', views.testadd), url(r'^index/', views.index), url(r'^home/', views.home), ] # views.py def index(request): return render(request, 'index.html') def home(request): return HttpResponse('home')
In the above code, there are many jump links in the index.html page, all pointing to the home route. If you want to change the url address of your home, many links in the index.html page will change. Is there a way to bind the url address dynamically? Reverse parsing is.
Definition
Reverse parsing: dynamically parse a result according to an alias, which can directly access the corresponding url
There is no regular expression in the route, which is directly written to death
url(r'^home/', views.home,name='xxx'), # Alias the corresponding relationship between route and view function
Front end reverse parsing
<p><a href="{% url 'xxx'%}">111</a></p>
Back end reverse parsing
from django.shortcuts import render,HttpResponse,redirect,reverse def get_url(request): url = reverse('xxx') print(url) return HttpResponse('get_url')
Reverse analysis of nameless grouping
When parsing, you need to manually specify what the regular matching content is
url(r'^home/(\d+)/', views.home, name='xxx'),
Front end reverse parsing
<p><a href="{% url 'xxx' 12 %}">111</a></p>
Back end reverse parsing
def get_url(request): url = reverse('xxx', args=(1,)) url2 = reverse('xxx', args=(1231,)) print(url) print(url2) return HttpResponse('get_url')
The parameters passed in manually only need to be matched by regular expressions
Reverse parsing of named groups
url(r'^home/(?P<year>\d+)/', views.home, name='xxx'),
Front end reverse parsing
Can be grouped directly with nameless
<p><a href="{% url 'xxx' 12 %}">111</a></p>
Standard writing:
<p><a href="{% url 'xxx' year=121 %}">111</a></p>
Back end reverse parsing
Can be grouped directly with nameless
You can also write:
def get_url(request): url = reverse('xxx', kwargs={'year': 13123}) print(url) return HttpResponse('get_url')
Taking editing function as an example, the application of reverse parsing
# urls.py url = (r'^edit_user/(\d+)/', views.edit_user, name='edit') # views.py def edit_user(request, edit_id): # Edit? ID is the primary key value of the data that the user wants to edit pass
<!--page--> {% for user_obj in user_list %} <a href='/edit_user/{{user_obj.id}}/'>edit</a> <a href='{% url 'edit' user_obj.id %}'>edit</a> {% endfor %}
Routing dissemination
Premise:
All app s in django can have their own urls.py \ templates \ static It is because of the above characteristics that you can use django development project to completely achieve group development of multiple people without interfering with each other, and each person only develops their own app The team leader only needs to integrate all the app s developed by everyone into an empty django project, Then register in the settings configuration file and use routing distribution to integrate multiple app s to complete the splicing of large projects
Routing distribution solves the problem that there are too many routing matching relationships in the project,
Using route distribution, you will see:
- The total route no longer does matching work, but only does task distribution
- After the request comes, the total route does not have a corresponding relationship. Only ask which app function you want to access and then forward the request to the corresponding app for processing
Use:
Total route (include)
Just import urls.py of all app s
from django.conf.urls import url, include from app01 import urls as app01_urls from app02 import urls as app02_urls urlpatterns = [ url(r'^app01/', include(app01_urls)), url(r'^app02/', include(app02_urls)), ] # Routing dissemination
Subrouter
# app01 urls.py from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^reg/', views.reg), ] # app02 urls.py from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^reg/', views.reg), ]
The easiest way to write:
# Not even import url(r'^app01/',include('app01.urls')), url(r'^app02/',include('app02.urls'))
Namespace (namespace)
When there is an alias conflict in multiple apps, you can create a namespace for each app when you do routing distribution
Then you can choose which namespace to search for aliases in reverse resolution
In the total route:
url(r'^app01/',include('app01.urls',namespace='app01')), url(r'^app02/',include('app02.urls',namespace='app02'))
Front end:
<a href="{% url 'app01:reg' %}"></a> <a href="{% url 'app02:reg' %}"></a>
Backend:
print(reverse('app01:reg')) print(reverse('app02:reg'))
But it's not necessary. You just need to make sure that there is no conflict in the whole django project when you start aliasing
Pseudo static
It is to disguise a dynamic web page as a static web page, which can facilitate the search engine SEO (Search Engine Optimization) and improve the collection strength of the search engine.
virtual environment
Every time you create a virtual environment, it's like you download a pure python interpreter again
After that, you can install more than N virtual environments on one machine
django version difference
In urls.py, there are differences in the way of path matching
Django version 1.xx
url is used.
from django.conf.urls import url urlpatterns = [ url(r'^reg.html',views.reg,name='app01_reg') ]
Django version 2.xx
It's path
from django.urls import path urlpatterns = [ path('admin/', admin.site.urls), ]
- The first parameter of path here is neither regular nor regular
- Django 2. X also has a re path method, which is the url in Django 1. X
- path provides five converters to automatically convert the matched data to the corresponding type
- Custom converters are also supported
django backend get file object
What should be paid attention to in form expression
- method must be changed to post
- Change enctype to formdata format
# urls.py from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^upload/', views.upload) ] # views.py def upload(request): if request.method == 'POST': print(request.FILES) # django will automatically put the data of file type into request.FILES file_obj = request.FILES.get('myfile') # File object # print(file_obj) # print(file_obj.name) with open(file_obj.name, 'wb') as f: for line in file_obj: f.write(line) return render(request, 'upload.html')