使用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    #服务器连接工具
修改settings.py文件,添加 blog 到 INSTALLED_APPS 中

修改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
修改blog中的views.py文件,添加函数index,
from django.http import HttpResponse
def index(req):
    return HttpResponse('<h1>Welcome to Bioinfohub!</h1>')
然后,测试,可以使用shell界面下的 w3m浏览器
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不行。

image

看到这个页面就成功了,恭喜!

附加学习:

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 %}
还可以进行 and or not逻辑操作,但不能合用。

还有关系运算,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
安装MySQL-python
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 页面。

image

一个莫名的问题来了之后,阵脚就乱了,本来就不熟,各种猜测,各种配置改来改去,都不行,越改越乱,到后面都想重装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>
posted @ 2017-06-17 02:15  Life·Intelligence  阅读(1524)  评论(0编辑  收藏  举报
TOP