Django使用手册

Django教程

Python是我学习的第一门编程语言,这两天刚刚学完python的WEB-django框架,参考其他书友的教程,结合自己的理解,对其进行简单的归纳总结。

一.搭建虚拟环境。

1.为什么使用虚拟环境?

一台电脑上可能有多个项目,项目之间所使用的Django版本可能不同,这时就需要使用虚拟环境来创建想对独立的python环境

virtualenvvirtualenvwrapper都可以用来创建虚拟环境,只是由于virtualenv用起来有点麻烦,所以wrapper对它进行了封装,让它更好用,最终我们使用wrapper提供的命令,但是实际工作都是virtualenv做的。

virtualenvwrapper的好处是,把虚拟环境全局管理起来了,不用针对每个项目建立。同一类项目(使用的django版本相同)可以建立同样的虚拟环境,也不用管它在哪,直接一个workon就可以。

2.如何安装配置虚拟环境?


Window 10平台

需要安装两个python模块

pip install virtualenv

pip install virtualenvwrapper-win


需要配置环境变量(默认虚拟环境会建立在系统c盘,不推荐)

实质为配置虚拟环境生成的位置

配置环境变量:

此电脑-》右键属性-》高级设置-》高级-》环境变量

点击系统变量下方的新建按钮,打开创建窗口

变量名:WORKON_HOME

变量值:虚拟环境存放路径(创建的用来作虚拟环境的空文件夹命名必须是英文,不能出现任何中文,最好是创建在一个磁盘的根路径下)


运行管理员窗口:

常用命令:

创建虚拟环境:mkvirtualenv环境名

切换虚拟环境:    workon 环境名

查看所有虚拟环境:  lsvirtualenv

删除虚拟环境:  rmvirtualenv 环境名

退出虚拟环境:deactivate

3.django安装(在虚拟环境下)

一般来说,选择长期支持版本比较好。

pip install django==1.8.2

pip install Django==2.0.3

pip install django

检查是否安装成功

进入python环境,运行如下代码:

import django

django.get_version()

二.Django开发流程

1.新建项目 :

django-admin startproject 项目名 这样会在当前目录新建一个目录,里面已经有一些基本的配置文件:

项目配置文件


目录说明

manage.py:一个命令行工具,可以使你用多种方式对Django项目进行交互

内层的目录:项目的真正的Python包

_init _.py:一个空文件,它告诉Python这个目录应该被看做一个Python包

settings.py:项目的配置文件(如配置数据库)

urls.py:项目的URL声明

wsgi.py:项目与WSGI兼容的Web服务器入口

2.新建APP:

 django-admin startapp APP名称 如果是搭建一个非常简单的应用,那么不使用APP也行,只需要吧路由指向目标view就可以了,但是如果要搭建复杂的应用并且需要良好的隔离性,那最好使用APP。同样,使用该命令也会在当前目录下新建一个目录,里面已经包含一些配置文件:


应用配置文件

创建APP后,需要在主配置文件settings.py里面的INSTALLED_APPS里面添加该APP的名称

3.Pycharm使用指定的虚拟环境打开上述项目

选中导航栏中的File右键单击打开选择Settings-->Project-->project interpreter-->设置按钮——》打开Add python interpreter窗口——》选择System interpreter--》在右边的Base interpreter:选项中点击右边的三个点打开找到虚拟环境的文件位置,找到python.exe选中

4.数据库

Django同很多框架一样使用了ORM(Object Relational Mapping,对象关系映射)的方式,每个model类代表一张数据库的表,每一个属性代表其一个字段(这种特性的实现依赖于python的元类)。

数据表定义

在APP(应用)配置文件models.py中新建模型类),如:定义一张商品表

商品表

当建立好models过后,执行如下迁移命令就可以在数据库中新建或更新数据表了:

生成迁移文件:根据模型类生成sql语句

python manage.py makemigrations

执行迁移:执行sql语句生成数据表

python manage.py migrate

注:在已经迁移的数据模型中添加字段,再次进行迁移,那么新添加的数据必须要允许null或者设置默认值,否则会报错,这其实是为了保护已经存在了的数据,当然在添加完该字段后把null去掉再更新数据库就可以了。

字段类型

注:Django默认为每张表设置了一个int(11)的自增主键(即id),不需要自己去定义了。

常用类型

# 数字类型:

AutoField:一个根据实际ID自动增长的IntegerField,通常不指定;如果不指定,一个主键字段将自动添加到模型中

IntegerField    (默认长度为11)的整数

PositiveIntegerField:

SmallIntegerField

PositiveSmallIntegerField

BigIntegerField:

BinaryField:

BooleanField:true/false 字段,此字段的默认表单控制是CheckboxInput

NullBooleanField:支持null、true、false三种值

DecimalField(max_digits=None, decimal_places=None):使用python的Decimal实例表示的十进制浮点数;DecimalField.max_digits:位数总数 ;DecimalField.decimal_places:小数点后的数字位数

FloatField:用Python的float实例来表示的浮点数

# 字符类型

CharField(max_length=字符长度):字符串,默认的表单样式是 TextInput,

只需要指定枚举枚举元组即可,例如type = models.CharField('类型', choices=CONTENT_TYPE),其中CONTENT_TYPE=(('a', 'abc'))

TextField:text类型,大文本字段,一般超过4000使用,默认的表单控件是Textarea

CommaSeparatedIntegerField:用逗号分隔的整数,我擦,这有用

# 时间类型

DateField[auto_now=False, auto_now_add=False]):使用Python的datetime.date实例表示的日期(参数DateField.auto_now:每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false;

参数DateField.auto_now_add:当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false

该字段默认对应的表单控件是一个TextInput. 在管理员站点添加了一个JavaScript写的日历控件,和一个“Today"的快捷按钮,包含了一个额外的invalid_date错误消息键

auto_now_add, auto_now, and default 这些设置是相互排斥的,他们之间的任何组合将会发生错误的结果


TimeField:使用Python的datetime.time实例表示的时间,参数同DateField

DateTimeField() # DATETIME类型,包括了日期和时间,需要注意的是Django默认的TIME_ZONE是UTC;在初始化的时候,格式如"2015-04-27T15:01:00Z",它属于python里面的datetime.datetime类型,可分别用year/month/day等获取时间。另外Django如果要实用MySQL里面的TIMESTAMP类型也是用该字段表示,并且在插入的时候不能直接插入一个整数,依然只能插入一个datetime.datetime对象,用时间戳的时候USE_TZ必须为False

FileField:一个上传文件的字段

ImageField:继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image

其它很有用的类型:

EmailField:Email邮箱类型FileField:文件类型,不过不能设置为primary_key和unique,要使用该字段还有很多需要注意的地方,具体的见官方文档

FilePathField:同上ImageFieldIPAddressField:从1.7开始已经不建议使用了,应该使用下面这个GenericIPAddressField:

URLField

UUIDField

字段通用参数

primary_key:若为 True, 则该字段会成为模型的主键字段

null:如果为True,Django 将空值以NULL 存储到数据库中,默认值是 False

blank:如果为True,则该字段允许为空白,默认值是 False

null和blank对比:null是数据库范畴的概念,blank是表单验证证范畴的

max_length = 3           最大长度,对整型无效

default = ''              设置默认值

verbose_name =         相当于备注,如果没给出那么就是该字段,当然,要指定的话,可以直接第一个参数一个字符串就可以指定了

editable = False/True      # 是否可编辑

unique:如果为 True, 这个字段在表中必须有唯一值

auto_now = False/True      # 用于时间,每次更新记录的时候更新该字段

auto_now_add = False/True  # 用于时间,创建新纪录的时候自动更新该字段

db_column:字段的名称,如果未指定,则使用属性的名称

db_index:若值为 True, 则在表中会为此字段创建索引

help_text:会在form表单控件中显示help文本

choices # 很实用的一个功能,相当于存储一个枚举列表,其中左边的key是实际存储在数据库中的值,例如,可以这样定义一个字段:YEAR_IN_SCHOOL_CHOICES= (

        ('FR', 'Freshman'),

        ('SO', 'Sophomore'),

        ('JR', 'Junior'),

        ('SR', 'Senior'),

 )        

然后在定义字段的时候给个参数choices=YEAR_IN_SCHOOL_CHOICES,在插入字段的时候,使用'RF'这样的,在获取字段值的时候这样:p.get_year_in_school_display()即可显示'Freshman'

verbose_name        # 定义字段的注释

关系的类型包括

ForeignKey:一对多,将字段定义在多的一端中

ManyToManyField:多对多,将字段定义在两端中

OneToOneField:一对一,将字段定义在任意一端中

5.配置项

全局配置

DEBUG =True      # DEBUG模式  ;项目在开发过程中 需要设置Debug为False 上线部署之后关闭调试模式

TEMPLATE_DEBUG =True# TEMPLATE的DEBUG模式

ALLOWED_HOSTS = []# 设置哪些域名可以访问,当debug为false时必须为其指定一个值,['*']表示允许所有的访问

INSTALLED_APPS = [默认APP+自己的APP]

MIDDLEWARE_CLASSES = [中间件]

ROOT_URLCONF ='admin.urls'# 读取的默认的url文件

TEMPLATES =[ {  'DIRS': [os.path.join(BASE_DIR,"templates")],    }] 配置templates(模块,即HTML前端页面)

# Database 数据库的配置:(默认自带sqlite3数据库)

mysql数据库

LANGUAGE_CODE ='en-us'           # 语言,中文可用zh-Hans、zh-CN,完整列表见:http://www.i18nguy.com/unicode/language-identifiers.html

TIME_ZONE ='Asia/Chongqing'# 时区

USE_TZ =False# 数据库中要使用时间戳就应该关闭这个

# Static files (CSS, JavaScript, Images) 静态文件目录

 STATIC_URL ='/static/'

STATICFILES_DIRS = [os.path.join(BASE_DIR,'static')] 配置自己创建的静态文件(即js/css/img)

STATIC_ROOT = os.path.join(BASE_DIR,'static')# 这个选项默认是没有的,在编码时将静态文件放在APP中的static目录下,部署时用python manage.py collectstatic就可以把静态文件收集到STATIDC_ROOT目录


# 配置 存储session使用redis数据库

# SESSION_ENGINE = 'redis_sessions.session'

# SESSION_REDIS_HOST = 'localhost'

# SESSION_REDIS_PORT = 6379

# SESSION_REDIS_DB = 0

# SESSION_REDIS_PASSWORD = ''

# SESSION_REDIS_PREFIX = 'session'

发送邮件配置

EMAIL_BACKEND ='django.core.mail.backends.smtp.EmailBackend'

EMAIL_USE_TLS =True #是否使用TLS安全传输协议(用于在两个通信应用程序之间提供保密性和数据完整性。)

EMAIL_USE_SSL =False #是否使用SSL加密,qq企业邮箱要求使用

EMAIL_HOST ='smtp.163.com' #发送邮件的邮箱 的 SMTP服务器,这里用了163邮箱

EMAIL_PORT =25 #发件箱的SMTP服务器端口

EMAIL_HOST_USER ='18137128152@163.com' #发送邮件的邮箱地址

EMAIL_HOST_PASSWORD ='qikuedu'

DEFAULT_FROM_EMAIL ='zzyblog <18137128152@163.com>'     (发件人)

请求与响应

HttpReqeust对象

服务器接收到http协议的请求后,会根据报文创建HttpRequest对象

视图函数的第一个参数是HttpRequest对象

在django.http模块中定义了HttpRequest对象的API

属性

下面除非特别说明,属性都是只读的

path:一个字符串,表示请求的页面的完整路径,不包含域名

method:一个字符串,表示请求使用的HTTP方法,常用值包括:'GET'、'POST'

encoding:一个字符串,表示提交的数据的编码方式

如果为None则表示使用浏览器的默认设置,一般为utf-8

这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值

GET:一个类似于字典的对象,包含get请求方式的所有参数

POST:一个类似于字典的对象,包含post请求方式的所有参数

FILES:一个类似于字典的对象,包含所有的上传文件

COOKIES:一个标准的Python字典,包含所有的cookie,键和值都为字符串

session:一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django 启用会话的支持时才可用,详细内容见“状态保持”

方法

is_ajax():如果请求是通过XMLHttpRequest发起的,则返回True

HttpResponse对象

在django.http模块中定义了HttpResponse对象的API

HttpRequest对象由Django自动创建,HttpResponse对象由程序员创建

不调用模板,直接返回数据

from django.http import HttpResponse

def index(request):

return HttpResponse('你好')

调用模板

from django.http import HttpResponse

from django.template import RequestContext, loader

def index(request):

        t1 = loader.get_template('polls/index.html')

        context = RequestContext(request, {'h1': 'hello'})

        return HttpResponse(t1.render(context))

属性

content:表示返回的内容,字符串类型

charset:表示response采用的编码字符集,字符串类型

status_code:响应的HTTP响应状态码

content-type:指定输出的MIME类型

方法

init :使用页内容实例化HttpResponse对象

write(content):以文件的方式写

flush():以文件的方式输出缓存区

set_cookie(key, value='', max_age=None, expires=None):设置Cookie

key、value都是字符串类型

max_age是一个整数,表示在指定秒数后过期

expires是一个datetime或timedelta对象,会话将在这个指定的日期/时间过期,注意datetime和timedelta值只有在使用PickleSerializer

时才可序列化

max_age与expires二选一

如果不指定过期时间,则两个星期后过期

from django.http import HttpResponse

from datetime import *

def index(request):

        response = HttpResponse()

        if request.COOKIES.has_key('h1'):

        response.write('

        ' + request.COOKIES['h1'] + '

        ')

        response.set_cookie('h1', '你好', 120)

        # response.set_cookie('h1', '你好', None, datetime(2016, 10, 31))

        return response

delete_cookie(key):删除指定的key的Cookie,如果key不存在则什么也不发生

子类HttpResponseRedirect

重定向,服务器端跳转

构造函数的第一个参数用来指定重定向的地址

from django.http import HttpResponse,HttpResponseRedirect

def index2(request,id):

        print(id,type(id))

       return HttpResponseRedirect("/redirecttest")

简写函数

render

render(request, template_name[, context])

结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的HttpResponse对象

request:该request用于生成response

template_name:要使用的模板的完整名称

context:添加到模板上下文的一个字典,视图将在渲染模板之前调用它

from django.shortcuts import render

def index(req):

        return render(req, 'booktest/index.html', {'h1': 'hello'})

重定向

redirect(to)

为传递进来的参数返回HttpResponseRedirect

to推荐使用反向解析

from django.shortcuts import redirect

from django.core.urlresolvers import reverse

def index(req):

        return redirect(reverse('booktest:index2'))


6.路由与视图

url: web访问请求的入口(相当于Laravel里的路由)

view:应用的逻辑部分,从客户端接收请求,处理并返回数据,一般返回到template模板进行渲染(相当于Laravel里的控制器)

将/list定位到booktest这个APP里面的views里面的list视图方法来处理的形式

app_name ="booktest"

urlpatterns = [

url(r'^list/$',list,name="list"),

给url命名可以方便我们进行统一修改url样式,比如之前用list的url可以访问到list这个方法,但现在如果想改成ls的方式来访问,那么由于后端的模板渲染等都是用的其命名list,就无需修改后端逻辑了

路由按照app分组

首先主urls.py里面使用include包含应用下的urls.py文件

from django.conf.urls import include

urlpatterns = [

        url(r'^app1', include('app1.urls',namespace='app1')),

]

然后在app1下的urls.py文件里面,进行如下设置:

from django.conf.urls import url

from . import views

app_name ="app1"

urlpatterns = [

    url(r'^/(\d+)$', views.hello,,name="index"), #一个参数对应一个分组。

]

7.ORM增删改查

ORM代替SQL语句实现

进入shell命令行:  python manage.py shell

引入所需的模型类 from APP(应用名).models import   模型类

查询记录

Blog.objects.all()# 获取该表的所有记录,返回的是记录对象组成的列表

Blog.objects.get(pk=1)# 根据主键获取数据

Blog.objects.get(name="")# 只会找到第一个匹配的数据

Blog.objects.filter(name="")# 这个就会找到匹配的多个数据

Blog.objects.filter(name__contains="")# 模糊查找name字段的值,返回列表Blog.objects.order_by("字段1","字段2")# 排序,order_by不加任何参数表示不需要排序(字段前'+'代表升序,'-'代表降序。)

Blog.objects.all().order_by("字段")

Blog.objects.count()# 返回记录总数

Blog.objects.values('id','name')  # 相当于select id name from Blog,返回的是一个字典Blog.objects.values('name').distinct()  # distinct在django的mysql引擎中无法对field进行distinct操作,所以需要这样做Blog.objects.values_list('id', flat=True)# 查询该字段的所有值并且返回的是id的列表,而不是包括了名字的字典

Blog.objects.all().defer('title')# 仅仅取某个字段,这里返回是一个model对象Blog.objects.all().only('title')# 仅仅取某个字段,也是返回一个model对戏那个Blog.objects.all().values_list('title')# 仅仅取某个字段,这里返回一个数组

Blog.objects.latest('id')# 根据某个字段查找其最后一条记录,返回的是一个对戏那个,不是id

Blog.objects.filter(time__gte ='2015-07-23', time__lte ='2015-07-24')# 大于等于并且小于等于,不加e表示不能等于

Blog.objects.filter(time__isnull =True)# 判断某个字段是否为空

Blog.objects.all().exclude(id=7)# 排除,即不等于Blog.objects.filter('time__year':'2015','time__month':'08','time__day':'17'):按年月日查询日期,可仅查询其中某一个条件

增加记录:

book= BookInfo()

book.title = “神雕侠侣”

book.pub_date = “1998-01-01”

book.save()

修改记录

修改书标题

book.title = “神雕侠侣续集”

book.save()

删除记录

删除shan图书

book.delete()

关联查询

数据库中存储外键为整形

ORM中外键为对象类型

1.一对一(关联关系双方可随意定义):

外键创建方法:models.OneToOneField()

关联方(关联关系所在方)查找非关联方:关联方对象.关联关系名

非关联方查找关联方:非关联方对象.关联方类名(小写)

2.多对多(关联关系双方随意定义):

外键创建方法:models.ManyToManyField()

关联方(关联关系所在方)查找非关联方:关联方对象.关联关系名

非关联方查找关联方:非关联方对象.关联方类名(小写)_set.all()

3.一对多(关联关系定义在多方):

外键创建方法:models.Foreignkey()

关联方(关联关系所在方)查找非关联方:关联方对象.关联关系名

非关联方查找关联方:非关联方对象.关联方类名小写_set.all()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,780评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,424评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,397评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,576评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,997评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,945评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,107评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,850评论 0 208
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,625评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,804评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,285评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,613评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,291评论 3 242
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,164评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,963评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,096评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,886评论 2 278

推荐阅读更多精彩内容