当前位置: 移动技术网 > IT编程>脚本编程>Python > Windows+Apache+Python+Django 踩坑记录

Windows+Apache+Python+Django 踩坑记录

2019年07月26日  | 移动技术网IT编程  | 我要评论

璀璨人生大结局播放,维基中国解密梁光烈,广东教育出版社

摘要

  使用python进行web项目开发;相对于主流三大web端解决方案(java/.net/php) python在某些方面具有一定的优势,相对 java/.net 有更轻量级的部署方案,相对php有更安全开放的环境支持,这些不同点几乎完全取决于python语言本身的特性。

0x01: 环境部署

  注:开发环境与运行环境的部署需要的基本技能 —— 理论基础知识扎实,了解相关基本原理,了解具体开发体系;如果不具备这些能力那么遇到问题就会很懵

  0x11: windows+apache 部署

  1. apache压缩包直接百度 "apache" 就能找到官网下载了,飞机票>>  ;压缩包解压至安装目录,路径最好不要含有中文和空格(江湖规矩)

  2. httpd.conf 配置文件(apachepath/conf/httpd.conf),apache部署中最重要的部分,一般只用修改第一条 serverroot 就可以了,文档中 "#" 为行注释

    serverroot 改为你的真实路径(一般在37行上下),ex: serverroot "d:/program/apache/apache24",新版本apache中采用 "srvroot" 宏替换后面所有会用到路径的地方,新版本修改 define srvroot "c:/apache24" 为真实路径可全局替换,较老版本要手动修改以下两个地方:标识静态文件路径(大概在251行上下)以及文件访问权限,cgi 脚本路径及访问权限(大概在368/380行上下);注意:路径分隔为 "/" 而不是 "\"

    listen 为监听端口,默认80(通常在60行上下)一般不用修改

    loadmodule 为随apache启动加载的模块(71-185左右),一般不用管

    servername 取消注释(225上下),好像是 iana dns导航什么的

    documentroot 表示静态文件路径,见第一条 serverroot

    errorlog 表示记录文件输出路径(300行上下),debug的时候会经常用到这个文件,不更改记录级别的话提示警告什么的也在里面,我也不知道咋回事儿

    loglevel 表示记录输出级别(310行上下),取值文档中有注释麻烦自己看

    include 表示要引入的其它配置文件(原文档中490-530行大量出现),要使用了再详细了解吧

    <files xx.xx*> 表示文件访问权限,按类型限制

    <ifmodule xxx_module> 标签表示如果加载了 xxx_module 模块就将其内容作为该模块的配置

    <directory xxxx> 标签表示文件夹权限,见第一条 serverroot

   3. 安装/卸载系统服务,不安装没法用

    安装:管理员权限打开控制台,cd 到 apache24/bin/ 目录下,执行 "httpd -k install" 将apache服务注入系统,可使用 -n 参数指定服务名(一般不要这么干),ex: "httpd -k install -n "apache2439" ",如此步安装过程报错考虑可能是vc库版本问题,一般apache压缩包中会有一个空文件,文件名表示该版本所依赖的vc库,若无请自行下载

    安装完成后可到系统服务将该服务 "自动启动" 改为手动启动,否则该服务将随系统开启而启动;如果部署到服务器则不用修改

    卸载:管理员权限打开控制台,cd 到 apache24/bin/ 目录下,执行 "httpd -k uninstall" 卸载服务,若注入服务时使用 -n 参数指定服务名则此处也要用 -n 参数指定

  4. 启动/停止/重启服务

    启动:管理员权限打开控制台,cd 到 apache24/bin/ 目录下,执行 "httpd -k start" 开始运行服务器,若注入服务时使用 -n 参数指定服务名则此处也要用 -n 参数指定

    重启:"httpd -k restart"

    停止:"httpd -k stop"

    其它:"httpd -h" 可查看httpd支持的所有命令,当然,是英文版的

  n. 若上述步骤都没有什么问题,则访问 127.0.0.1 就能看到 "it works!" 了(服务器需允许httpd.exe通过防火墙)

  0x21: apache+django部署

  注:python安装都不会的就不用继续看了

  1. 运行模式解释,apache服务器脚本运行模式有一大堆,具体是咋回事儿我也不是很懂,以下是我对其中一部分的个人理解,若有偏差欢迎指正

    cgi: 服务器收到请求后由配置信息找到cgi程序(脚本)路径,随后由该程序指定的运行方式运行(直接运行或解析器),然后将执行结果返回给服务器调用处

    fcgi: gci的升级版,改进cgi每次服务器的请求都会调用一次cgi程序体浪费空间和性能的缺点;fcgi创建一个程序执行的管理程序,服务器只与管理程序通信(通信机制一般使用socket)。每次请求会被fgci管理程序分配给工作进程或线程,由于管理进程事先会启动多个工作进程/线程,所以省去了事务生成/销毁的系统开销

    wsgi: fcgi的改进版,管理程序实现方式改为服务器插件而不是使用socket通信,官方文档中一般使用 middleware(中间件) 这个概念,可避免端口占用,主要性能提升在于降低通信开销(内存共享快于socket通信)

  2. 中间件 mod_wsgi 是django在apache上的一种方案,采用上述wsgi的实现方式

  3. django安装,建议直接 "pip install django" 安装,安装完成后会有 "success" 之类的提示,可执行 "pip list" 可查看安装包列表内是否有 "django x.x.x" 以确认安装

    3.1 pip安装缓慢原因:下载源在国外,解决:修改下载源,方法:"c:/users/用户名" 目录下创建 "pip" 文件夹,文件夹内创建 "pip.ini" 配置文件,内容为:

      [global]

      index-url = https://pypi.douban.com/simple/

    3.5. django中一些基础概念的介绍

      项目:一个web项目的容器,其中包括该web项目要用到的所有文件,例如静态文件、python脚本、数据库等

      应用:web项目中的一个功能的所有实现,代码以及数据

      项目和应用是多对多的关系,一个项目可由多个应用构成,一个应用可供多个项目使用

  4. mod_wsgi 安装,去python库里下载mod_wsgi,模块版本一定要对应apache和python的版本,因为这是一个中间件,就是用来适配两端模块的,再送一张飞机票>>  ,下载到的是 whl 文件,使用 "pip install mod_wsgi-xxx.whl" 进行安装

  5. 创建django项目/应用

    控制台执行 "django-admin startproject projname" ,生成一个django项目,同上 django-admin 也在python 中 scripts 目录下,该命令会在指定目录生成一个django项目文件结构,不指定目录则生成在当前目录,使用 "django-admin startapp appname" 生成一个应用,贴出自用的一个生成项目和应用的 .bat 脚本

@echo off
echo.  ** django **
echo.新建 django 项目输入 1
echo.新建 django 应用输入 2
set /p cho=输入后回车: 
goto tag%cho%
:tag1
set /p projname=输入项目名: 
django-admin startproject %projname%
goto end
:tag2
set /p appname=输入应用名: 
django-admin startapp %appname%
:end
echo.请自查当前目录是否生成文件
pause

  

  6. apache 适配 mod_wsgi 中间件,修改配置文件 httpd.conf

    注:网上一堆找 xxx.so 模块文件再改上述 httpd.conf 中 loadmodule 是不可行的,因为python3之后的版本使用的模块为 pyd 格式

    控制台执行 "mod_wsgi-express module-config" ,该命令中的 mod_wsgi-express 在 python 目录中 scripts 文件夹下,如果环境变量 path 中没有该 scripts 的路径就 cd 过去再用,将得到的3行结果复制下来,粘贴到 apache 中的 httpd.conf 配置文件末尾,一般是 loadfile+loadmodule+wsgipythonhome,分别表示python解析器路径/中间件路径/python容器路径(也可执行 "mod_wsgi-express module-config >> apachepath/conf/httpd.conf",apachepath代表apache安装根目录,如果你熟悉命令行应该知道这是个啥)

    添加行 " wsgiscriptalias / "djangopath/djangoname/wsgi.py" ",该行为apache找到django项目提供依据,路径为django项目下的 wsgi.py 文件

    添加行 " wsgipythonpath "djangopath" ",该行为django项目的容器路径

    配置 wsgi.py 的访问权限:

      <directory "djangopath/djangoname">

       <files "wsgi.py">
        require all granted
       </files>
      </directory>

    配置静态文件路径及访问权限:

      alias /static "djangopath/static"

      <directory "djangopath/static">
       allowoverride none
       options none
       require all granted
      </directory>

    配置多媒体文件路径及访问权限:(可选)

      alias /media "djangopath/media"

      <directory "djangopath/media">
       allowoverride none
       options none
       require all granted
      </directory>

    我的配置代码

#配置wsgi.py访问权限
wsgiscriptalias / "d:/program/apache/apache24/htdocs/dj/dj/wsgi.py"
wsgipythonpath "d:/program/apache/apache24/htdocs/dj"
<directory "d:/program/apache/apache24/htdocs/dj/dj">
<files "wsgi.py">
require all granted
</files>
</directory>

#此项为静态文件路径
alias /static "d:/program/apache/apache24/htdocs/dj/static"
#静态路径权限配置
<directory "d:/program/apache/apache24/htdocs/dj/static">
allowoverride none  
options none  
require all granted
</directory>

#此项为多媒体文件路径
alias /media "d:/program/apache/apache24/htdocs/dj/media"
#多媒体权限配置
<directory "d:/program/apache/apache24/htdocs/dj/media">
allowoverride none  
options none  
require all granted
</directory>

  n. 配置完成以上内容重启apache,使用浏览器访问 127.0.0.1 就能看到django的欢迎界面了(服务器需要在django项目中setting.py中设置 "allowed_hosts=['*']",详见django配置文件解析)

0x02: 使用django进行开发(python3.7+django2.2.2)

  0x12: django框架简介

  1. mvt,应该属于设计模式什么的吧,其实思想和mvc差不多

    m(model): 数据持久层,操作数据库的

    v(view): 视图层,其实是控制逻辑的

    t(template): 模板层,返回给用户看的内容

  2. 最小文件结构,执行 "django-admin startproject projname" 生成

  projname

   |-- projname<dir>

   |--  |--  __pycahce__<dir> #首次运行后自动生成的python二进制文件

   |--   |--  ....pyc

   |--  |--  __init__.py #空文件,python模块标识

   |--  |--  setting.py #该项目的配置信息

   |--  |--  urls.py #该项目的所有url路由

   |--  |--  wsgi.py #wsgi的接口??

   |-- db.selite3 #项目首次运行后自动生成的数据库文件(若未修改django默认使用的数据库sqlite3)

   |-- manage.py #管理该项目的文件

  3. 扩展文件结构,自行创建(可选)的文件结构

    projname/templates<dir>: 放置html文件的路径,django中成为模板文件

    projname/static<dir>: 放置静态文件,包括css/js/image

    projname/media<dir>: 放置多媒体文件,大概除了上面两个其它的文件都可以放这儿吧,也不是很懂这是干嘛的

    projname/projname/views.py: 视图文件,其实名字随便取,但最好这样(江湖规矩)

    projname/projname/models.py: 模型文件,用来编写模型的,只能是这个名字好像

  0x22: 项目配置,setting.py

    base_dir: 项目所在路径,不常改

    secret_key: 啥密钥来着??不常改

    debug: 调试模式默认为true,用于输出调试信息,项目上线后应改为false

    allowed_hosts: 允许通过的地址,上线后一般设置为['*']

    installed_apps: 安装的应用,创建应用后需要在此添加

    middleware: django提供的工具集,如csrf

    root_urlconf: url配置文件,指向项目下的urls.py路由文件,一般不改

    templates: 模板配置文件

    wsgi_application: cgi应用实例,一般不改

    databases: 数据库配置

    auth_password_validators: 密码认证配置,一般不改

    # 以下为国际化配置

    language_code: 语言('zh-hans'),设置为中文后django主页显示为中文

    time_zone: 时区('asia/shanghai')

    use_i18n: 国际化

    use_i10n: 国际化

    use_tz: 时间存储带时区(false)

    static_url: 静态文件(css/js/image/fonts)位置('/static/')

    # 以下为非默认配置

    append_slash: 自动在url后加 '/', 默认为true

    staticfiles_dirs: 静态文件路径,设置为 (os.path.join(base_dir, 'static'),) 否则使用django自带服务器启动时不能访问静态文件

  0x32: 其它常用操作

  1. 数据迁移,数据库生成与更改后都应执行数据迁移指令,控制台执行以下命令

    python manage.py makemigrations #创建数据库文件夹migrations(存在则跳过)

    python manage.py migrate #生成数据表及填充权限

    创建管理员用户,用于登录django的控制台 127.0.0.1/admin

      python manage.py createsuperuser #创建管理员,然后输入一堆信息就成了

  2. 新应用目录结构,略

  3. 启动django自带的web调试服务器,只能用作调试,并发性为0

    控制台cd到django项目根目录下,执行 "python manage.py runserver",django会在127.0.0.1:8000开启服务器,runserver 可选参数为[ip:port]

  4. 新增应用后,应在 setting.py 文件中的 installed_apps 中添加该应用的名称

  5. 使用mysql数据库,大概记录一下(我使用的默认的sqlite,没有用mysql)

    mysql数据库安装,请自行百度

    python mysql连接驱动安装,老规矩 "pip install pymysql"

    项目中使用mysql数据库需要在 __init__.py 中初始化数据库,代码为:

      import pymysql

      pymysql.install_as_mysqldb()

    修改项目 setting.py 文件数据库部分:

databases = {
    'default': {
        'engine': 'django.db.backends.mysql', #django中model的实现
        'name': 'dbname', #数据库名称
        'user': 'loginusername', #登录用户
        'password': 'loginpwd', #登录密码
        'host': '127.0.0.1', #数据库位置
        'port': '3306', #数据库监听端口
    }
}

  6. setting.py 模板路径设置,templates 中 'dirs':[base_dir+'/templates',]

  7. django后台管理工具,以下只做简要介绍,其它请自行查找

    访问 127.0.0.1/admin进入管理页面(未登录显示登录)

    服务器部署 页面没有css样式原因:未作 admin 静态文件迁移(apache配置文件中将权限交给django后没有决定路径解析的权限),解决:将 "pythonpath/lib/site-packages/django/contrib/admin/static" 目录下的 "admin" 目录拷至 "apachepath/htdocs/djangoname/static" 文件夹下

  8. ajax禁止问题,报错为 "csrf token missing or incorrect.",原因:csrf阻止,解决:注释掉配置文件 setting.py 中 "middleware" 中的 csrf 插件

  0x42: 开发部分

  1. 核心部分概述

    urls.py: django中的路由系统,说明网址与视图层(函数调用)的映射关系

    views.py: django中的视图层,其中放置的函数供路由系统调用

    models.py: django中的模型层,供视图层调用,用于处理数据持久化,屏蔽相对底层的操作(直接操作sql语句),当然django也提供直接执行sql语句的接口,但不建议你这么干

  2. urls.py, views.py, models.py

###########urls.py###########
# 当 "urlpatterns" 条目为空或只存在 admin 映射时访问 127.0.0.1 会映射到django默认主页

from django.contrib import admin
from django.urls import path
from . import views #存在 views.py 文件时可导入视图文件以使用其中的函数

urlpatterns = [
    path('admin/', admin.site.urls), #将.../admin映射到django管理界面
    path('sayhello/', views.sayhello), #调用 sayhello 视图
]

###########views.py###########
# 使用 "django-admin startapp appname" 创建的应用自动生成该文件

from django.shortcuts import render,httpresponse,redirect #通常使用这3种方式返回
from . import models #如需使用则手动建立该文件

def sayhello(request):
    return httpresponse('hello django.')

###########models.py###########
#使用 "django-admin startapp appname" 创建的应用自动生成该文件
#修改本文件中内容后执行数据迁移指令,自动生成数据库结构映射

from django.db import models

# 模型建立示例
class user(models.model):
    name=models.charfield(primary_key=true,max_length=16)
    age=models.integerfield(default=0)

    编写完成后重启服务器,访问 127.0.0.1:8000/sayhello 就能看到结果了

  3. 一个使用模板+静态资源的示例setting.py 中需配置 staticfiles_dirs 的值

    文件结构

   projname

    |--  projname<dir>

     |--  __init__.py

     |--  settings.py

     |--  urls.py

     |--  views.py

     |--  wsgi.py

    |--  static<dir>

     |--  templatetest.css

     |--  templatetest.jpg

     |--  templatetest.js

    |--  templates<dir>

     |--  templatetest

    |--  manage.py

##################urls.py##################
from django.urls import path
from . import views

urlpatterns = [
    path('<int:pagenum>/',views.template),
]

##################views.py##################
from django.shortcuts import render

def template(request,pagenum):
    content={
        'pagenum':pagenum,
    }
    return render(request,'templatetest.html',content)

##################templatetest.html##################
<!doctype html>
<html>
<head>
    <title>testpage</title>
    <link rel="stylesheet" type="text/css" href="../static/templatetest.css">
</head>
<body>
    <p>图片显示为圆形则css/图片加载成功</p>
    <p>弹出对话框则javascript脚本加载成功</p>
    <p>括号内为地址栏输入的数字({{pagenum}})</p>
    <img src="../static/templatetest.jpg">
    <script type="text/javascript" src="../static/templatetest.js"></script>
</body>
</html>

##################templatetest.css##################
img{
    width: 200px;
    height: 200px;
    border-radius: 50%;
}

##################templatetest.js##################
document.onload=alert('调用javascript');

0x03: 后记

  写得有点久了,95%是在做东西的时候写的,到发布的时候已经快一个月时间了,其中有些东西现在也记不大清了;当时没有发布我觉得可能有些重要的地方没写完,发布之前我又重新把上面的东西都跑了一次,发现果然是有些东西没写到 0.0

  这篇文章可能不是描述的最详细的,但应该是这一套技术比较全面的了,如果有什么问题或建议请回复评论(虽然最后确实头都写晕了 555~)

  原创文章,转发请注明

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网