[toc]
新建应用,访问index
如何在 Windows 上安装 Django并创建应用 -无聊才读书 [1]
创建新的项目
django-admin.py startproject GameProject
cd GameProject
在项目目录创建templates目录,将模板网站资源(html、css、js、img)放入templates目录,确保有一个入口文件index.html。然后返回项目目录。
创建新的应用
python manage.py startapp game
修改game/views.py
from django.http import HttpResponse
from django.shortcuts import render
def index(request):
#return HttpResponse("Hello, world. You're at the polls index.")
return render(request,"index.html")
#返回要在网页上显示的信息
HttpResponse函数用来直接返回文本信息;
render函数专门用来加载网页模板,第一个参数位置写request参数,第二个写模板文件名。
有官方推荐的方式,和简单的方式
django官方文档[2]
有关urls的知识在下一节有介绍。
应用目录中创建urls.py文件:
vi urls.py
urls.py内容写入:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
修改GameProject/urls.py文件
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('game/', include('game.urls')),
path('admin/', admin.site.urls),
urlpartterns添加path('game/',include('game.urls')),
注意import include。
include的用途:
函数允许引用其他 URLconfs。 无论 Django 遇到什么 include(),它都会删除与该点匹配的 URL 的任何部分,并将剩余的字符串发送到包含的 URLconf 处进行进一步处理。[1]
当您包含其他 URL 模式时,您应该始终使用 include ()。 admin.site.urls 是唯一的例外。
修改GameProject/urls.py文件
from django.contrib import admin
from django.urls import path
from game import views
urlpatterns = [
path('game/', views.index),
path('admin/', admin.site.urls),
这就取消了应用目录内的二级路由,也不需要include(),直接由总路由控制url该访问视图中的哪个方法。
修改GameProject/settings.py
'DIRS'代表整个工程的模板文件目录的路径。
'APP_DIRS'表示是否启用应用内模板目录,默认状态就是使用应用目录内的templates文件夹。
如果将'DIRS'省略,则需要将网页模板文件放在应用目录下的templates目录下,当'APP_DIRS'为True可正常使用。
在本例中,这里写成DIRS:[os.path.join(BASE_DIR,"templates")],
或者DIRS: [BASE_DIR+'/templates'],
让项目知道我们自定义的工程模板文件目录的位置。两种写法的区别在于前者不需要斜杠,跨操作系统的适应性更好。
启动服务器,外网可访问,使用80端口(默认只能内部访问,使用8000端口)。需要保证当前端口未占用
python manage.py runserver 0:80
内网使用localhost,外网可以使用ip/域名网址+/game来访问刚刚配置好的静态网页,例如:http://62.234.114.108/game
通过urls访问多个模板网页
目前,通过“index/”这个Url可以访问到“game”应用中的“index.html”文件。如果想通过url访问多个html文件,就需要多个url路由。有关urls的知识在下一节有介绍。
一级路由方案
有一种可行的简单的方法如下,在工程目录的urls.py中这样写:
from django.contrib import admin
from django.urls import path
from helapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('input/', views.input),
在应用的views.py中这样写:
from django.shortcuts import render
def index(request):
return render(request,"index.html")
def input(request):
return render(request,"input.html")
这样,只要index能正常访问,input在index的同目录下,那么它就也能访问。
这样偷了个懒,不需要使用“include()”也不需要使用应用里的“urls.py”。这不是官方推荐的方案,但可以用。
多级路由方案
官方建议的方案,对于多应用的大中型项目更有利。总路由把url直接传递给匹配的分路由,再由分路由指定views。这样的话,一个一级url只能对应一个应用,想在同一个应用里访问到多个网页,可以对url做多次路由。
在工程目录的urls.py中,把input的路由去掉:
urlpatterns = [
path('admin/', admin.site.urls),
# path('input/', include('helapp.urls')),
path('index/', include('helapp.urls')),
"include()"的使用,使得前面匹配完成的字段抹消掉,路由目的地"helapp.urls"只会收到"index/"后面的字段。
在应用的urls.py中:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index),
path('input', views.input),
这两个"path"就分别对应"localhost/index"和"localhost/index/input"两个url。使得调用views.py中调用不同的方法,从而返回不同的页面。
在应用的views.py中:
from django.shortcuts import render
def index(request):
return render(request,"index.html")
def input(request):
return render(request,"input.html")
使用django上线完整静态网站
上面的方法只能展示单独的html文件,若此文件有静态css、js、img文件的链接,因为没有写对应的路由,所以无法直接调用,网站会显示不正常。
官方给出的方法是静态资源与模板文件存放在不同的路径,通常是在应用目录下有templates和static文件夹(也可以自定义指定其他路径)。模板文件表示可以进行动态传参,而静态文件只能是模板文件的附属,只能让模板文件调用,后端不可操作其内容。
官方正常操作
欲使用静态文件目录,先打开工程同名目录下的“settings.py”,将最末尾改为如下示例:
STATIC_URL = '/static/'
之后将准备好的与html文件相匹配的css文件放入应用目录下的static目录。(实测,修改好了上面的示例后,静态文件放在工程目录下的static也可以)
要链接这个css文件,则要在html文件中设置以下代码:[2]
{% load static %}<link rel="stylesheet" type="text/css" href="{% static 'style.css' %}">
这里{% load static %}代表这里提示需要一个静态文件,{% static 'style.css' %}代表从规定的静态文件目录中找这个路径。
如果事先写好的静态网站有许多静态文件的调用,则修改会很繁琐。但如果是静态文件互相调用,则可以简单很多,比如在css文件中使用图片:
body {background: white url("images/background.gif") no-repeat;}
但如果html文件中有许多<img>
图片需要用src链接,只能一个一个改。以至于我想偷个懒——
偷懒简单操作
如果把网站中的index.html文件也看作静态资源,即可用最少的修改完成完整静态网站的上线。以下是步骤:
在app目录下创建static文件夹,将现有的整个网站模板放入。注意,刚才的templates是在工程总目录下创建。
打开工程同名目录下的“settings.py”,将最末尾改为如下示例:
STATIC_URL = '/static/'
修改templates目录下的index.html文件,可使用链接、跳转等形式。跳转的方法网上有很多,这里举出几个例子:
<head> {% load static %}
<meta http-equiv="refresh" content="0;url= {% static 'index.html' %} ">
</head> <!-- meta跳转 -->
<script language="javascript" type="text/javascript">
{% load static %} window.location.href='{% static 'index.html' %}';
</script><!-- script跳转 -->
{% load static %} <!-- 链接跳转 -->
<a href="{% static 'index.html' %}">跳转连接</a>
如此,应该能正常显示整个模板网站了。其实这是基于static目录可以直接访问。但实际使用不推荐这样做,因为首先静态html无法传递动态参数,其次使网站资源都可以通过url无脑地进行静态访问并不是一种很好的习惯。
通过请求views加载静态资源
如果不想一个一个修改网页内的url,也不想纯静态访问,其实可以让后端处理每个url访问请求。虽然不同的url很多,但是格式都有规律。使用正则表达式解析url, 可以找到需要的静态文件并返回。正则表达式的详细使用见下一节
在urls文件中,导入re_path,并使用正则匹配变量,并交给views的方法:
from django.urls import path, re_path
from . import views
urlpatterns = [ # 第一个参数是路径,第二个参数是视图,第三个是参数
re_path(r'(?P<fl_name>\w+)\.html$', views.pt_htm),
re_path(r'(?P<kind>\w+)/(?P<fl_name>.*)\.(?P<fmt_name>\w+)$', views.pt_stc),
path('', views.index),
在views中这样写(注意导包):
from django.shortcuts import render
from django.http import HttpResponse
import os
from hello import settings
# Create your views here.
def index(request):
return render(request, "index.html")
def pt_htm(request, fl_name):
return render(request, fl_name + '.html')
def pt_stc(request, kind, fl_name, fmt_name):
path = os.path.join(settings.BASE_DIR,
"helapp/static/" + kind + "/{}".format(fl_name + '.' + fmt_name)) # 路径
with open(path, 'rb') as s:
data = s.read()
if fmt_name == 'jpg':
return HttpResponse(data, content_type="image/jpg")
elif fmt_name == 'png':
return HttpResponse(data, content_type="image/png")
# elif fmt_name == 'css':
# return HttpResponse('', content_type="text/css")
elif fmt_name == 'js':
return HttpResponse(data, content_type="application/x-javascript")
注意,关于css的请求我注释掉了,因为我找的这个网站模板还使用了静态资源字体文件,调用字体文件时有url参数,不好解析,所以css的调用还是在html中用{%load static%}
为好(详情见前文)。
在static/css中新建一个index.css文件,用于收集其他css文件。只要在这里引用了其他所有的css文件,网页只要链接这一个css就可以了。index.css内写法举例如下:
@import "style.css";
@import "style1.css";
在每个html文件中合适的位置加入:
{%load static%}
<link href="{%static 'css/index.css'%}" rel="stylesheet" type="text/css" media="all" />
应该是要删掉其他的css link的,因为views里没有对应的处理那些url的代码,不删会报错。如果不想费事在html里一个一个删的话,把上面views注释的部分解注释,让其返回的是空字符串而不是data,浏览器就不会报错了。这样做也不会影响到load static的css。