django project 的快速构建

2003年,堪萨斯(Kansas)州 Lawrence 城中的一个 网络开发小组 ——World Online 小组,为了方便制作维护当地的几个新闻站点(一般要求几天或者几小时内被建立),Adrian Holovaty 和 Simon Willison  使用ptyhon开发了一种节省时间的网络程序开发框架。

在2005年夏天,这个框架被开发完成,World Online 小组中的Jacob Kaplan-Moss 决定把这个框架发布为一个开源软件。于是7月份Django发布了,名字以比利时的吉普赛爵士吉他手Django Reinhardt来命名。

Dango 的主要目的是为了使 开发复杂的、数据库驱动的网站 变得简单。

截止目前 django 支持的数据有 SQLite,MySQL, Oracle, PostgreSQ,默认使用SQLite。

Django的安装:

官方下载地址: http://www.djangoproject.com/download/ 

  1. 下载tar包,Django-*.tar.gz  # 具体版本根据需要下载

  2. tar xzvf Django-*.tar.gz 。

  3. cd Django-* 

  4. sudo python setup.py install

pip 安装 

$ pip install Django

验证:

$ python
>>> import django
>>> print(django.VERSION)
(1, 10, 1, 'final', 1)

第一个Django程序

$ django-admin startproject blog  # 创建一个 project

$ tree blog/
blog/
├── blog
│   ├── __init__.py 
│   ├── settings.py   # 当前项目的配置文件
│   ├── urls.py    # 当前项目的URL规则声明,其实就是django站点的内容清单
│   └── wsgi.py   # 为WSGI 兼容服务提供的接口
└── manage.py   # 一个命令行工具,用来让你和django 进行各种交互

启动 开发服务器

python3 manage.py runserver  

开发服务器是完全使用python编写的轻量级服务器程序,使用开发服务器可以帮助我们集中精力快速开发,而不必考虑服务器配置的事情。等到发布产品的时候在考虑就可以了。

runserver 命令在默认情况下 使用的8000端口,且只有本机IP可以访问。如果希望使用其他端口可以将端口修改掉。同样,修改 IP 也是如此。

python3 manage.py runserver 8080   # 修改端口
python3 manage.py runserver 0.0.0.0:8000  # 修改IP

配置数据库

前面我们说到 setting.py 包含,django project的设置信息。数据库的配置 也是在这里进行配置的。

django默认使用的数据库是 sqlite ,官方还支持mysql、oracle、postgresql。 如果需要使用第三方的数据库,需要自己安装。查看详细信息

# 默认配置
DATABASES = { 
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }   
}

# mysql 配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  
        'NAME': 'mydatabase',     # 数据库名
        'USER': 'mydatabaseuser',  
        'PASSWORD': 'mypassword',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

ENGINE : 从 'django.db.backends.sqlite3''django.db.backends.postgresql','django.db.backends.mysql', or 'django.db.backends.oracle' 中选一个就可以了,其他的可以,需要自己配置。

NAME: 你使用的数据库的名。如果使用的是SQLite,那么数据库就是你本机上的一个文件,这时NAME 应该是这个文件的完整路径(含文件名),如果文件不存在,django会在第一次同步数据库的时候自动创建。

USER : 连接数据库的用户名(sqlite不用写)

PASSWORD :连接数据库的密码(sqlite不用写)

HOST : 数据库所在的主机,如果数据库在本机,可以留空,(sqlite不用写)

PORT: 数据库所在机器的端口(sqlite不用写)

注意: 使用prostgresql和mysql时需要提前创建好数据库。

设置时区

django默认的时区,是美国中央时区(芝加哥),通过设置 TIME_ZONE 可以更改为本地时区。

TIME_ZONE = 'Asia/Shanghai'

配置到这里就做完了。

这里我们开始添加第一个app

$ cd blog/
$ django-admin startapp vote   # 添加一个app
$ tree .
.
├── blog
│   ├── __init__.py  
│   ├── settings.py
│   ├── urls.py 
│   └── wsgi.py
├── manage.py
└── poll
    ├── admin.py   # 用来配置django admin
    ├── apps.py
    ├── __init__.py
    ├── migrations
    │   └── __init__.py
    ├── models.py   # 在这里写的类对应数据库中的表
    ├── tests.py
    └── views.py   # 

一个app就是完成某件事的一个web程序,比如一个公共数据资料库 或者一个简单的投票程序

一个project 包含一系列的配置,以及多个app。

添加 app 以后如果我们想在 project 中使用,需要将app注册到project中

注册的过程就是在 setting.py 的 INSTALLED_APPS 变量中 添加 app 的名字。这里 app 的名字是 poll。

INSTALLED_APPS = [
    'django.contrib.admin',  
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'poll',  # 这一行是我们自己添加的
]

models.py : 在这里定义model,这里定义的类对应了你数据库中的表,数据库中的表根据这里定义的类生成,可以通过这里的类操作数据库。

from django.db import models

# Create your models here.

class Poll(models.Model):
    """
    问题表
    """
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField("date published")

class Choice(models.Model):
    """
    选项表
    """
    poll = models.ForeignKey(Poll)
    choice = models.CharField(max_length=200)
    votes = models.IntegerField()

类中的每一个变量对应数据库表中的一个字段。每一个字段都使用Field类的实例来表示,比如CharField表示字符类型的字段,DateTimeField 表示日期类型的字段。

每个实例的名字(类中的变量) 就是字段的名字。

每个Field实例你都可以通过位置参数 来 定义一个可读性更强的名字,就像上面的 pub_date 。

现在我们添加了一个叫 poll 的 app, 还写了 model。现在我们生成一下 model(也就是创建数据库表)。

python3 manage.py makemigrations # 相当于 在该app下建立 migrations目录,并记录下你所有的关于modes.py的改动,比如0001_initial.py, 但是这个改动还没有作用到数据库文件。

同步:

python3 manager.py migrate  # 将该改动作用到数据库文件,比如生成数据库表

django admin 是为管理员设计的,它的存在是为了方便管理员对数据进行增删改查 和管理站点任务。

 使用django admin之前我们要先创建超级用户

python3 manage.py createsuperuser  # 创建超级用户

在django admin中现实Poll表

在poll/admin.py中添加如下内容:

from django.contrib import admin

from poll.models import Poll

admin.site.register(Poll)

调整admin中表数据的显示

from django.contrib import admin

# Register your models here.

from poll.models import Poll
from poll.models import Choice



class ChoiceInline(admin.StackedInline):
    model = Choice
    extra = 3

class PollAdmin(admin.ModelAdmin):
    """
    自定义 字段顺序
    """
    fields = ['pub_date', 'question']
    inlines = [ChoiceInline]  # 添加Poll的时候在Poll页面实现添加多个Choice; 和ChoiceInline类共同实现
    list_display = ('question', 'pub_date')

admin.site.register(Poll,PollAdmin)
admin.site.register(Choice)

编写第一个view, views.py中有很多函数,每一个函数可以表示我们的一个或多个页面。

from django.shortcuts import render

# Create your views here.

from django.http import HttpResponse


def index(request):
    return HttpResponse("Hello world!")

我们写出的view 终究是要别人来访问的。而别人放访问网站的页面都是通过url 来访问的。

设计URL

总url配置在 blog/url.py 中进行配置,我们先配置一个最简单的。

from django.conf.urls import url
from django.contrib import admin
from poll import views


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', views.index),        # 对应views.py中的 index函数
    url(r'^poll/$', views.index),   # 对应views.py中的index 函数
]
 

这样我们就编写了一个最基本的页,实现了页面的访问。

如果我们将 views.py中的 index() 函数的返回值,用前端语言包装一下。会有什么效果?

def index(request):
    return HttpResponse("<h1>Hello world!</h1><h2>The second line.</h2>")

这个时候我们就再访问 http://127.0.0.1:8000/ 就会发现 网页的内容变了。

如果index() 返回的内容很多,我们肯定不会这样写,一般我们会将 要返回的内容,放到一个html文件里。

这样我们就可以编写一个见到那的静态网站了。

但是很多时候我们网页的内容是动态变化的。

我们可以在对上面的进行一个简单的修改。

## views.py 
def index(request):
    lst = [1, 2, 3, 4, 5]
    return render(request, 'index.html', {'lst':lst})


## index.html
## 在 body 标签中 增加如下内容
    {% if lst  %}
        <ul>
            {% for i in lst %}
                <li> {{ i }}</li>
            {% endfor %}
        </ul>
    {% endif %}

很多时候,我们是需要操作数据库的:

## views.py 
def index(request):
    lst = [1, 2, 3, 4, 5]
    data = Poll.objects.all()[:5]   # 获取前5个数据,这里得到的是一个QuerySet,  了解更多QuerySet
    print(data)
    return render(request, 'index.html', {'lst':lst, "data":data})



## index.html
## 在 body 标签中 增加如下内容
    {% if data  %}
        <ul>
            {% for i in data %}
                <li> {{ i.id }}</li>
                <li> {{ i.question }}</li>
                <li> {{ i.pub_date }}</li>
            {% endfor %}
        </ul>
    {% endif %}

这些还不够,我们在写django项目的时候,很多时候是要用到bootstrap这怎样的框架的。

在django中我们这样去配置。

在setting.py末尾添加如下内容:

# 更多内容  
STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'statics'), )

# static 目录结构
.
├── blog
├── db.sqlite3
├── manage.py
├── poll
├── static
│   └── bootstrap
│       ├── css
│       │   ├── bootstrap.css
│       │   ├── bootstrap.css.map
│       │   ├── bootstrap.min.css
│       │   ├── bootstrap-theme.css
│       │   ├── bootstrap-theme.css.map
│       │   └── bootstrap-theme.min.css
│       ├── fonts
│       │   ├── glyphicons-halflings-regular.eot
│       │   ├── glyphicons-halflings-regular.svg
│       │   ├── glyphicons-halflings-regular.ttf
│       │   └── glyphicons-halflings-regular.woff
│       ├── jquery-3.1.1.js
│       └── js
│           ├── bootstrap.js
│           ├── bootstrap.min.js
│           └── npm.js
└── templates
# html文件 部分设置
.........
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap-theme.css"> <script src="/static/bootstrap/jquery-3.1.1.js"></script> <script src="/static/bootstrap/js/bootstrap.js"></script> .........

<!--使用bootstrap -->
<h1> <p class="bg-primary">Something Something Something</p> <p class="bg-success">Something Something Something</p> <p class="bg-info">Something Something Something</p> <p class="bg-warning">Something Something Something</p> <p class="bg-danger">Something Something Something</p> </h1> <!-- 通过 JavaScript 启动一个模态框。此模态框将从上到下、逐渐浮现到页面前。 --> <!-- Button trigger modal --> <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal"> Launch demo modal </button> <!-- Modal --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button> <h4 class="modal-title" id="myModalLabel">Modal title</h4> </div> <div class="modal-body"> ... </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div> </div> </div>

前端向后端提交数据

##  views.py
    if request.method == "GET":
        print(request.GET)
        print("GET username: ", request.GET.get("username"))  # request.GET可以看成一个字典,用GET方法传递的值都会保存到其中,
        print("GET password: ", request.GET.get('password'))  # 也可以用 request.GET.get('key', None)来取值,没有时不报错
    elif request.method == "POST":
        print("POST username", request.POST['username'])
        print("POST username", request.POST['password'])


##  index.html
<form action="/" method="post">
    {% csrf_token %}  <!--防御 CSRF(Cross Site Request Forgery, 跨站域请求伪造)-->
    <!--网页的值传到服务器是通过 <input> 或 <textarea>标签中的 name 属性来传递的 -->
    <input type="text" name="username"> <br>
    <input type="text" name="password"> <br>
    <input type="submit" value="提交">
</form>

Web服务器开发领域里著名的MVC模式是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,

  M 模型负责业务对象与数据库的映射(ORM),

  V 视图负责与用户的交互(页面),

  C 控制器接受用户的输入调用模型和视图完成用户的请求:  

Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是值:

  M 代表模型(Model):负责业务对象和数据库的关系映射(ORM)。

  T 代表模板 (Template):负责如何把页面展示给用户(html)。

  V 代表视图(View):负责业务逻辑,并在适当时候调用Model和Template。

除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示

过程:

1.  客户端发送请求

2.  Web服务器(中间件)接收到请求

3.  urlconf中找到对应的 view 函数

4.  view函数根据请求,调用相应的Model存取数据、获取 Template 向用户展示数据

5.  view函数根据处理结果,返回一个Http相应给web服务器

6. web服务器将相应发送给客户端

原文地址:https://www.cnblogs.com/resn/p/6126763.html