再次编辑的时候已经到了2018年1月底,我差不多有一个月没有任何更新了。

最近换了一家新的单位,技术栈稍微更新了一丢丢。

之前我一直在做基于openstack框架的开发,里面web开发、数据库管理、RPC以及消息队列还有多线程、协程之类的,已经算是比较熟悉了,毕竟是日产800行bug的男人。

那时候我在做k8s和openshift,pacemaker和swarm的部署,集群内部的构造、属性、功能也比较熟悉,来到新的环境后,这边做的是zookeeper+marathon+mesos,这是一个很复古的集群;

也没说这类集群不好,但目前从云化的角度来看,k8s明显胜出一筹不止,docker官方也逐渐承认了这个事实。openstack社区之前上的新项目magnum也在推动这个事情,mesos还没有完全被抛弃掉,我也就跟着学习了一下。

 

新单位是一家互联网公司。互联网公司需要解决的就是高并发问题,所以java语言居多,也有一些企业正在转型go。这是一个很重要的前提,也就决定了为什么这里会使用zk以及mesos。

我之前做的web开发都是轻量级的,诸如flask,pecan,只能满足局域网里面的需求,这边使用Django一般处于两种考虑,一是互联网公司的开发节奏,django把什么事情都做好了,开发起来比较容易,另一方面,还是并发的问题。

这边大约有600多个服务,一周两个小版本,开发效率低下,但是版本更新速度奇高。老实说这种开发模式很不稳健,但是,这个也着急不来,我上家单位做这个事情也是慢慢来的,最后也蛮好的。(所以错过了很多机遇?哈哈)

 

那吐糟完了,现在就开始搞一下django的入门吧。

首先说明下开发环境,我的操作系统是ubuntu 16.04,有些软件的版本比较新,所以安装依赖库的时候比较痛苦。我建议还是采用基本的ubuntu 14.04比较靠谱。

1.当然是安装django,pip install Django。安装好之后验证一下,在python终端里面输入:

2.下面创建第一个工程吧:

首先进入一个建好的目录,我的是/home/kiel/django,然后执行:

django-admin.py startproject first_prj

进入这个目录,执行 python manage.py runserver(默认在8000端口,当然可以指定端口启动)

3.查看一下刚刚创建的工厂的目录结构,对结构里面的内容进行分析:

首先是最上层的三个对象,db.sqlite就是sqlite,first_prj就是django项目的“”容器“”,关于该项目的一切都在里面,等会会介绍一下里面的内容;最后呢就是manage.py,它实际上就是django项目的一个工具,

注意我在第二步里面做了一个 python manage.py runserver的操作,这就是一个启动django服务的一个动作。如果现在对这个感兴趣,可以现在看一下,最最原始的manage.py支持哪些操作:

python manage.py

大部分命令我也是一脸懵逼,但是我感兴趣的几个命令都在:runserver(启动django项目),startapp,startproject,shell,migrate(分别对应了新建app,新建project,启动python终端,在终端里面进行测试,数据库迁移并生成新的版本文件)。

实际上开发一个全新的项目也就需要这一丢丢,可能在开发过程中有一些特别需求,才会引入对这些命令的理解。这个事情我也有一点点个人认知,后面深入讲的时候会仔细介绍一下。

现在我回归一下正题,我要介绍一下项目容器里面到底有哪些玩意:

settings.py 这个顾名思义,就是django的配置文件。里面包括了一些宏定义,也包括了一些诸如数据库、消息队列、扩展app的配置。

urls.py 这个也是顾名思义,就是一个正则匹配的url集合,用户输入指定的url时即可以指向特定的函数。

wsgi.py 也是的,做了一个wsgi协议的入口。关于wsgi,我会在flask里面讲这玩意。

现在一个轮廓已经有了,但是非常简陋,不知道怎么下手开发。

那我还是进入eclipse开始搞事情吧。

我在first_prj目录下新增了一个view文件,里面就是一个简单的实现,还记得我之前讲过的单例模式吗,我这里用一下最简单的单例模式。

 1 '''
 2 Created on Jan 26, 2018
 3 
 4 @author: kiel
 5 '''
 6 
 7 
 8 from django.http import HttpResponse
 9 import datetime
10 
11 
12 class TestFirstPrj(object):
13     
14     def __init__(self):
15         self.init_time = str(datetime.datetime.now())
16 
17     def first_page(self, request):
18         return HttpResponse(self.init_time)
19         
20 
21 prj_instance = TestFirstPrj()

然后修改一下urls.py,提供一个访问路径:

 1 """first_prj URL Configuration
 2 
 3 The `urlpatterns` list routes URLs to views. For more information please see:
 4     https://docs.djangoproject.com/en/1.9/topics/http/urls/
 5 Examples:
 6 Function views
 7     1. Add an import:  from my_app import views
 8     2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
 9 Class-based views
10     1. Add an import:  from other_app.views import Home
11     2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
12 Including another URLconf
13     1. Add an import:  from blog import urls as blog_urls
14     2. Import the include() function: from django.conf.urls import url, include
15     3. Add a URL to urlpatterns:  url(r'^blog/', include(blog_urls))
16 """
17 from django.conf.urls import url
18 from django.contrib import admin
19 
20 
21 from first_prj.view import prj_instance
22 
23 urlpatterns = [
24     url(r'^admin/', admin.site.urls),
25     url(r'^test_first$', prj_instance.first_page)
26 ]

执行一下 python manage.py runserver,在浏览器里面查看:

老实说这个玩意丑爆了,由于我返回的只是一个字符串,我中间曾经测试过返回字典,可能是我返回的姿势不对,只能把两个键返回出来,这就很尴尬了。

我后来就把HttpResponse改成了JsonResponse,然后再整合一下,输出就长这个样子了:

 

其实到这里我已经很满意了,但是还是有点丑,那我就再优化优化吧,使用django模板。

4.一点改进

在firsrt_prj下面创建一个templates目录,里面添加firstpage.html文件,整个目录的树形结构如下:

其中html里面的内容如下:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>kiel Django 测试</title>
 6     </head>
 7     <body>
 8         <h1>项目起始时间:{{init_time}}</h1>
 9             <p>当次调用时间:{{atime}}</p>
10             <p>调用对象:{{class_name}}</p>
11     </body>
12 </html>

 

view.py文件修改成如下样子:

 1 '''
 2 Created on Jan 26, 2018
 3 
 4 @author: kiel
 5 '''
 6 
 7 
 8 from django.shortcuts import render
 9 import datetime
10 
11 
12 class TestFirstPrj(object):
13     
14     def __init__(self):
15         self.init_time = str(datetime.datetime.now())
16 
17     def first_page(self, request):
18         return render(request, 'firstpage.html',
19                       {'init_time': self.init_time,
20                        'atime': str(datetime.datetime.now()),
21                        'class_name': self.__class__.__name__})
22         
23 
24 prj_instance = TestFirstPrj()

settings.py里面需要对模板TEMPLATES参数进行修改进行修改:

TEMPLATES = [
    {
      'BACKEND': 'django.template.backends.django.DjangoTemplates',
      'DIRS': [BASE_DIR+'/templates'],
      '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',
        ],
      },
    },
]

保存一下,由于之前没有停止运行,该django项目仍在运行,可以访问:

 

 再访问一次:

至此,只能算是初步入门,只是把一个url和一个function映射关系建立起来了。

现在回想一下我做了什么?

建立一个工程,在url里面添加了一个url匹配规则,并将他映射到一个函数里面。我可以直接返回字符串,返回字典,也可以用指定的模板进行返回。中间没有其他附加流程。

事实上,这个玩意就这么简单粗暴。