C:/python38
- python.exe
- Scripts
- pip.exe
- pip3.8.exe
- django-admin.exe
- Lib
- re.py
- site-pakages
- django
C:/python39
- python.exe
- Scripts
- pip.exe
- pip3.9.exe
- django-admin.exe
- Lib
- re.py
- site-pakages
- django
>>>C:/python39/Scripts/pip install django
django项目
>>>E:
>>>cd code
>>>C:/python39/Scripts/django-admin startproject mysite
目录结构
E:\code\mysite
- mysite
- urls.py URL和函数对应关系
- wsgi.py 底层请求处理入口【同步】
- asgi.py 底层请求处理入口【异步】
- settings.py 配置文件(内置配置文件global_settings假设200项配置 + 用户3项配置 =201配置)
- manage.py [管理项目]
运行项目
>>>cd mysite
>>>C:\python39\python manage.py runserver
对应关系 urls.py
from django.http import HttpResponse
def demo(request):
return HttpResponse("OK")
urlpattens = [
path("demo/",demo),
]
C:\python39
- python.exe
- Scripts
- pip.exe
- pip3.9.exe
- virtualenv.exe
- Lib
- re.py
- site-pakages
>>>C:\python39\pip install virtualenv
>>>C:\python39\Scripts\virtualenv F:\envs\x1 --python=python3.9
F:\envs\x1
- python.exe
- Scripts
- pip.exe
- pip3.9.exe
- activate.exe
- django-admin.exe
- Lib
- site-pakages
- django
- ..
>>>F:
>>>cd F:\envs\x1\
>>>activate.exe
(x1)>>>pip install django
(x1)>>>pip install django==3.2
(x1)>>>django-admin startproject mysite
E:\PycharmProjects\day002
E:\PycharmProjects\day002\.venv
注意:第2期,都是基于这种方式去创建项目。
本质:
(.venv) E:\PycharmProjects\day003>pip install django==3.2
(.venv) E:\PycharmProjects\day003>django-admin startproject day003
E:\PycharmProjects\day003\day003
- day003
...
- manage.py
(.venv) E:\PycharmProjects\day003>django-admin startproject day003 .
E:\PycharmProjects\day003
- day003
...
- manage.py
系统解释器 和 虚拟环境
命令行【线上部署】
安装virtualenv
创建虚拟环境
激活虚拟环境
安装django
pip install django
pip install django==3.2
创建新项目
django-admin startproject xxxx
编写代码
运行项目
python manage.py runserver
python manage.py runserver 8000
python manage.py runserver 127.0.0.1:8000
Pycharm【开发】
最新版本的django
注意事项:pycharm为了防止大家用低版本pycharm,例如:2020.1版本的pycharm
老旧版本的django
虚拟环境
安装老旧django
创建项目
django-admin startproject xxxx .
Pycharm配置:项目 + 环境
注意:requirements.txt
+ Python解释器(问、文档)
django内置有100个功能,5个功能是项目使用概率比较大。
Django纯净和Flask等轻量级框架的对比:
E:/PycharmProjects/day004
- day004
- urls.py URL和函数对应关系
- wsgi.py 底层请求处理入口【同步】
- asgi.py 底层请求处理入口【异步】
- settings.py 配置文件(内置配置文件global_settings假设200项配置 + 用户3项配置 =201配置)
- manage.py [管理项目]
INSTALLED_APPS = [
'django.contrib.admin', # django内置后台管理,简单数据库的增删改查
'django.contrib.auth', # 用户登录和认证权限
'django.contrib.contenttypes', # 复杂表结构关系
'django.contrib.sessions', # 如果项目中有登录成功让用户可以访问。
'django.contrib.messages', # 消息展示,依赖Session
'django.contrib.staticfiles', # 静态资源处理,图片、css、js等
]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# 找功能模块,将功能模块中需要创建表结构,创建出来。
>>>python manage.py makemigrations 【找功能模块】【表结构】【生成配置文件并放到指定目录】
>>>python manage.py migrate 【读取生成的配置文件,提交到数据库】
>>>python manage.py createsuperuser
纯净版配置:
# Application definition
INSTALLED_APPS = [
# 'django.contrib.admin',
# 'django.contrib.auth',
# 'django.contrib.contenttypes',
# 'django.contrib.sessions',
# 'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
# 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
# 'django.contrib.auth.middleware.AuthenticationMiddleware',
# 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
# 'django.contrib.auth.context_processors.auth',
# 'django.contrib.messages.context_processors.messages',
],
},
},
]
from django.contrib import admin
from django.urls import path
urlpatterns = [
# path('admin/', admin.site.urls),
]
创建的django项目:
E:/PycharmProjects/day004
- day004
- urls.py URL和函数对应关系
- wsgi.py 底层请求处理入口【同步】
- asgi.py 底层请求处理入口【异步】
- settings.py 配置文件(内置配置文件global_settings假设200项配置 + 用户3项配置 =201配置)
- manage.py [管理项目]
关于APP,主要用于业务功能模块的开发。
创建APP
python manage.py startapp app01
python manage.py startapp app02
E:/PycharmProjects/day004
- day004
- urls.py URL和视图函数对应关系
- wsgi.py 底层请求处理入口【同步】
- asgi.py 底层请求处理入口【异步】
- settings.py 配置文件(内置配置文件global_settings假设200项配置 + 用户3项配置 =201配置)
- manage.py [管理项目]
- app01
- migrations
- ..
- ...
- models.py 用ORM代替原生SQL语句(对类和对象进行操作 -> SQL语句 -> 自动执行)
编写类 + makemigraions/migrate -> 数据库
- apps.py "app01.apps.App01Config"
- admin.py 配合django-admin可以对当前app中的表进行增删改查操作。
- test.py 单元测试(不写单元测试)
- views.py 业务功能【视图函数】
- app02
- migrations
- models.py
- admin.py
- apps.py
- test.py
- views.py
注意:一般情况下一个app就够了;开源组件;公共模块,拆分到单独的app模块。
多app应用的目录结构:
单独1个app的项目 【推荐】
E:/PycharmProjects/day004
- day004
- urls.py URL和视图函数对应关系
- wsgi.py 底层请求处理入口【同步】
- asgi.py 底层请求处理入口【异步】
- settings.py 配置文件(内置配置文件global_settings假设200项配置 + 用户3项配置 =201配置)
- manage.py [管理项目]
- app01
- migrations
- ..
- ...
- models.py 用ORM代替原生SQL语句(对类和对象进行操作 -> SQL语句 -> 自动执行)
编写类 + makemigraions/migrate -> 数据库
- apps.py "app01.apps.App01Config"
- admin.py 配合django-admin可以对当前app中的表进行增删改查操作。
- test.py 单元测试(不写单元测试)
- views.py 业务功能【视图函数】
多个app
多个app,放在apps的文件夹中 【推荐】
E:/PycharmProjects/day004
- apps
- app01
- views.py
- admins.py
- models.py
...
- app02
- views.py
- admins.py
- models.py
...
- app03
- views.py
- admins.py
- models.py
...
- day004
- urls.py URL和视图函数对应关系
- wsgi.py 底层请求处理入口【同步】
- asgi.py 底层请求处理入口【异步】
- settings.py 配置文件(内置配置文件global_settings假设200项配置 + 用户3项配置 =201配置)
- manage.py [管理项目]
到底什么时候创建1个app?什么时候创建多个app?
案例1:公司官网
app01: -> 公司官网开发,主要使用者:学员。
app02: -> 内部运营使用的功能模块
app03: -> 导师下载作业、批改作业、评分。
案例2:公司官网【现阶段】
app01:
公司官网开发,主要使用者:学员。
内部运营使用的功能模块
导师下载作业、批改作业、评分。
app01: -> 公司官网开发,主要使用者:学员。
app02: -> 内部运营使用的功能模块
app03: -> 导师下载作业、批改作业、评分。
通俗的语言来表示:URL -> 函数对应关系
from django.urls import path, re_path
from apps.www import views
from django.urls import URLPattern
from django.urls.resolvers import RoutePattern
urlpatterns = [
URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None),
path('login/', views.login, name='n1'),
# http://127.0.0.1:8000/info/2222/
# http://127.0.0.1:8000/info/2222/?a1=1&b1=2
# path('info//', views.info),
# http://127.0.0.1:8000/other/11/yiyebaitou/
# http://127.0.0.1:8000/other/222/shiyi/
# path('other///', views.other),
# path('xx//', views.xx),
# path('xx//', views.xx),
# http://127.0.0.1:8000/yy/2014-11-11
# re_path(r'yy/(\d{4})-(\d{2})-(\d{2})/', views.yy),
]
编写路由
启动项目时
urlpatterns = [
对象(URL地址、函数),
对象(URL地址、函数),
对象,
对象,
对象,
URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None),
]
# 内部路由匹配的时,默认执行:
URLPattern.resolve
self.pattern.match()
return ResolverMatch(...)
# 进阶操作
# 路由系统中的扩展点:
URLPattern.resolve
RoutePattern.match
自定义ResolverMatch类
用户浏览器访问
http://127.0.0.1:8000/login/
django的源码内部,一定会匹配,获得相应的视图函数
http://127.0.0.1:8000 /login/
urlpatterns = [
对象(URL地址、函数),
对象(URL地址、函数),
对象,
对象,
对象
]
urlconf = 'day006.urls'
resolver = URLResolver(RegexPattern(r"^/"), urlconf)
resolver_match = resolver.resolve(request.path_info)
callback, callback_args, callback_kwargs = resolver_match
执行视图函数
听完的感受:
流程是懵逼,Django请求的流程懵逼【证明】。
我们需要基于源码记住
urlpatterns = [
path('login/', views.login),
path('info//' , views.info),
]
urlpatterns = [
URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None),
URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None),
URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None),
URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None),
]
源码内部路由匹配的时,是怎么做的?
URLPattern.resolve
RoutePattern.match
def resolve(self, path):
match = self.pattern.match(path)
if match:
new_path, args, captured_kwargs = match
# Pass any default args as **kwargs.
kwargs = {**captured_kwargs, **self.default_args}
return ResolverMatch(
self.callback,
args,
kwargs,
self.pattern.name,
route=str(self.pattern),
captured_kwargs=captured_kwargs,
extra_kwargs=self.default_args,
)
def match(self, path):
match = self.regex.search(path)
if match:
# RoutePattern doesn't allow non-named groups so args are ignored.
kwargs = match.groupdict()
for key, value in kwargs.items():
converter = self.converters[key]
try:
kwargs[key] = converter.to_python(value)
except ValueError:
return None
return path[match.end() :], (), kwargs
return None
path('login/', views.login, name='n1'),
URLPattern(RoutePattern("login/", name="n1", is_endpoint=True), views.login, None, "n1"),
def login(request):
return HttpResponse("欢迎登陆")
from django.urls import reverse
result = reverse("n1")
print(result) # "login/"
path('api/auth/login//' , views.login, name='n1'),
def login(request,v1):
return HttpResponse("欢迎登陆")
from django.urls import reverse
result = reverse("n1",kwargs={"v1":123})
print(result) # "/api/auth/login/123/"
result = reverse("n1",kwargs={"v1":999})
print(result) # "/api/auth/login/999/"
name存在的意义?例如:用户登录登录程序
/api/auth/login/ -> 函数登录
/api/user/account/ -> 函数账单
path('api/auth/login/', views.login, name='n1'),
path('api/user/account/', views.account, name='n2'),
def login(request):
# 当用户登录成功之后,需要让用户跳转到 /api/user/account/ 页面
# return redirect("/api/user/account/")
# url = reverse("n2") # "/api/user/account/"
# return redirect(url)
return redirect("n2")
def account(request):
return HttpResponse("用户信息")
name存在的意义?例如:权限管理
A用户有权访问的网址:
/api/auth/login/
/api/user/account/
/api/user/order/
/api/user/order//
B用户有权访问的网址:
/api/user/account/
/api/user/order/
/api/user/order//
A用户有权访问的网址:
n1
n2
n3
B用户有权访问的网址:
n2
n3
创建Django项目
app的概念
路由系统
【必备】常见路由操作
# http://127.0.0.1:8000/info/2222/
# http://127.0.0.1:8000/info/2222/?a1=1&b1=2
path('info//' , views.info),
# http://127.0.0.1:8000/other/11/yiyebaitou/
# http://127.0.0.1:8000/other/222/shiyi/
path('other///' , views.other),
# path('xx//', views.xx),
# path('xx//', views.xx),
# http://127.0.0.1:8000/yy/2014-11-11
re_path(r'yy/(\d{4})-(\d{2})-(\d{2})/', views.yy),
【必备】name别名
【可选】源码的流程+扩展点
MyURLPattern(MyRoutePattern("login/", name=None, is_endpoint=True), views.login, None, None),
URLPattern(RoutePattern("login/", name="n1", is_endpoint=True), views.login, None, "n1"),
django.urls.resolvers.URLResolver.resolve
django.urls.URLPattern.resolve
django.urls.resolvers.RoutePattern.match
django.urls.resolvers.URLResolver.resolve
for obj in ....:
# django.urls.URLPattern.resolve
# obj.resolve
# self.pattern.match
django.urls.resolvers.RoutePattern.match