[python] python django web 开发 —— 15分钟送到会用(只能送你到这了)

1、安装python环境 1.1 安装python包管理器: wget https://bootstrap.pypa.io/get-pip.py sudo python get-pip.py 1.2 安装python虚拟环境virtualenv virtualenvwrapper 首先说明下为什么要装这两个包: First, it’s important to understand that a virtual environment is a special tool used to keep the dependencies required by different projects in separate places by creating isolated, independent Python environments for each of them. In short, it solves the “Project X depends on version 1.x, but Project Y needs 4.x” dilemma. It also keeps your global site-packages neat, tidy, and free from clutter. If you would like a full explanation on why Python virtual environments are good practice, absolutely give this excellent blog post on RealPython a read. 用虚拟开发环境可以为每个工程提供独立的python开发环境、独立的包、独立的版本,每个独立的环境会在~/.virtualenvs/下形成资源包~ sudo pip install virtualenv virtualenvwrapper sudo rm -rf ~/.cache/pip 之后在~/.profile文件最后添加下面几行: # virtualenv and virtualenvwrapper export WORKON_HOME=$HOME/.virtualenvs source /usr/local/bin/virtualenvwrapper.sh 之后如果想用python虚拟环境,在每次打开一个新的terminal就要执行一次source ~/.profile source ~/.profile 接下来我们生成一个python虚拟环境来用于python-web的开发提供环境:(这里用的是python2.7) mkvirtualenv python_web -p python2 注:再次说明python虚拟环境是完全独立的,也就是说在python_web的环境下安装的python包,步适用于全局;在全局安装的包,不适合python_web。 如何验证你如何将python_web环境生成好了呢?——新开一个terminal,执行下列命令: source ~/.profile workon python_web 如果terminal前面的文字变成了(python_web)表明成功创建了名为cv的python虚拟环境; 2、安装Django 从官网上得知2.7版本的python可使用最高1.11版本的Django,因此在python_web环境中安装: pip install Django==1.11 测试Django有没有安装成功,进入python命令交互模式: import django django.VERSION 3、第一个例子hello world 找到你的django-admin.py文件,并把它加入系统路径。如果用的是setup.py工具安装的Django,django-admin.py应该已被加入了系统路径中。我的django-admin.py的目录为: /root/.virtualenvs/python_web/lib/python2.7/site-packages/django/bin 进入该目录下,运行如下命令,新建一个项目: python django-admin.py startproject mysite startproject命令创建一个目录,包含一个名为mysite的文件夹和一个名为manage.py的文件。其中mysite文件夹下包含有四个文件,分别为: (python_web) ➜ mysite tree . ├── db.sqlite3 ├── manage.py └── mysite ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py 为了安装后更多的体验,让我们运行一下django开发服务器看看我们的准系统。django开发服务是可用在开发期间的,一个内建的,轻量的web服务。 我们提供这个服务器是为了让你快速开发站点,也就是说在准备发布产品之前,无需进行产品级 Web 服务器(比如 Apache)的配置工作。 开发服务器监测你的代码并自动加载它,这样你会很容易修改代码而不用重启动服务。如果你还没启动服务器的话,请切换到你的项目目录里 (cd mysite),运行下面的命令: python manage.py runserver 你会看到如下内容: Django version 1.11, using settings 'mysite.settings' Starting development server at http://127.0.0.1:3000/ Quit the server with CTRL-BREAK 这将会在端口3000启动一个本地服务器, 并且只能从你的这台电脑连接和访问。 既然服务器已经运行起来了,现在用网页浏览器访问 http://127.0.0.1:8000/ 。 你应该可以看到一个令人赏心悦目的淡蓝色Django欢迎页面。 表明它开始工作了。 但是我的服务器搭在阿里云上,并且绑定了phage.cc的域名,因此可以通过这样的方式使之能访问: python manage.py runserver 0.0.0.0:3000 注:0.0.0.0”这个IP地址,告诉服务器去侦听任意的网络接口。 注:采用phage.cc:3000去访问会报错误 alid HTTP_HOST header: 'www.phage.cc:3000'. You may need to add u'www.phage.cc' to ALLOWED_HOSTS. 可以通过添加允许来实现通过: settings.py : ALLOWED_HOSTS = [u'www.phage.cc'] 4、自己建视图 4.1 静态视图hello world 在文件夹mysite中新建一个views.py的文件: from django.http import HttpResponse def hello(request): return HttpResponse("Hello world") 在这段代码中:我们定义一个叫做hello 的视图函数,这个函数只有简单的一行代码: 它仅仅返回一个HttpResponse对象,这个对象包含了文本“Hello world”。 注:每个视图函数至少要有一个参数,通常被叫作request。 这是一个触发这个视图、包含当前Web请求信息的对象,是类django.http.HttpRequest的一个实例。在这个示例中,我们虽然不用request做任何事情,然而它仍必须是这个视图的第一个参数。 注:视图函数的名称并不重要;并不一定非得以某种特定的方式命名才能让 Django 识别它。 在这里我们把它命名为:hello,是因为这个名称清晰的显示了视图的用意。 4.2 URLconf将视图和URL绑定(类似nodejs中的路由) URLconf 就像是 Django 所支撑网站的目录。 它的本质是 URL 模式以及要为该 URL 模式调用的视图函数之间的映射表。 你就是以这种方式告诉 Django,对于这个 URL 调用这段代码,对于那个 URL 调用那段代码。 这个映射表在urls.py中,我们想要实现访问/hello/调用hello视图,返回hello world需要做下面样子修改: from django.conf.urls import url urlpatterns = [ url(r'^hello/$', hello), ] 注: 这里的^hello/$是正则表达式,匹配所有/hello/形式的请求。 之后我们运行该服务器,在浏览器中可以访问hello视图: http://www.phage.cc:3000/hello/ 4.3 动态内容视图请求当前时间 在views.py中添加一个新视图current_datatime: from django.http import HttpResponse import datetime def hello(request): return HttpResponse("Hello world") def current_datetime(request): now = datetime.datetime.now() html = "It is now %s." % now return HttpResponse(html) 类似hello视图,这里用了python的datetime工具,获取时间并合成一个html字符串,作为视图返回。 同理,我们也需要在urls.py中做url映射: from django.conf.urls import url from mysite.views import hello, current_datetime urlpatterns = [ url(r'^hello/$', hello), url(r'^time/$', current_datetime), ] 这样我们通过访问 http://www.phage.cc:3000/time/ 可以获取time视图返回。 4.4 动态URL视图 在我们的current_datetime 视图范例中,尽管内容是动态的,但是URL ( /time/ )是静态的。 在 大多数动态web应用程序,URL通常都包含有相关的参数。 举个例子,一家在线书店会为每一本书提供一个URL,如:/books/243/、/books/81196/。 让我们创建第三个视图来显示当前时间和加上时间偏差量的时间,设计是这样的: /time/plus/1/ 显示当前时间+1个小时的页面 /time/plus/2/ 显示当前时间+2个小时的页面 /time/plus/3/ 显示当前时间+3个小时的页面,以此类推。 注: 在java或php中有可能见到这样的实现:/time/plus?hours=3,但这样被认为不漂亮 之前我们已经看到url是以正则表达式的形式出现,因此想要实现/time/plus/xxx/也就比较容易了: from django.conf.urls import url from mysite.views import hello, current_datetime, hours_ahead urlpatterns = [ url(r'^hello/$', hello), url(r'^time/$', current_datetime), url(r'^time/plus/(\d{1,2})/$', hours_ahead), ] 那么我们如是实现hours_ahead来接收请求中的xxx数字呢? from django.http import Http404, HttpResponse import datetime ... def hours_ahead(request, offset): try: offset = int(offset) except ValueError: raise Http404() dt = datetime.datetime.now() + datetime.timedelta(hours=offset) html = "In %s hour(s), it will be %s." % (offset, dt) return HttpResponse(html) hours_ahead 和我们以前写的 current_datetime 很象,关键的区别在于: 它多了一个额外参数,时间差。 注: offset 是从匹配的URL里提取出来的。 例如:如果请求URL是/time/plus/3/,那么offset将会是3;如果请求URL是/time/plus/21/,那么offset将会是21。请注意:捕获值永远都是字符串(string)类型,而不会是整数(integer)类型,即使这个字符串全由数字构成(如:“21”)。 注: 在这里我们命名变量为 offset ,你也可以任意命名它,只要符合Python 的语法。 变量名是无关紧要的,重要的是它的位置,它是这个函数的第二个 参数 (在 request 的后面)。 你还可以使用关键字来定义它,而不是用 位置。 5、模板 5.1 最简单的模板DEMO 模板的好处是将python和html分开,下面是一个最简单的例子: def template_test(request): now = datetime.datetime.now() t = Template("It is now {{ current_date }}."); html = t.render(Context({'current_date': now})) return HttpResponse(html) 上面的例子在html中嵌入一个 current_date 变量,通过context给变量赋值,通过render来渲染。除了双大括号表示的变量,还有循环、条件等各种玩法: https://docs.djangoproject.com/en/2.1/ref/templates/builtins/ 。 5.2 将html和python彻底分离 但是上面我们并没有真正将html和python分离,更进一步的做法是将html单独放置: 1) 在mysite下新建一个文件夹:templates,并在其中新建一个template_test1.html: It is now {{ current_date }}. 2) 而我们的template_test就能改造成: def template_test1(request): now = datetime.datetime.now() t = get_template('template_test1.html'); html = t.render({'current_date': now}) return HttpResponse(html) 3) 最后我们得通过下面方法让get_template的输入参数不用写完整路径: TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),], 'APP_DIRS': True, 'OPTIONS': { 注:我们还可以用render_to_response来简化template_test操作: def template_test2(request): now = datetime.datetime.now() return render_to_response('template_test1.html', {'current_date': now}) 5.3 模板继承 一个多页面的网站,其每个页面可能会有相同的头部、尾部的结构,主页面的内容存在更新变动。如果我们为每个页面单独创建一个独立的html将会产生大量冗余,此外如果我们想要对所有页面的头部做一个修改,也将比较麻烦。此时我们可以采用模板的思想来完美解决这个问题: 1)新建一个母版html(base.html) (python_web) ➜ templates git:(master) cat base.html {% block title %}{% endblock %}

My helpful timestamp site

{% block content %}{% endblock %} {% block footer %}

Thanks for visiting my site.

{% endblock %} 2) 创建一个继承base.html的template_test2_use_base_1.html: (python_web) ➜ templates git:(master) cat template_test2_use_base_1.html {% extends "base.html" %} {% block title %}The current time{% endblock %} {% block content %}

It is now {{ current_date }}.

{% endblock %} 3) 再创建一个继承base.html的template_test2_use_base_2.html: (python_web) ➜ templates git:(master) cat template_test2_use_base_2.html {% extends "base.html" %} {% block title %}Future time{% endblock %} {% block content %}

In {{ hour_offset }} hour(s), it will be {{ next_time }}.

{% endblock %} 可见base.html中的{% block title %}{% endblock %} 、{% block content %}{% endblock %} 、{% block footer %}{% endblock %} 都可以被继承者们重新实现! 注:当然,如果继承者没有实现,则不会显示。 6、python django的数据库操作 6.1 安装MYSQL数据库 我们先在linux上安装数据库: sudo apt-get install mysql-server sudo apt-get install libmysqlclient-dev 安装过程中会提示设置密码什么的,注意设置了不要忘了,安装完成之后可以使用如下命令来检查是否安装成功: sudo netstat -tap | grep mysql 通过上述命令检查之后,如果看到有mysql 的socket处于 listen 状态则表示安装成功。 登陆mysql数据库可以通过如下命令: mysql -u root -p -u 表示选择登陆的用户名, -p 表示登陆的用户密码,上面命令输入之后会提示输入密码,此时输入密码就可以登录到mysql。 下面是一些命令行中操作的DEMO,可做今后参考: mysqladmin -u root -p create blog mysql mysql -u root -p show databases; use blog; CREATE TABLE IF NOT EXISTS `blog_table`( `blogId` BIGINT UNSIGNED, `url` VARCHAR(100) NOT NULL, `title` VARCHAR(1000) NOT NULL, `support` INT UNSIGNED, `pageView` INT UNSIGNED, PRIMARY KEY ( `blogId` ) )ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `tag_table`( `tagId` INT UNSIGNED AUTO_INCREMENT, `tagName` VARCHAR(100) NOT NULL, PRIMARY KEY ( `tagId` ) )ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `blog_tag_relation_table`( `relationId` INT UNSIGNED AUTO_INCREMENT, `blogId` BIGINT UNSIGNED, `tagId` INT UNSIGNED, PRIMARY KEY ( `relationId` ) )ENGINE=InnoDB DEFAULT CHARSET=utf8; show tables; desc blog_table; desc tag_table; desc blog_tag_relation_table; //change blogId int 2 bigint alter table blog_table change blogId blogId BIGINT UNSIGNED; //show data select * from blog_table; //delete data delete from blog_table where blogId=201801021423; INSERT INTO blog_table(blogId,url,title,support,pageView) VALUES(201801021423,'http://106.14.226.191:3000/blog/201607281658.html','[商业_法务] 1、公司一款新消费类电子产品如何快速全面的专利保护',0,0); //too short alter table blog_table change title title VARCHAR(1000) NOT NULL; INSERT INTO tag_table(tagId,tagName) VALUES(0,'硬件_模拟电路'); select * from blog_table; select * from tag_table; select * from blog_tag_relation_table; delete from blog_table where blogId>0; delete from tag_table where tagId>=0; delete from blog_tag_relation_table where relationId >= 0; select a.title , a.url, b.tagName from blog_table a, tag_table b, blog_tag_relation_table c WHERE a.blogId = c.blogId AND a.blogId = 201602021408 AND b.tagId = c.tagId; select a.title , a.url, b.tagName from blog_table a, tag_table b, blog_tag_relation_table c WHERE a.blogId = c.blogId AND b.tagId = c.tagId ORDER BY b.tagId; 为了python操作mysql需要执行下面命令: pip install MySQL-python 6.2 配置及测试数据库 在settings.py中下面几项是对数据库的配置: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'pyserver', 'USER': 'root', 'PASSWORD': '123456', } } 一旦在输入了那些设置并保存之后应当测试一下你的配置。 我们可以在mysite 项目目录下执行python manage.py shell 来进行测试(没有错误表示成功): from django.db import connection cursor = connection.cursor() 6.3 创建books app 在mysite 项目文件下输入下面的命令来创建books app: python manage.py startapp books 这个命令并没有输出什么,它只在 mysite 的目录里创建了一个 books 目录。 让我们来看看这个目录的内容: (python_web) ➜ books tree . ├── admin.py ├── apps.py ├── __init__.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py └── views.py 这个目录包含了这个app的模型和视图。 6.4 编写模型 编辑models.py : from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField() class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField() Publisher 模块相当于SQL语句: CREATE TABLE "books_publisher" ( "id" serial NOT NULL PRIMARY KEY, "name" varchar(30) NOT NULL, "address" varchar(50) NOT NULL, "city" varchar(60) NOT NULL, "state_province" varchar(30) NOT NULL, "country" varchar(50) NOT NULL, "website" varchar(200) NOT NULL ); 6.5 由模型自动生成创建表SQL 再次编辑settings.py,将下面列出选项加#注释掉,并添加‘mysite.books’ 到INSTALLED_APPS 的末尾: INSTALLED_APPS = [ #'django.contrib.admin', #'django.contrib.auth', #'django.contrib.contenttypes', #'django.contrib.sessions', #'django.contrib.messages', #'django.contrib.staticfiles', 'books', ] 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', ] 你可能会执行python manage.py validate ,然后你会特别伤心的看到人家提示Unknown command: 'validate'Type 'manage.py help' for usage.,对吧?所以你要用如下这个命令: python manage.py check 然后你还想生成sql语句,你就运行了python manage.py sqlall books,错误提示是Unknown command: 'sqlall'Type 'manage.py help' for usage.同样如果你想提交sql语句到数据库而运行syncdb,错误提示是Unknown command: 'syncdb' Type 'manage.py help' for usag
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信