Welcome to reprint, but please quote the original source at the beginning or end.
preface
Django and Flask are two of my favorite Python Web frameworks, but they are positioned very differently
-
Django -> “More is less”: Is “large and complete” heavyweight Web framework, its own a large number of common tools and components (such as database ORM components, user authentication, authority management, paging, cache), and even its own management background Admin, suitable for rapid development of functional enterprise website
-
Flask -> “Less is more”: a lightweight, extensible “micro” framework. By default, Django doesn’t have any of the tools and components that come with It, just a very simple and efficient “routing component” for Flask.
In ordinary days, do small tools small application what, the author still likes Flask, with the help of such small micro frame, can be lifted out in dozens of minutes.
But when it comes to writing larger applications, I usually go with Django. The main reason is that its ORM module is so good.
In Flask, SQLAlchemy is still the most used ORM framework, but I don’t think it’s as friendly as DjangoORM.
So the author came up with an idea: Flask + DjangoORM
starts
Manually creating a project
$ mkdir FlaskWithDjangoORM
Copy the code
withpip
Install the required dependency libraries
$ pip install flask django mysqlclient
Copy the code
Manually createapp
application
In a standard Django project, you use the $python manage.py startapp command to create a subapplication named app. The subapplication will typically have several files/directories in its directory:
migrations/
This directory holds database migration filesadmin.py
This file is related to the management backgroundapps.py
This file is related to the child application Settingsmodels.py
This file holds the database modeltests.py
This file holds the unit testsviews.py
This file holds the view-layer code
But if we were using Only Django’s ORM module, we would leave just migrations/ and models.py. So discard the command and create it manually:
$ cd FlaskWithDjangoORM
$ mkdir -p app/migrations
$ touch app/migrations/__init__.py
Copy the code
The app subapplication was initialized. Procedure
$ cat >> app/__init__.py <<EOF
import os
from django.apps import apps
from django.conf import settings
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
apps.populate(settings.INSTALLED_APPS)
EOF
Copy the code
Create a data model Visit to record the time of each Web request
$ cat >> app/models.py <<EOF
from django.db import models
class Visit(models.Model):
created_at = models.DateTimeField(auto_now_add=True, null=True)
EOF
Copy the code
insettings.py
Internal configuration of database connections (this article’s example usesMySQL
)
$ cat >> settings.py <<EOF
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'flask-with-django-orm-sample',
'USER': 'USERNAME',
'PASSWORD': 'PASSWORD',
'HOST': 'DATA_BASE_HOST',
'PORT': '3306',
'OPTIONS': {
'charset': 'utf8mb4',
# https://django-mysql.readthedocs.io/en/latest/checks.html#django-mysql-w002-innodb-strict-mode
'init_command': "SET sql_mode='STRICT_TRANS_TABLES', innodb_strict_mode=1",
},
}
}
INSTALLED_APPS = ('app',)
SECRET_KEY = 'SOME_SECRET_KEY'
EOF
Copy the code
configurationmanage.py
Management tool
This is carried over from a standard Django project (slightly changing the setdefault parameter)
$ cat >> manage.py <<EOF #! /usr/bin/env python """Django's command-line utility for administrative tasks.""" import os import sys def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings') try: from django.core.management import execute_from_command_line except ImportError as exc: raise ImportError( "Couldn't import Django. Are you sure it's installed and " "available on your PYTHONPATH environment variable? Did you " "forget to activate a virtual environment?" ) from exc execute_from_command_line(sys.argv) if __name__ == '__main__': main() EOFCopy the code
At this point, let’s look at the directory structure:
. ├ ─ ─ app │ ├ ─ ─ just set py │ ├ ─ ─ migrations │ │ └ ─ ─ just set py │ └ ─ ─ models. Py ├ ─ ─ the manage. Py └ ─ ─ Settings. PyCopy the code
These files alone are more than enough to run Django ORM
Synchronize the local data model to the database
Create migration files
$ python manage.py makemigrations
Migrations for 'app':
app/migrations/0001_initial.py
- Create model Visit
Copy the code
Perform the migration
$ python manage.py migrate
Operations to perform:
Apply all migrations: app
Running migrations:
Applying app.0001_initial... OK
Copy the code
Take a look at the database
mysql> show databases; +------------------------------+ | Database | +------------------------------+ | flask-with-django-orm-sample | | Information_schema | | mysql | + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 3 rows in the set (1.23 SEC)Copy the code
Select the database and list all the database tables
mysql> use flask-with-django-orm-sample; Database changed mysql> show tables; +----------------------------------------+ | Tables_in_flask-with-django-orm-sample | +----------------------------------------+ | app_visit | | django_migrations | + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 2 rows in the set (0.04 SEC)Copy the code
We can see that there is a migration table, django_migrations, which records all the records of the migration of data model changes.
If we query the table, we can see 0001_INITIAL exists, which corresponds to the migration file app/migrations/ 0001_Initial.py generated by running Names, Hoisting
mysql> select * from django_migrations; +----+-----+--------------+----------------------------+ | id | app | name | applied | +, + + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + | 1 | | 0001 app _initial 08:01:16. | 2020-12-20 | 618904 +, + + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 1 row in the set (0.22 SEC)Copy the code
Take a look at the structure of the app_visit table, which corresponds to the Visit we defined in app/models.py.
mysql> desc app_visit; +------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | created_at | datetime(6) | YES | | NULL | | +------------+-------------+------+-----+---------+----------------+ 2 Rows in set (0.25 SEC)Copy the code
createserver.py
As aflask
The master file
$ cat >> server.py <<EOF
from flask import Flask
from app.models import Visit
app = Flask(__name__)
@app.route("/")
def index():
Visit.objects.create()
return str(Visit.objects.count())
if __name__ == '__main__':
app.run()
EOF
Copy the code
Run server.py
$ python server.py
* Serving Flask app "server" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Copy the code
The test results
Multiple accesses on the new terminallocalhost:5000/
, you can see the return from1
Begin to increase in order
Check the program log
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) 127.0.0.1 - - [20/Dec/2020 09:52:56] "GET/HTTP/1.1" 200 - 127.0.0.1 - - [20/Dec/2020 09:52:58] "GET/HTTP/1.1" 200 - - [20/Dec/2020 09:53:00] "GET/HTTP/1.1" 200 - 127.0.0.1 - - [20/Dec/2020 09:53:03] "GET/HTTP/1.1" 200 - - [20/Dec/2020 09:53:03] "GET/HTTP/1.1" 200 - 127.0.0.1 - - [20/Dec/2020 09:53:04] "GET/HTTP/1.1" 200 - - [20/Dec/2020 09:53:05] "GET/HTTP/1.1" 200 - 127.0.0.1 - - [20/Dec/2020 09:53:07] "GET/HTTP/1.1" 200 - - [20/Dec/2020 09:53:07] "GET/HTTP/1.1" 200 - 127.0.0.1 - - [20/Dec/2020 09:53:08] "GET/HTTP/1.1" 200 - - [20/Dec/2020 09:53:12] "GET/HTTP/1.1" 200 - 127.0.0.1 - - [20/Dec/2020 09:53:14] "GET/HTTP/1.1" 200 - [20/Dec/2020 09:53:14] "GET/HTTP/1.1" 200 - 127.0.0.1 - - [20/Dec/2020 09:53:17] "GET/HTTP/1.1" 200 - [20/Dec/2020 09:53:17] "GET/HTTP/1.1" 200 - 127.0.0.1 - - [20/Dec/2020 09:53:18] "GET/HTTP/1.1" 200 - - [20/Dec/2020 09:53:19] "GET/HTTP/1.1" 200 - [20/Dec/2020 09:53:26] "GET/HTTP/1.1" 200 -Copy the code
Check the database again
mysql> select * from app_visit; +----+----------------------------+ | id | created_at | +----+----------------------------+ | 1 | 2020-12-20 09:52:56. 660151 | | 2 | 2020-12-20 09:52:58. 761042 | | 3 | 2020-12-20 09:53:00. 393140 | | | 4 09:53:01. 2020-12-20 811832 | | | 5 2020-12-20 09:53:03. 216767 | | | 6 09:53:04. 2020-12-20 471404 | | 7 | 2020-12-20 09:53:05. 639631 | | | 8 The 2020-12-20 09:53:06. 790564 | | | 9 09:53:07. 2020-12-20 823484 | | | 10 2020-12-20 09:53:08. | 836709 | | 2020-12-20 11 09:53:12. 069902 | | | 12 09:53:13. 2020-12-20 | 293624 | | 2020-12-20 13 09:53:14. 799734 | | | 14 2020-12-20 15 09:53:15. 993364 | | | 09:53:17. 2020-12-20 | 022426 | | 2020-12-20 16 09:53:18. 141073 | | | 17 2020-12-20 18 09:53:19. 499833 | | | 09:53:26. 2020-12-20 608735 | + + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 18 rows in the set (0.02 SEC)Copy the code
The access records in the log are exactly the same as the access records stored in the database, and you’re done! Knock it off and go to bed!