Django是一款Python web开发框架,如何形容它 我们可以看下官方给的定义:
Django makes it easier to build better Web apps more quickly and with less code.
(Django使得构建更好的Web应用程序更简单,代码更少。)
Django起源
Django框架是美国World Company的工程师Adrian Holovaty和Simon Willison在开发其公司运行的新闻网站(LJWorld.com、Lawrence.com、KUsports.com ) 过程中,逐渐完善丰富而成,2005年开源,是迄今为止Python界名气最大的Web框架。
Django这个词来自吉普赛语,D不发音,中文通常翻为姜戈,不过也有人相当搞笑的称为强哥
Django框架取名于20世纪三十年代法国著名的爵士吉他手 Django Reinhardt —— 迄今为止最伟大的吉他手之一,尽管他的左手只有三个指头
Django的特点
- 完善的文档(http://python.usyiyi.cn)
- 数据库访问组件(ORM)
- URL映射技术
- 自带管理界面(admin)
- 调试信息完整
Django结构体系
- 管理工具(Management):创建站点,迁移数据,静态文件维护的命令行工具
- 模型(Model):提供数据访问接口和模块,包括数据字段,数据关系的定义及操作
- 视图(View):用来实现向用户返回具体的Web页面数据内容等功能
- 模板(Template):Django自己的一套页面渲染模板语言,更加方便开发者自定义页面的生成方式
- 表单(Form):Django可以通过Model中的字段属性生成对应的HTML表单
开发环境搭建
- Python
Windwos:Python官网下载对应的安装文件
坑点:安装的时候有一个add Paython 3.x to path 一定要勾选上,不然无法打开pip
MAC及Linux自带Python,无需安装 - Django:通过Python的包管理工具pip进行安装
pip install django==1.8.2
#验证Django成功安装
>>> import django
>>> print(django.get_version())
1.8
创建第一个项目
上面我们已经通过pip包管理工具成功安装django,下面我们来使用它创建第一个项目:
django-admin startproject pro_1 会在指定目录下创建一个pro_1的文件夹,我们来解读下目录结构
pro_1
-----pro_1 #整个项目的容器文件夹,这个名称可以随意起
-------__init__.py #这个文件告诉python这个目录是一个包
-------settings.py #该Django项目的配置/设置
-------urls.py #Django项目的总路由管理文件
-------wsgi.py #一个兼容的web服务器入口,在项目运行发布的时候用到
-----manage.py #一个实用的命令行工具,可以让我们以各种方式和Django项目进行交互
Django开发模式:MVT模式
为了更好的理解MVT,我们首先来解读下MVC,MVC 由(试图View/控制器Controller/模型Model)组成,在我们实际应用中,模型(Model)用来处理应用程序数据逻辑,视图(V)用来处理我们从M拿过来的数据,控制器(C)定义程序行为选择相应的视图
大部分开发语言中都有MVC框架,MVC框架的核心思想是解耦,降低各功能模块之间的耦合性,方便变更,更容易重构代码,最大程度上实现代码的重用
MVT基于MVC,并在MVC的基础上做了更细的划分,区别主要在于C 和 T ,C之前是控制器,现在变成了Template,把C融入到了View里。
MVT模式包含:试图(View)负责业务逻辑,并在适当时候调用Model和Template 模板(Template)负责如何把页面展示给用户 模型(Model)处理应用程序数据逻辑
一个完整的Django项目-第一部分(基础+模型)
上面一系列的铺垫后,我们来开始通过Django完成一个完整的项目(本项目案例采用的是官方提供的投票应用)
1.创建项目 django-admin startproject mysite
2.配置数据库 setting.py
默认情况下使用的是SQLite,你不需要额外安装其他内容,SQLite包含在Python中,如果你会其他的数据库也可以在 database binding中配置(我们这个项目采用SQLite)
#创建完项目后默认写法
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
#如需变更修改ENGINE为 'django.db.backends.mysql'或'django.db.backends.oracle'
3.启动服务器
了解了项目的结构以后,我们来验证下Django项目是否正常运行 python manage.py runserver
接下来打开浏览器输入http://127.0.0.1:8000/
当你看到和上图一样的效果就已经执行起来了,如果你的8000被占用,可以指定一个端口
python manage.py runserver 8080
4. 创建应用
项目已经有了,我们需要开始进行加工了,我们需要创建一个具体的应用来完成,项目类似一个大的文件夹,而应用是一个具体的文件,一个项目下面可以包含N个应用,一个应用也可以运用到多个项目中去就是这个道理
创建应用程序,这里要注意我们的目录还是在项目的目录下才可以:
python manage.py startapp polls
创建完成后,会生成的目录结构如下:
polls/
__init__.py
admin.py
migrations/
__init__.py
models.py
tests.py
views.py
5.创建模型
Django模型是与数据库设计相对应,其实数据库也有自己的SQL语句,假设我们不了解数据库语句如何操作数据库,这就Django模型的作用,Django把数据库的语法转换成Python的语法形式,我们只要编写Python代码,Django会把Python代码翻译成对应数据库操作语言。
需求:我们来分析下投票应用,我们将创建两个模型: Question和Choice。Question对象具有一个question_text(问题)属性和一个publish_date(发布时间)属性。 Choice有两个字段:选择的内容和选择的得票统计。 每个Choice与一个Question关联。
模型代码编写在polls/models.py文件中
from django.db import models
class Question(models.Model):
#CharField来表示字符串,max_length 参数则指定 question_text 允许的最大长度
question_text = models.CharField(max_length=200)
#DateTimeField时间类型
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
#ForeignKey表示一种一对多的关联关系
question = models.ForeignKey(Question)
choice_text = models.CharField(max_length=200)
#IntegerField 整数类型
votes = models.IntegerField(default=0)
更多的数据类型可以看下官网文档https://docs.djangoproject.co...
6.迁移操作
我们已经编写了投票应用的数据库模型代码,但是数据库并没有真实创建,因为这还只是python代码,需要通过Django把它翻译成数据库认识的代码,才能执行。
执行后Django会自动完成两个动作,1.为该应用创建数据库表(create table语句)2.创建一个访问数据库的python api
首先我们要把创建好的polls应用告诉项目,打开settings.py文件,修改INSTALLED_APPS
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls'
)
下面我们执行 python manage.py makemigrations polls
通过执行makemigrations告诉Django,对模型做了什么更改,Django接收到之后在migrations下生成一个0001_initial.py文件,这个文件里面就是记录我们对模型做了哪些修改
#0001_initial.py文件
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
]
operations = [
migrations.CreateModel(
name='Choice',
fields=[
('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)),
('choice_text', models.CharField(max_length=200)),
('votes', models.IntegerField(default=0)),
],
),
migrations.CreateModel(
name='Question',
fields=[
('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)),
('question_text', models.CharField(max_length=200)),
('pub_date', models.DateTimeField(verbose_name='date published')),
],
),
migrations.AddField(
model_name='choice',
name='question',
field=models.ForeignKey(to='polls.Question'),
),
]
上面文件看不懂,没有关系,并不要求大家去阅读它,如果你懂数据库的sql语句,我们可以通过下面指令来看下刚刚的Django为我们做了什么 python manage.py sqlmigrate blog 0001
不懂SQL就可以跳过这段了,懂SQL的同学会发现生成的表明和我们定义的不同,以下列了几个说明点:
- 表名是自动生成的,由app的名字(polls)和模型名字的小写字母组合而成 —— question和choice
- 主键(id)是自动添加的。(你也可以重写这个行为。)
- 按照惯例,Django会在外键的字段名后面添加 "_id"。(是的,你依然可以重写这个行为。)
- 外键关系由FOREIGN KEY约束显式声明。不用在意DEFERRABLE部分;它只是告诉PostgreSQL直到事务的最后再执行外键关联。
- sqlmigrate命令并不会在你的数据库上真正运行迁移文件 —— 它只是把Django 认为需要的SQL打印在屏幕上以让你能够看到。
接下来很关键,因为上面步骤下来其实数据库还没有创建,执行python manage.py migrate
执行的过程通过检测刚刚在migrations下生成的文件,知道我们对数据要做哪些操作翻译后执行
migrate命令会找出所有还没有被应用的迁移文件(Django使用数据库中一个叫做django_migrations的特殊表来追踪哪些迁移文件已经被应用过),并且在你的数据库上运行它们 —— 本质上来讲,就是使你的数据库模式和你改动后的模型进行同步。
迁移功能非常强大,可以让你在开发过程中不断修改你的模型而不用删除数据库或者表然后再重新生成一个新的 —— 它专注于升级你的数据库且不丢失数据
模型变更的三个步骤:
修改你的模型(在models.py文件中)。
运行python manage.py makemigrations ,为这些修改创建迁移文件
运行python manage.py migrate ,将这些改变更新到数据库中
7.通过Django提供的API操作数据库
python manage.py shell
一旦你建立好数据模型,Django 会自动为你生成一套数据库抽象的API,可以让你创建、检索、更新和删除对象。
- 添加数据
- 查询数据
好像并看出来查询的内容是什么,我们来修改下models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
再来查询看下
- 修改数据
- 删除数据
当然除了上面列的基础的增删改查操作以外,其他的方法可以看官网https://docs.djangoproject.co...
一个完整的Django项目-第二部分(Admin后台)
Django Admin后台
Django根据前面缩写的模型文件完全自动地生成管理后台,一般情况下后台都是由网站管理员使用,进入admin后台我们首先需要创建一个超级管理员账号,运行 python manage.py createsuperuser 命令新建
这个地方对于之前没有用过linux的人有一个大坑,就是输入密码的时候,并不会显示出来
接下来我们启动开发服务器 python manage.py runserver
打开浏览器访问http://127.0.0.1:8000/admin/
输入刚刚填写的账号密码登录进去后的操作界面如下:
通过上图我们发现可以编辑的Groups、Users它们是由django.contrib.auth提供的,这个认证框架集成在Django中,如何让我们自己的应用也可以编辑,还需要配置一下
打开amdin.py
from django.contrib import admin
from .models import Question,Choice
# Register your models here.
admin.site.register(Question)
admin.site.register(Choice)
然后你就可以通过这个管理后台去进行操作了
一个完整的Django项目-第三部分(视图)
Web引用的交互过程其实就是HTTP请求与响应的过程
在Django中,网页的页面和其他内容都是由视图来传递的(视图对WEB请求进行回应)。每个视图都是由一个简单的Python函数(或者是基于类的视图的方法)表示的。Django通过检查请求的URL(准确地说,是URL里域名之后的那部分)来选择使用哪个视图。
在我们的投票应用中,将有以下四个视图:
- Question首页 —— 显示最新发布的几个Question。
- Question“详细”页面 —— 显示单个Question的具体内容,不显示该议题的当前投票结果,而是提供一个投票的表单。
- Question“结果”页面 —— 显示特定的Question的投票结果。
- 投票功能 —— 处理对Question中Choice的投票。
编写视图,在views.py文件中输入
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
为了能够调用视图,我们需要把视图映射到URL上,我们在polls文件夹下创建一个 urls.py配置
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
]
下一步,我们需要从主urls.py中配置
#坑点:注意urlpaterns前面的空格
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^polls/', include('polls.urls')),
]
访问http://127.0.0.1:8000/polls/即可看到页面输出Hello, world. You're at the polls index.
这个地方配置的url有4个参数:
- regex(必填):regex意思是‘正则表达式’用于匹配字符串中的模式的语法,在这里是匹配url
- view(必填):当Django找到成功匹配正则规则的话,就会调用view参数指定的视图函数,并将HttpRequest对象作为第一个参数
- kwargs(可选):任何关键字参数都可以以字典形式传递给目标视图
- name(可选)命名你的URL,可以在Django中通过名称明确的引用这个URL
我们来写一个带参数的视图
首先修改views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
def detail(request, question_id):
return HttpResponse("You're looking at question %s." % question_id)
def results(request, question_id):
response = "You're looking at the results of question %s."
return HttpResponse(response % question_id)
def vote(request, question_id):
return HttpResponse("You're voting on question %s." % question_id)
修改polls/urls.py
urlpatterns = [
# ex: /polls/
url(r'^$', views.index, name='index'),
# ex: /polls/5/
url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
# ex: /polls/5/results/
url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
# ex: /polls/5/vote/
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]
来实现看看能不能捕获到我们的参数http://127.0.0.1:8000/polls/21/
这是一个华丽的分割线,上面都是视图的小菜,现在来开始进入视图的正题了,我们需要视图显示数据这个应该怎么做
#修改views.py文件的index
from django.http import HttpResponse
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
output = ', '.join([p.question_text for p in latest_question_list])
return HttpResponse(output)
访问http://127.0.0.1:8000/polls/ 可以看到在Admin后台添加的数据
一个完整的Django项目-第四部分(模板)
上面视图出来的数据了,页面丑么?丑
我们应该怎么改变页面的外观,Django提供了模板系统,通过创建一个视图能够调用的模板,将页面的设计从Python中分离出来。首先在polls目录下创建一个叫templates的文件里,django将在这里查找模板,为了更好的重用我们在templates下创建polls文件夹,再创建index.html
路径目录为:polls/templates/polls/index.html
在index.html中插入代码
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
修改views.py
from django.http import HttpResponse
from django.template import RequestContext, loader
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = RequestContext(request, {
'latest_question_list': latest_question_list,
})
return HttpResponse(template.render(context))
这次再来运行,将你的浏览器指向‘/polls’来加载这个页面,页面样式也有了
上面代码是不是太过繁琐,我们可以修改下views.py
from django.shortcuts import render
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'latest_question_list': latest_question_list}
return render(request, 'polls/index.html', context)
render()函数将请求对象作为它的第一个参数,模板的名字作为它的第二个参数,一个字典作为它可选的第三个参数。 它返回一个HttpResponse对象,含有用给定的context 渲染后的模板。
现在来处理下详情页面的视图,首先创建detail.html (polls/templates/polls/detail.html)页面插入内容
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
处理views.py下的detail
def detail(request, question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
return render(request, 'polls/detail.html', {'question': question})
当你访问列表页面http://127.0.0.1:8000/polls/ 点击标题既可以进入看到详情,页面的样式我并没有太多的CSS,样式部分我们可以自己补充
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。