使用Python Django在Ubuntu下搭建数据库型网站
最近想做一个数据库网站,我对Python很熟悉,也了解到Django很好用,于是说搞就搞。
首先,在快云上买了一个vps,一元试用一个月,Ubuntu系统。
1.安装Django
apt-get update apt-get install python-pip python-dev build-essential python -m pip install django
安装的方法很多,可以自由选用。
2.创建prj和app
#创建项目
django-admin.py startproject test01
./
├── manage.py #管理器
└── test01 #项目目录
├── __init__.py #包文件
├── settings.py #项目配置文件
├── urls.py #URL管理器
└── wsgi.py #服务器连接工具
修改urls.py文件,url(r'^blog/index/$', 'blog.views.index'), 进行网站测试
注意:一定要在项目的根目录里建app,否则会出问题*
from blog.views import index urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^blog/index/$', index), ]
#创建应用
django-admin.py startapp blog
./
├── blog
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py # 数据库交互器
│ ├── tests.py
│ └── views.py # 视图操作器
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
from django.http import HttpResponse def index(req): return HttpResponse('<h1>Welcome to Bioinfohub!</h1>')
python manage.py runserver
w3m http://127.0.0.1:8000/blog/index
OK,测试成功!!!
3.安装和配置Apache2,并连接Django
# 安装 sudo apt-get install apache2
我已经安装过Nginx了,需要停止它
/etc/init.d/nginx stop
编辑配置文件,vim /etc/apache2/apache2.conf,在最后添加一行,不然会报错
ServerName localhost:80
# 安装wsgi模块 sudo apt-get install libapache2-mod-wsgi
后面的报错真是惨不忍睹,好在最终部署成功了,花了我一个多小时。
File "/var/www/mysite/mysite/settings.py", line 29 122.114.29.29,
Django的安装和测试非常简单,上面已经完成了。
Apache的安装和测试也是非常简单,能打开默认的测试页面。
最难的就是让Django和Apache连接在一起!!!
# 安装Apache后,要在末尾加上一句,不然会报错 /etc/apache2/apache2.conf ServerName localhost:80
然后要在/etc/apache2/sites-available/下新建一个网站的配置文件(文件可以随便命名,亲测),里面一个都不能错。(删除此文件记得还要删除一个../sites-enabled/里面的一个链接文件,否则报错)
然后让配置文件生效,重启Apache
<VirtualHost *:80> ServerName 122.114.29.29 DocumentRoot /var/www/mysite/mysite <Directory /var/www/mysite/mysite> Require all granted </Directory> WSGIScriptAlias / /var/www/mysite/mysite/wsgi.py </VirtualHost>
a2ensite mysite.conf
service apache2 reload
修改mysite/settings.py文件,ip地址必须加上引号,否则会报错!
ALLOWED_HOSTS = [ '122.114.29.29', ]
整个过程没什么难的,最重要的一点就是整个Django项目要存储在/var/www/目录下!!!
因为Apache不能访问/var/www/之外的路径,这个测试页面有写。
测试页面在/var/www/html/index.html,如果只写普通网站就没有什么好配置的了,网站入口就在这,但Django不行。
看到这个页面就成功了,恭喜!
附加学习:
The configuration layout for an Apache2 web server installation on Ubuntu systems is as follows:
/etc/apache2/ |-- apache2.conf # the main configuration file. It puts the pieces together by including all remaining configuration files when starting up the web server. | `-- ports.conf #It is used to determine the listening ports for incoming connections, and this file can be customized anytime. |-- mods-enabled #Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/ directories contain particular configuration snippets which manage modules, global configuration fragments, or virtual host configurations, respectively. | |-- *.load | `-- *.conf |-- conf-enabled | `-- *.conf |-- sites-enabled | `-- *.conf
重点来了:
# 默认不能访问其他目录,需要配置 By default, Ubuntu does not allow access through the web browser to any file apart of those located in /var/www, public_html directories (when enabled) and /usr/share (for web applications). If your site is using a web document root located elsewhere (such as in /srv) you may need to whitelist your document root directory in /etc/apache2/apache2.conf. The default Ubuntu document root is /var/www/html. You can make your own virtual hosts under /var/www. This is different to previous releases which provides better security out of the box.
好了,网站有了雏形,下面就可以开始正式搞 数据库 和 数据展示了!
补充:
如何通过Apache绑定多个域名到本主机空间?
修改/etc/apache2/sites-available/test.conf文件,以及Django的settings.py文件。
4.模板
基本测试--使用模板
创建template目录,可以随意命名,但是要去 mysite/settings.py 里修改地址
mkdir blog/templates
TEMPLATES = [
'DIRS': [os.path.join(BASE_DIR, 'templates')],
]
创建模板文件(下面是错误的模板,不能把内容写到<script>里,html是不区分缩进和回车的)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title> Bioinfohub </title> <meta name="Generator" content="NPP-Plugin"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> </head> <body> <script type="text/javascript"> </script> <h1>Hello Bioinfohub!</h1> <li>By Li Zhixin</li> </body> </html>
修改blog/views.py文件
from django.http import HttpResponse from django.template import loader, Context def index(req): t = loader.get_template('index.html') #c = Context({}) c = {} return HttpResponse(t.render(c))
注意,新版Django里c必须是字典,而不能是Context格式的对象。
第二种渲染方法,减少重复。
from django.shortcuts import render_to_response def index(req): return render_to_response('index.html', {})
模板变量--传入Python变量
<li>{{tool}}: {{function}}</li>
return render_to_response('index.html', {'tool':'BWA','function':'Alignment'})
或者传入字典,然后在模板里用点号来调用。
<li>{{tools.name}}</li> <li>{{tools.function}}</li>
tools = {'name':'BWA','function':'Alignment'} return render_to_response('index.html', {'tools':tools})
总结,模板里的变量tools始终是一个字典的key,必须在views中出现。
而views中字典的值就是一个我们要传入的对象,该对象可以是大部分的Python对象,list、dict、class等。
记住,传入模板的始终是一个字典,字典的值是传入的对象。
list可以在模板内使用 list.0 来取出第一个元素。
可以执行类的方法,但是该方法不能有输入参数。
模板标签--选择和循环
{% if tools %} <li>tools exist</li> <li>{{tools.name}}</li> <li>{{tools.function}}</li> {% else %} <li>no tools exist</li> {% endif %}
还有关系运算,in运算。
{% for tool in tools %} <li>{{tool}}</li> {% endfor %}
还可以遍历values、items
{% for tool in tools.values %}
5.url 配置
可以这样
from blog.views import index
url(r'^index/$', index),
也可以直接
url(r'^index/$', blog.views.index),
后面可以加引号,也可以不加,效果是一样的。
还可以进行模式匹配,关联一系列的URL
url(r'^index/\d{2}/$', index),
还可以从 URL 中输入参数,传递到 views 的方法中
此时需要修改三个文件:
blog/views.py
def index(req, num): tools = {'name':'BWA','function':'Alignment'} return render_to_response('index.html', {'tools':tools, 'num':num})
blog/templates/index.html
{% if num %} <li>num: {{num}}</li> {% else %} <li>no num exist</li> {% endif %}
mysite/urls.py
url(r'^index/(?P<num>\d{2})/$', index), #给参数取名为 num
url(r'^index/(\d{2})/$', index), #不取名
6.数据库
安装和配置数据库
推荐使用MySQL数据库,Ubuntu安装也是非常简单
apt-get install mysql-server apt-get install mysql-client apt-get install libmysqlclient-dev sudo netstat -tap | grep mysql mysql -u root -p show databases;
转:
一、 启动方式 1、使用 service 启动:service mysql start 2、使用 mysqld 脚本启动:/etc/inint.d/mysql start 3、使用 safe_mysqld 启动:safe_mysql& 二、停止 1、使用 service 启动:service mysql stop 2、使用 mysqld 脚本启动:/etc/inint.d/mysql stop 3、mysqladmin shutdown 三、重启 1、使用 service 启动:service mysql restart 2、使用 mysqld 脚本启动:/etc/inint.d/mysql restart
apt-get install rpm sudo apt-get install python-setuptools sudo apt-get install libmysqld-dev sudo apt-get install libmysqlclient-dev sudo apt-get install python-dev sudo easy_install mysql-python python -m pip install mysql-python
测试是否安装成功
import MySQLdb
配置数据库 mysite/settings.py
mysql> create database mysite
DATABASES = { 'default': { #'ENGINE': 'django.db.backends.sqlite3', #'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mysite', 'USER': 'root', 'PASSWORD': '****', 'HOST': '', 'PORT': '', } }
创建表单 blog/models.py
class Employee(models.Model): name = models.CharField(max_length=20)
def __unicode__(self):
return self.name
数据库同步
#在django1.9之前,数据库同步只需要一条命令:
Python manage.py syncdb
#在djang1.9以后,数据库同步执行指令如下: #同步数据库接口(注意需要切换至python project工作空间所在路径) python manage.py makemigrations #同步数据 python manage.py migrate
查看是否成功
mysql> use mysite; mysql> show tables; mysql> desc blog_employee;
操作数据
python manage.py shell
>>> from blog.models import Employee >>> emp = Employee() #或者直接 emp = Employee(name=’lizhixin’)
# 或者直接 Employee.object.create(name=’lizhixin’) >>> emp.name = "LIZHIXIN" >>> emp.save()
mysql> select * from blog_employee; #查看操作记录
Employee.objects.create(name='zhao') >>> emp = Employee(name='zhang') >>> emp.save()
遍历数据库
emps = Employee.objects.all()
emps[0].id
使用数据
我去,改回去网页就不能访问了,真是他妈的蛋疼!!!
卧槽,原来是数据库的原因,改成MySQL后原来的网页就无法访问了,改回sqlite就又可以了!!!
VPS空间,centos,reboot后,ssh就连不上了,解决方法。
ubuntu14.04下mysql数据库的默认存放路径并修改
django 1.10版本改了写法了。首先要在引入view模块,其次后面URL设置里views.hello不要加引号了。
emps = Employee.objects.all()
return render_to_response(‘index.html’, {‘emps’:emps})
照常显示{{emps}},可以规范化显示
以下是重点,血泪的经验!!!
断断续续搞了一天,终于解决了这个棘手的问题,压抑了一天的心情终于得到了释放。
问题:学到MySQL数据库时,决定用MySQL替换默认的sqlite,一切看起来是那么简单,安装教程配置好了后却死活打不开网页,停留在 Internal Server Error 页面。
一个莫名的问题来了之后,阵脚就乱了,本来就不熟,各种猜测,各种配置改来改去,都不行,越改越乱,到后面都想重装Ubuntu和Django、Apache了。
还好我冷静了一下,知道瞎改是没用的,然后回来最原来的那个app,开始调错。
完全是无头苍蝇,看着网上的各种乱七八糟的教程,瞎试,事实证明,大多数教程都是垃圾。
通过比较调试,我把问题定位到了数据库问题,因为sqlite可以用。
我感觉是MySQL和Apache的交互问题,但一直都无法深入定位问题。
后来无意在Google里学到了一门内功,apache error log,Internal Server Error 错误太宽泛,你无法定位,想要定位你必须去看Apache的error日志!!!
[Mon Jun 19 14:13:17.981891 2017] [:error] [pid 17769] [remote 198.20.87.98:7261] mod_wsgi (pid=17769): Target WSGI script '/var/www/mysite/mysite/wsgi.py' cannot be loaded as Python module. [Mon Jun 19 14:13:17.981918 2017] [:error] [pid 17769] [remote 198.20.87.98:7261] mod_wsgi (pid=17769): Exception occurred processing WSGI script '/var/www/mysite/mysite/wsgi.py'. [Mon Jun 19 14:13:17.981964 2017] [:error] [pid 17769] [remote 198.20.87.98:7261] Traceback (most recent call last): [Mon Jun 19 14:13:17.981983 2017] [:error] [pid 17769] [remote 198.20.87.98:7261] File "/var/www/mysite/mysite/wsgi.py", line 19, in <module> [Mon Jun 19 14:13:17.982015 2017] [:error] [pid 17769] [remote 198.20.87.98:7261] application = get_wsgi_application() [Mon Jun 19 14:13:17.982028 2017] [:error] [pid 17769] [remote 198.20.87.98:7261] File "/usr/local/lib/python2.7/dist-packages/django/core/wsgi.py", line 13, in get_wsgi_application [Mon Jun 19 14:13:17.982052 2017] [:error] [pid 17769] [remote 198.20.87.98:7261] django.setup(set_prefix=False) [Mon Jun 19 14:13:17.982061 2017] [:error] [pid 17769] [remote 198.20.87.98:7261] File "/usr/local/lib/python2.7/dist-packages/django/__init__.py", line 27, in setup [Mon Jun 19 14:13:17.982073 2017] [:error] [pid 17769] [remote 198.20.87.98:7261] apps.populate(settings.INSTALLED_APPS) [Mon Jun 19 14:13:17.982079 2017] [:error] [pid 17769] [remote 198.20.87.98:7261] File "/usr/local/lib/python2.7/dist-packages/django/apps/registry.py", line 78, in populate [Mon Jun 19 14:13:17.982090 2017] [:error] [pid 17769] [remote 198.20.87.98:7261] raise RuntimeError("populate() isn't reentrant") [Mon Jun 19 14:13:17.982106 2017] [:error] [pid 17769] [remote 198.20.87.98:7261] RuntimeError: populate() isn't reentrant
第二门内功,Python报错看最后,锁定错误。
[Mon Jun 19 14:11:17.341368 2017] [:error] [pid 17769] [remote 116.6.99.221:10845] [ Errno 13] Permission denied: '/var/www/mysite/.python-eggs'
发现,Django会在运行时创建一个临时用户,该用户是没有权限在/var/www目录下写入的!!!
我强行将其目录权限改为777才最终解决了问题。
当然mysite.conf配置文件也要改(其实改不改无所谓)
<VirtualHost *:80> ServerName 122.114.29.29 DocumentRoot /var/www/mysite/mysite <Directory /var/www/mysite/mysite> Require all granted </Directory> # WSGIDaemonProcess mysite python-path=/var/www/mysite/mysite:/usr/local/lib/python2.7/dist-packages # WSGIProcessGroup mysite WSGIScriptAlias / /var/www/mysite/mysite/wsgi.py </VirtualHost>