共计 14187 个字符,预计需要花费 36 分钟才能阅读完成。
基础知识
什么是django?
Django是一个基于 Python 的高级 Web 开发框架, 特点: 高效,快速,高度集成(不用自己弄底层),免费,开源
上网的流程
输入 URL→向目标 url 发送 http 请求→服务器把页面响应给浏览器(通过后台编写的代码处理请求)→浏览器解析 获取到的页面源代码文档(所以看到的不是html 文档)→看到网页
目录结构
- 项目项目目录结构.
├── manage.py 与项目进行交互的命令行工具集的入口(项目管理器)
└── myblog 项目的一个容器,包含项目最基本的一些配置(不建议修改名称,会影响配置文件)
├── __init__.py声明模块的文件(默认为空,使myblog 为一个模块,可以直接在代码中引用)
├── settings.py 配置文件
├── urls.py配置页面url
└── wsgi.py(Python Web Server Gateway Interface 服务器网关接口,python 应用与 Web 服务器之间的接口,)
manage.py
如 root@localhost ~]#python manage.py runserver(直接输入python manage.py 可以列出命令选项)
settings.py
项目的总配置文件,包含了数据库、web 应用、时间等各种配置文件
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
#项目的跟目录
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'qkotgzdcj-n!q#1@pwv7cyya!5$cuvqp3d=vrljrbuo48qvr5b'
#启动项目所必须的安全码
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
#调试,打开后异常会反馈给用户页面
ALLOWED_HOSTS = ['192.168.230.129']
#只允许外界通过【】内的地址访问
# Application definition
INSTALLED_APPS = ['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'zzb',
]
#组成项目的应用,自己创建的应用需加进去
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',
]
#中间件,自带的工具集
ROOT_URLCONF = 'blog.urls'
#url 的根文件,指向 urls.py
TEMPLATES = [
{'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'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',
],
},
},
]
#模板(html 文件)配置
WSGI_APPLICATION = 'blog.wsgi.application'
#把 myblog 当做一个模块
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {'default': {# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.MySQL',
'NAME':'blog',
'USER':'root',
'PASSWORD':'',
'HOST':'',
'PORT':'',
'OPTIONS':{'autocommit':True,
},
}
}
#数据库配置,使用其他数据库需改动
# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
#密码认证
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL = '/static/'
#静态文件的地址
STATIC_ROOT = '/var/www/html/blog/zzb/static/'
- 应用的目录结构
.├── admin.py (该应用的后台管理系统配置(django 自带一个后台管理系统,每个应用都有各自的配置文件)
├── apps.py 该应用的一些配置,1.9 版本后才有。
├── __init__.py
├── migrations 数据迁移模块
│ └── __init__.py(有这个文件说明它是一个模块)
├── models.py 数据模块(在其中创建数据表)使用 ORM 框架,类似于 MVC 结构中的 Models( 模型)
├── tests.py 自动测试模块,在这里编写测试脚本(语句)
└── views.py 执行响应的逻辑代码所在的模块,决定了接受web 的请求后如何响应(项目中大部分在这里编写)
正式开始创建博客系统
搭建环境(建议源码安装, 这里为了简便介绍 yum | pip 安装)
Python
- linux 自带 Python,无需安装,
- 低于2.7 的版本与最新的 Django 不兼容
Django(自带一个小型的服务器)
安装(二选一)
- a) pip 安装(需要本地有 python-pip)
[root@localhost ~]#pip install Django==1.10.2
- b) 下载源码(执行效率更高),进入源码目录执行[root@localhost ~]#python setup.py install
判断安装是否完成
[root@localhost ~]# python -m django –-version
MySQL
yum install mariadb mariadb-server
mysql 的使用请参考其他教程, 这里不作介绍
将 Django 部署到 Apache 服务器上
安装mod_wsgi(yum install mod_wsgi)
创建第一个项目
用 django-admin 创建项目
在 /var/www/html 目录下:
[root@localhost ~]#django-admin startproject blog(新命令 django-admin) 会在 /var/www/html/ 下生成一个新的文件夹blog
用 manage.py 创建应用
[root@localhost ~]#python manage.py startapp zzb
添加应用名到 settings.py 中的INSTALLED_APP 里,
INSTALLED_APPS = ['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'zzb',
]
修改 settings.py, 输入 linux 本机 ip
ALLOWED_HOSTS = ['192.168.230.129']
创建第一个页面(响应)
- 修改 apache 配置文件 (/etc/httpd/conf/httpd.conf), 修改配置文件后重启 apache
在最后添加:
WSGIScriptAlias / /var/www/html/blog/blog/wsgi.py
WSGIPythonPath /var/www/html/blog
LoadModule wsgi_module modules/mod_wsgi.so
ErrorLog "logs/error_log"
<Directory /var/www/html/blog/blog>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
systemctl restart httpd
- 配置 wsgi.py, 因为 使用的不是django 自带的服务器,而是 apache,若配置相同则不需要修改
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "blog.settings")
application = get_wsgi_application()
- 编辑 zzb/views
# Create your views here.
from django.http import HttpResponse
def index(request):
return HttpResponse('hello,world')
每个函数必须返回一个响应,函数必须存在一个参数,一般约定为 request,对应一个 URL
- 配置 urls.py( 每个url 都以 url 函数的形式写在 urlpatterns 列表中。三个参数(URL(正则),对应响应方法,名称 zzb 为应用名)
from django.conf.urls import url
from django.contrib import admin
import zzb.views as bv
urlpatterns = [url(r'^admin/', admin.site.urls),
url(r'^index/',bv.index),
]
- 打开页面(192.168.230.129/index)
hellow,world
URL配置增强
- 修改blog 下的 url(注意 url 后面的 / 问题), 引入include
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [url(r'^admin/', admin.site.urls),
url(r'^blog/',include('zzb.urls') ),
]
- 在 app(zzb) 下新建urls.py
from django.conf.urls import url
from . import views
urlpatterns = [url(r'^index/$',views.index),
]
- 启动 Apache, 关闭防火墙
systemctl start httpd
systemctl stop firewalld
- 浏览器输入地址: http://192.168.230.129/blog/index/
hello,world
创建第一个 Templates( 模板)
- 在 APP 根目录下创建名叫 templates(小写) 的目录,
- 在 templates 目录下创建以 app 名为名称的目录, 将 html 文件放入其中( 解决templates 冲突)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" >
<title>Title</title>
</head>
<body>
<h1>Hello,Blog</h1>
</body>
</html>
- 在views.py 中返回 render()
Models(模型)
一个 model 对应一张数据表, 以类的形式表现, 包含类一些基本字段以及数据的一些行为. ORM(object relation mapping) 对象关系映射, 不需要编写 SQL 语句
- 在settings.py 中修改, 使用 MySQL 代替 django 自带数据库.
DATABASES = {'default': {# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.mysql',
'NAME':'blog',
'USER':'root',
'PASSWORD':'',
'HOST':'',
'PORT':'',
'OPTIONS':{'autocommit':True,
},
}
}
- 在数据库中创建名为blog 的数据库
在 MySQL 中执行:
CREATE DATABASE blog;
- pip安装pymysql 插件
- 修改blog/__init__.py, 添加
import pymysql
pymysql.install_as_MySQLdb()
- 应用根目录下创建 models.py, 并引入 models 模块 , 创建类, 继承 models.Model, 类即是一张数据表, 在类中创建字段
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=32, default='Title')
content = models.TextField(null=True)
def _unicode_ (self):
return self.title
- 生成数据表
[root@localhost ~]#python manage.py makemigrations
[root@localhost ~]#python manage.py migrate(会在app/migrations/ 目录下生成移植文件)
可以通过执行 [root@localhost ~]#python manage.py sqlmigrate 应用名 文件 id( 查看SQL 语句)
- 往数据库中写入数据
INSERT INTO zzb_article VALUE('1','2','3');
- 取出数据
views.py中
1 # -*- coding: utf-8 -*-
2 from __future__ import unicode_literals
3
4 from django.shortcuts import render
5
6 # Create your views here.
7 from django.http import HttpResponse
8 from . import models
9
10 def index(request):
11 article = models.Article.objects.get(pk=1)
12 return render(request,'zzb/index.html',{'article':article})
- 页面呈现数据
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{article.title}}</h1>
<h3>{{article.content}}</h3>
</body>
</html>
Admin(自动化数据管理界面)
可直接在admin 中管理数据库
- [root@localhost ~]#python manage.py createsuperuser
- 进入192.168.230.129/admin 登录
- 更改语言 , 修改 settings.py 中LANGUAGE_CODE=‘zh_Hans’
- 配置应用
在应用下的 admin.py 中引入自身的models 模块(或者里面的模型类)
在应用目录下的admin.py 中做如下修改
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
from models import Article
# Register your models here.
admin.site.register(Article)
- 修改数据默认显示的名称
编辑应用下 models.py, 在 Article 类下添加一个方法, 根据 Python 版本(3/2.7) 选择_str_(self)或_unicode_(self)
- 关于admin 页面没有 css 样式的解决办法
1. 去 djando 的解压包里的 /doc/howto/static-files 中查看帮助文档, 找到解决办法
2. 在应用目录下创建 static 目录, 在 settings.py 中添加 STATIC_ROOT=’你的ststic 的文件夹地址’
3. 在 urls.py 中添加修改
urlpatterns = [# ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
4. 执行 python manage.py collectstatic
博客开发
博客主页面开发
index.html
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>
<a href="{% url'zzb:edit_page'0 %}">新文章</a>
</h1>
{% for article in articles %}
<a href="{% url'zzb:article_page'article.id %}">{{article.title}}</a>
<br/>
{% endfor %}
</body>
</html>
博客文章页面开发
article_page.html
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Article Page</title>
</head>
<body>
<h1>{{article.title}}
</h1>
<h3>{{article.content}}</h3>
<br/><br/>
<a href="{% url'zzb:edit_page'article.id %}">修改文章</a>
</body>
</html>
博客编辑页面开发
edit_page.html
<DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Edit Page</title>
</head>
<body>
<form action="{% url'zzb:edit_action'%}" method="post">
{% csrf_token %}
{% if article %}
<input type="hidden" name="article_id" value="{{article.id}}">
<label>文章标题
<input type="text" name = "title" value="{{article.title}}"/>
</label>
<br/>
<label>文章内容
<input type="text" name = "content" value="{{article.content}}"/>
</label>
<br/>
{% else %}
<input type="hidden" name="article_id" value="0">
<label>文章标题
<input type="text" name = "title" />
</label>
<br/>
<label>文章内容
<input type="text" name = "content" />
</label>
<br/>
{% endif %}
<input type="submit" value="提交"/>
</form>
</body>
</html>
views.py配置
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render
from django.http import HttpResponse
from . import models
def index(request):
articles = models.Article.objects.all()
return render(request, 'zzb/index.html', {'articles':articles})
def article_page(request, article_id):
article = models.Article.objects.get(pk=article_id)
return render(request,'zzb/article_page.html',{'article':article})
def edit_page(request,article_id):
if str(article_id) == '0':
return render(request,'zzb/edit_page.html')
article = models.Article.objects.get(pk=article_id)
return render(request,'zzb/edit_page.html',{'article': article})
def edit_action(request):
title = request.POST.get('title','TITLE')
content = request.POST.get('content','CONTENT')
article_id = request.POST.get('article_id','0')
if str(article_id) == '0':
models.Article.objects.create(title=title,content=content)
articles = models.Article.objects.all()
return render(request,'zzb/index.html',{'articles':articles})
article = models.Article.objects.get(pk=article_id)
article.title = title
article.content = content
article.save()
return render(request,'zzb/article_page.html',{'article':article})
url配置
from django.conf.urls import url
from . import views
urlpatterns = [url(r'^index/$', views.index),
url(r'^article/(?P<article_id>[0-9]+)/$', views.article_page, name='article_page'),
url(r'^edit/(?P<article_id>[0-9]+)/$',views.edit_page, name='edit_page'),
url(r'^edit/action/$',views.edit_action, name='edit_action'),
]
Templates过滤器
过滤器属于 django 模板语言, 修改模板中的变量,从而显示不同内容
{{value | filter}}
举例:{{list_nums | length}} 表示 list 的长度
{{value | filter | filter | filter}} 可叠加
使用过滤器简化edit_page.html
<DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Edit Page</title>
</head>
<body>
<form action="{% url'zzb:edit_action'%}" method="post">
{% csrf_token %}
<!--解决跨站请求伪造问题,POST 表单需要添加这句 --!>
<input type="hidden" name="article_id" value="{{article.id | default:'0'}}">
<!--default 过滤器, 默认值 --!>
<label> 文章标题
<input type="text" name = "title" value="{{article.title}}"/>
</label>
<br/>
<label> 文章内容
<input type="text" name = "content" value="{{article.content}}"/>
</label>
<br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
Django Shell
python交互式命令行程序 , 自动引入项目环境 , 可以使用它和项目进行交互
启动django shell
pyhton manage.py shell
交互举例:
from blog.models import Article
Article.objects.all()
作用:1)调试工作 2)测试未知的方法
Admin 增强
配置admin.py, 使其显示更多内容
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
from models import Article
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title','content','pub_time')
list_filter = ('pub_time',)
# Register your models here.
admin.site.register(Article,ArticleAdmin)
配置models.py, 增加时间参数
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=32, default='Title')
content = models.TextField(null=True)
pub_time = models.DateTimeField(null=True)
def _unicode_ (self):
return self.title
写在最后:
有的情况修改 urls.py 后, 需要重启 apache 才能看到效果, 但不知道为什么, 请注意.
有的情况在 templates 下创建以应用为名的目录 (解决冲突) 后,Django 不能读取放在其中的 html 文件,
如:
Django tried loading these templates, in this order:
Using engine django:
django.template.loaders.app_directories.Loader: /usr/lib64/python2.7/site-packages/django/contrib/admin/templates/index.html (Source does not exist)
django.template.loaders.app_directories.Loader: /usr/lib64/python2.7/site-packages/django/contrib/auth/templates/index.html (Source does not exist)
django.template.loaders.app_directories.Loader: /var/www/html/blog/zzb/templates/index.html (Source does not exist)
html 文件放在 templates/zzb 下, 然而 Django 没有检索这一目录, 只能被迫把 index.html 放在 templates 目录下。
更多参考
Nginx+uWSGI+Supervisor 在 Ubuntu 上部署 Flask 应用 http://www.linuxidc.com/Linux/2016-07/133064.htm
uWSGI+Django+Nginx 的工作原理流程与部署过程 http://www.linuxidc.com/Linux/2017-03/141785.htm
快速部署 Python 应用:Nginx+uWSGI 配置详解 http://www.linuxidc.com/Linux/2016-12/137830.htm
Nginx+uWSGI+Django+Python 应用架构部署 http://www.linuxidc.com/Linux/2015-10/124183.htm
Ubuntu Server 14.04.2 LTS 配置 Nginx + Uwsgi + Django http://www.linuxidc.com/Linux/2015-04/116397.htm
Flask+uWSGI+Nginx+Ubuntu 部署教程 http://www.linuxidc.com/Linux/2016-06/132690.htm
Ubuntu 16.04 下安装部署 Nginx+uWSGI+Django1.9.7 http://www.linuxidc.com/Linux/2016-07/133484.htm
Nginx+uWSGI+Django 在 Ubuntu 下的部署 http://www.linuxidc.com/Linux/2016-07/133490.htm
uWSGI+Nginx+Django 安装和配置 http://www.linuxidc.com/Linux/2017-03/141822.htm
Ubuntu 16.10 下部署 Django+uWSGI+Nginx 服务器 http://www.linuxidc.com/Linux/2017-05/143661.htm
Linux 上利用 Nginx 代理 uWSGI 处理 Flask Web 应用 http://www.linuxidc.com/Linux/2016-08/134164.htm
本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-07/146003.htm