unopinioned vs opinioned
这是个新词
意思就是 web框架的一种特点
scalable
scale 有点"尺寸"相关的概念 意思就是你的web应用 可大可小 适合很方便的调节 而不像传统的那种 牵一发而动全身
我们直接利用pycharm的terminal终端 无需cmd
找到 你想放置django工程的文件夹 比如我选定了django_MDN 文件夹
然后terminal 输入:
django-admin startproject locallibrary
locallibrary 是项目名称 你可以随便改
然后你就会看到这样的层级目录:
在manage.py 同级目录 terminal运行:
python manage.py startapp catalog
如果不行 试试
python3 manage.py startapp catalog
py manage.py startapp catalog
py-3 manage.py startapp catalog
之后就能看到pycharm的目录显示:
或者你dir 查看目录内文件 更可信:
我们的目录应该是现在这样的:
locallibrary/
manage.py
locallibrary/
catalog/
admin.py
apps.py
models.py
tests.py
views.py
__init__.py
migrations/
大部分文件都是可以顾名思义的
我们已经创建了一个名为catalog的应用
现在 我们在setting.py 中进行注册
找到 INSTALLED APP 这个列表 添加上catalog 如下:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth', # authentic 验证
'django.contrib.contenttypes',
'django.contrib.sessions', # session 会话
'django.contrib.messages',
'django.contrib.staticfiles',
'catalog'
]
可见django已经帮我们内置了一些应用 比如用户验证authentication 会话session 等
还是在setting.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "django", #数据库名字
'USER':'root', # 一般默认就是root
'PASSWORD':'2333', # 你的密码
'HOST':'localhost', # 我们现在还是本地服务器跑着学习 后面上真的云服务器
'PORT':'3306' # 端口号
}
}
你得在mysql创建一个空数据库,把名字填在“NAME”里面
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
如果是其他数据库 你可以参考官网
或者google csdn等等
database name
那边我们说过 url.py管得是url参数的映射 具体来说 我们用path()函数 将url的参数对应一个view(视图)
可以想象一下 我们通过一个url参数 比如\best
去查看NBA MVP的时候 肯定出来的是一个页面 也就是一个视图 所以path就是帮我们找到 我们要的网页
大概有三种用法 后面还会补充更多 这里只是混个脸熟:)
'^home'
匹配网址 path(r’^home’, views.home, name=‘home’)'catalog//'
匹配网址 path(r’‘catalog//’’, Home.as_view(), name=‘home’)catalog/任何字符/
里面的任何字符 也就是可以传参 然后用来 比如展现到你的前端网页上然后当你的path()太多的时候 我们直接用url pattern —— 一个列表 来装他们 于是我们也可以这么添加新的path
from django.urls import include
from django.urls import path
urlpatterns += [
path('catalog/', include('catalog.urls')),
]
urlpattern 这个列表包含所有path
注意 django已经默认给我们url pattern 加了一项:
urlpatterns = [
path('admin/', admin.site.urls),
]
这个意思就是 使用admin/
可以访问所有站点(site)上的url 也就是我们写在url pattern里面的一堆path
为啥要有这句?-- admin是管理者(我们)访问的 当然应该可以测试所有的url(也是我们写的url模式)
可以想象 假设你的网站有100个web应用 你应当怎么管理至少上百个url pattern?
很明显我们会把一些细小的url匹配模式 放到我们应用里面去 这就是我们必须在我们的应用catalog
里面
加上一个url.py 文件 内容如下:
from django.urls import path
from catalog import views
urlpatterns = [
]
那么 当浏览器请求的url 到达我们网站(site) 有点类似根目录 我们site会调用根目录的url.py
然后根目录的url.py就应该转发(或者说重定向redirect)到 应用catalog
的URL.py 也就是上面我们写的那个
问题是 如何写清楚“转发” 这个操作
我们在根目录的url.py 里面写上:
urlpatterns = [
path('admin/', admin.site.urls), #1
path('catalog/', include('catalog.urls')), #2
path('', RedirectView.as_view(url='/catalog/', permanent=True)), #3
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) #4
第二句就是 意思 你访问我网站的catalog 我就把这个请求转给catalog.urls 也就给catalog目录下的url.py处理
第三句很有意思
catalog/url.py
catalog/url.py
(从未见过如此厚颜无耻之徒)第四句 你或许这么访问过 提供vue.js 的官方网站
也就是地址栏输入网址 得到的是人家的源码
那么有没有想过 我们的服务器也可以这么提供我们写的前端代码呢?比如.html .js .css
这就是返回静态文件
当然Django倒是默认不支持这么弄 但是不方便我们debug
于是第四句就是搞定这个的——让我们的服务器也能返回 前端代码
总之 最后我们要往根目录urls.py 写的代码是:
from django.contrib import admin
from django import views
from django.urls import include
from django.urls import path
from django.views.generic import RedirectView
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls), #1
path('catalog/', include('catalog.urls')), #2
path('', RedirectView.as_view(url='/catalog/', permanent=True)),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) #4
这 是我们运行网站前的最后一步 :)
你会好奇 我们并没有进行任何数据库的编写 那么 为啥还迁移数据库呢?
事实上 django帮你写好了一部分数据库的结构 用于后续管理 (别找了 不在model.py里面^_^)
我们创建的应用 应用相关信息等等 都会保存在django自动创建的数据库中
另外 希望你别忘了
Django 使用对象关系映射器(ORM)将Django代码中的模型定义映射到底层数据库使用的数据结构。
那么 纯ORM 纯原生sql 或者两者混用都是ok得了 个人项目无所谓 团体项目 这个得沟通好:)
这里 我们要安装好 mysql-client 库 直接用pycharm安装就行
然后
我们在terminal 与manage.py 同级目录 逐行运行:
python manage.py makemigrations
python manage.py migrate
注意理解这个迁移过程:实际上 make migrations 只是通过我们ORM python代码 (model.py里面的) 转换成sql 语句 然后 真正执行操作的是 migrate
有种说法是 这个migrate 只是我们数据库版本控制(version control)的一个提纲(schema)而已
其他迁移的命令细节 可以看官网
如果我不放心他自动生成的那些sql怎么办 也就我不信任ORM呢?
我们可以查看他生成的代码
首先 找到所有的migrations
运行:
python manage.py showmigrations
admin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
[X] 0003_logentry_add_action_flag_choices
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
[X] 0008_alter_user_username_max_length
[X] 0009_alter_user_last_name_max_length
[X] 0010_alter_group_name_max_length
[X] 0011_update_proxy_permissions
catalog
(no migrations)
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
sessions
[X] 0001_initial
我们看到熟悉的auth
catalog
sessions
意味着这些都是 已经安装好的app (登记好的)
如果没有在setting登记 就会出现:
第二步 我们拿到app名称 还有相应的migrations的名字 就可以这样运行:
python manage.py sqlmigrate auth 0001
注意 这个migration原名贼长 幸好我们可用代号 0001
然后我们就得到了:
BEGIN;
--
-- Create model Permission
--
CREATE TABLE "auth_permission" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varch
ar(50) NOT NULL, "content_type_id" integer NOT NULL REFERENCES "django_content_type" ("id") D
EFERRABLE INITIALLY DEFERRED, "codename" varchar(100) NOT NULL);
--
-- Create model Group
--
CREATE TABLE "auth_group" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(80
) NOT NULL UNIQUE);
CREATE TABLE "auth_group_permissions" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "grou
p_id" integer NOT NULL REFERENCES "auth_group" ("id") DEFERRABLE INITIALLY DEFERRED, "permiss
ion_id" integer NOT NULL REFERENCES "auth_permission" ("id") DEFERRABLE INITIALLY DEFERRED);
--
-- Create model User
--
CREATE TABLE "auth_user" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "password" varchar
(128) NOT NULL, "last_login" datetime NOT NULL, "is_superuser" bool NOT NULL, "username" varc
har(30) NOT NULL UNIQUE, "first_name" varchar(30) NOT NULL, "last_name" varchar(30) NOT NULL,
"email" varchar(75) NOT NULL, "is_staff" bool NOT NULL, "is_active" bool NOT NULL, "date_joi
ned" datetime NOT NULL);
CREATE TABLE "auth_user_groups" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "user_id" i
nteger NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "group_id" integ
er NOT NULL REFERENCES "auth_group" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE "auth_user_user_permissions" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "
user_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "permi
ssion_id" integer NOT NULL REFERENCES "auth_permission" ("id") DEFERRABLE INITIALLY DEFERRED)
;
CREATE UNIQUE INDEX "auth_permission_content_type_id_codename_01ab375a_uniq" ON "auth_permiss
ion" ("content_type_id", "codename");
CREATE INDEX "auth_permission_content_type_id_2f476e4b" ON "auth_permission" ("content_type_i
d");
CREATE UNIQUE INDEX "auth_group_permissions_group_id_permission_id_0cd325b0_uniq" ON "auth_gr
oup_permissions" ("group_id", "permission_id");
CREATE INDEX "auth_group_permissions_group_id_b120cbf9" ON "auth_group_permissions" ("group_i
d");
CREATE INDEX "auth_group_permissions_permission_id_84c5c92e" ON "auth_group_permissions" ("pe
rmission_id");
CREATE UNIQUE INDEX "auth_user_groups_user_id_group_id_94350c0c_uniq" ON "auth_user_groups" (
"user_id", "group_id");
CREATE INDEX "auth_user_groups_user_id_6a12ed8b" ON "auth_user_groups" ("user_id");
CREATE INDEX "auth_user_groups_group_id_97559544" ON "auth_user_groups" ("group_id");
CREATE UNIQUE INDEX "auth_user_user_permissions_user_id_permission_id_14a6b632_uniq" ON "auth
_user_user_permissions" ("user_id", "permission_id");
CREATE INDEX "auth_user_user_permissions_user_id_a95ead1b" ON "auth_user_user_permissions" ("
user_id");
CREATE INDEX "auth_user_user_permissions_permission_id_1fbb5f2c" ON "auth_user_user_permissio
ns" ("permission_id");
COMMIT;
如果不放心 就这么检查
另外 除了我们在ugly的mysql客户端输入sql
我们也可以在sqlyog输入 就好像我们之前做的那样
当然 还可以调用sql在python的语言接口(implementation)
也就是调用pyMysql库 这是它的官方文档
这几乎就是真的写sql语句了其实 不再是ORM 对象关系映射(Object Relational Mapping)
python3 manage.py runserver
我们就这样运行网站吧 本地服务器 默认端口8000
你可以输入网址到地址栏: http://127.0.0.1:8000/
然后你就会拿到:
注意 这并不意味你成功了:)
忘了吗?我们的url映射把所有的皮球踢给了catalog/url.py
然而那玩意现在是空的:)
所以他说 你并没有做任何 configuration on urls pattern
解决问题 很简单 我们去配置咯
然后这个问题留给下一节 目前 我很享受看到django的小火箭 抖动的样子:)
你可以稍微配置一下:
找到根目录的setting.py:
把这两句改成中国:
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
然后启动服务器python manage.py runserver
中文版小火箭:
这一节 我们终于弄出来人生中第一个网站 虽然展现的是django送我们的小火箭
当然不用担心 这是我们的一小步 全栈领域的一大步
当然对于我来说 这篇文章这么长能够通过审核也是不容易
下一节 我们聊聊数据库的控制ORM