Django综述

1入门框架思想          MVC大部分开发语言中都有MVC框架MVC框架的核心思想是:解耦降低各功能模块之间的耦合性,方便变更,更容易重构代码,最大程度上实现代码的重用m表示model,主要用于对数据库层的封装v表示view,用于向用户展示结果c表示controller,是核心,用于处理请求、获取数据、返回结果MVTDjango是一款python的web开发框架与MVC有所不同,属于MVT...
摘要由CSDN通过智能技术生成

1入门

框架思想

          MVC
  • 大部分开发语言中都有MVC框架
  • MVC框架的核心思想是:解耦
  • 降低各功能模块之间的耦合性,方便变更,更容易重构代码,最大程度上实现代码的重用
  • m表示model,主要用于对数据库层的封装
  • v表示view,用于向用户展示结果
  • c表示controller,是核心,用于处理请求、获取数据、返回结果
  • MVT
  • Django是一款python的web开发框架
  • 与MVC有所不同,属于MVT框架
  • m表示model,负责与数据库交互
  • v表示view,是核心,负责接收请求、获取数据、返回结果
  • t表示template,,负责呈现内容到浏览器

  02主要知识点介绍

  • 环境搭建
  • 定义模型
  • 使用后台管理
  • 编写视图
  • 定义模板    
  • 创建虚拟环境

    • 创建:mkvirtualenv [虚拟环境名称]
    • 删除:rmvirtualenv [虚拟环境名称]
    • 进入:workon [虚拟环境名称]
    • 退出:deactivate
    • 所有的虚拟环境,都位于/home/.virtualenvs目录下
    • 进入虚拟环境前的提示:
    • 进入虚拟环境后的提示:
    • 查看当前的所有虚拟环境:workon [两次tab键]
    • 查看虚拟环境中已经安装的包
    pip list
    pip freeze
    

    安装django

    • 建议安装1.8.2版本,这是一个稳定性高、使用广、文档多的版本
    pip install django==1.8.2
    
    • 查看版本:进入python shell,运行如下代码
    import django
    django.get_version()
    
    • 说明:使用pip install django命令进行安装时,会自动删除旧版本,再安装新版本

    创建项目

    • 命令django-admin startproject test1
    • 进入test1目录,目录结构如下图:

    目录说明

    • manage.py:一个命令行工具,可以使你用多种方式对Django项目进行交互
    • 内层的目录:项目的真正的Python包
    • _init _.py:一个空文件,它告诉Python这个目录应该被看做一个Python包
    • settings.py:项目的配置
    • urls.py:项目的URL声明
    • wsgi.py:项目与WSGI兼容的Web服务器入口

    设计介绍

    • 本示例完成“图书-英雄”信息的维护,需要存储两种数据:图书、英雄
    • 图书表结构设计:
      • 表名:BookInfo
      • 图书名称:btitle
      • 图书发布时间:bpub_date
    • 英雄表结构设计:
      • 表名:HeroInfo
      • 英雄姓名:hname
      • 英雄性别:hgender
      • 英雄简介:hcontent
      • 所属图书:hbook
    • 图书-英雄的关系为一对多

    数据库配置

    • 在settings.py文件中,通过DATABASES项进行数据库设置
    • django支持的数据库包括:sqlite、mysql等主流数据库
    • Django默认使用SQLite数据库

    创建应用

    • 在一个项目中可以创建一到多个应用,每个应用进行一种业务处理
    • 创建应用的命令:
    python manage.py startapp booktest
    
    • 应用的目录结构如下图


    定义模型类
    • 有一个数据表,就有一个模型类与之对应
    • 打开models.py文件,定义模型类
    • 引入包from django.db import models
    • 模型类继承自models.Model类
    • 说明:不需要定义主键列,在生成时会自动添加,并且值为自动增长
    • 当输出对象时,会调用对象的str方法
    from django.db import models
    
    class BookInfo(models.Model):
        btitle = models.CharField(max_length=20)
        bpub_date = models.DateTimeField()
        def _ _str_ _(self):
            return "%d" % self.pk
    
    class HeroInfo(models.Model):
        hname = models.CharField(max_length=20)
        hgender = models.BooleanField()
        hcontent = models.CharField(max_length=100)
        hBook = models.ForeignKey('BookInfo')
        def _ _str_ _(self):
            return "%d" % self.pk
    
    生成数据表
    • 激活模型:编辑settings.py文件,将booktest应用加入到installed_apps中


    • 生成迁移文件:根据模型类生成sql语句
    python manage.py makemigrations
    
    • 迁移文件被生成到应用的migrations目录

    • 执行迁移:执行sql语句生成数据表
    python manage.py migrate
    
    测试数据操作
    • 进入python shell,进行简单的模型API练习
    python manage.py shell
    
    • 进入shell后提示如下:

    • 引入需要的包:
    from booktest.models import BookInfo,HeroInfo
    from django.utils import timezone
    from datetime import *
    
    • 查询所有图书信息:
    BookInfo.objects.all()
    
    • 新建图书信息:
    b = BookInfo()
    b.btitle="射雕英雄传"
    b.bpub_date=datetime(year=1990,month=1,day=10)
    b.save()
    
    • 查找图书信息:
    b=BookInfo.objects.get(pk=1)
    
    • 输出图书信息:
    b
    b.id
    b.btitle
    
    • 修改图书信息:
    b.btitle=u"天龙八部"
    b.save()
    
    • 删除图书信息:
    b.delete()
    
    关联对象的操作
    • 对于HeroInfo可以按照上面的操作方式进行
    • 添加,注意添加关联对象
    h=HeroInfo()
    h.htitle=u'郭靖'
    h.hgender=True
    h.hcontent=u'降龙十八掌'
    h.hBook=b
    h.save()
    
    • 获得关联集合:返回当前book对象的所有hero
    b.heroinfo_set.all()
    
    • 有一个HeroInfo存在,必须要有一个BookInfo对象,提供了创建关联的数据:
    h=b.heroinfo_set.create(htitle=u'黄蓉',hgender=False,hcontent=u'打狗棍法')
    h

    服务器

    • 运行如下命令可以开启服务器
    python manage.py runserver ip:port
    
    • 可以不写ip,默认端口为8000
    • 这是一个纯python编写的轻量级web服务器,仅在开发阶段使用
    • 服务器成功启动后,提示如下信息

    • 默认端口是8000,可以修改端口
    python manage.py runserver 8080
    
    • 打开浏览器,输入网址“127.0.0.1:8000”可以打开默认页面
    • 如果修改文件不需要重启服务器,如果增删文件需要重启服务器
    • 通过ctrl+c停止服务器

    管理操作

    • 站点分为“内容发布”和“公共访问”两部分
    • “内容发布”的部分负责添加、修改、删除内容,开发这些重复的功能是一件单调乏味、缺乏创造力的工作。为此,Django会根据定义的模型类完全自动地生成管理模块
    使用django的管理
    • 创建一个管理员用户
    python manage.py createsuperuser,按提示输入用户名、邮箱、密码
    
    • 启动服务器,通过“127.0.0.1:8000/admin”访问,输入上面创建的用户名、密码完成登录
    • 进入管理站点,默认可以对groups、users进行管理
    管理界面本地化
    • 编辑settings.py文件,设置编码、时区
    LANGUAGE_CODE = 'zh-Hans'
    TIME_ZONE = 'Asia/Shanghai'
    
    向admin注册booktest的模型
    • 打开booktest/admin.py文件,注册模型
    from django.contrib import admin
    from models import BookInfo
    admin.site.register(BookInfo)
    
    • 刷新管理页面,可以对BookInfo的数据进行增删改查操作
    • 问题:如果在str方法中返回中文,在修改和添加时会报ascii的错误
    • 解决:在str()方法中,将字符串末尾添加“.encode('utf-8')”
    自定义管理页面
    • Django提供了admin.ModelAdmin类
    • 通过定义ModelAdmin的子类,来定义模型在Admin界面的显示方式
    class QuestionAdmin(admin.ModelAdmin):
        ...
    admin.site.register(Question, QuestionAdmin)
    
    列表页属性
    • list_display:显示字段,可以点击列头进行排序
    list_display = ['pk', 'btitle', 'bpub_date']
    
    • list_filter:过滤字段,过滤框会出现在右侧
    list_filter = ['btitle']
    
    • search_fields:搜索字段,搜索框会出现在上侧
    search_fields = ['btitle']
    
    • list_per_page:分页,分页框会出现在下侧
    list_per_page = 10
    
    添加、修改页属性
    • fields:属性的先后顺序
    fields = ['bpub_date', 'btitle']
    
    • fieldsets:属性分组
    fieldsets = [
        ('basic',{'fields': ['btitle']}),
        ('more', {'fields': ['bpub_date']}),
    ]
    
    关联对象
    • 对于HeroInfo模型类,有两种注册方式

      • 方式一:与BookInfo模型类相同
      • 方式二:关联注册
    • 按照BookInfor的注册方式完成HeroInfo的注册

    • 接下来实现关联注册
    from django.contrib import admin
    from models import BookInfo,HeroInfo
    
    class HeroInfoInline(admin.StackedInline):
        model = HeroInfo
        extra = 2
    
    class BookInfoAdmin(admin.ModelAdmin):
        inlines = [HeroInfoInline]
    
    admin.site.register(BookInfo, BookInfoAdmin)
    
    • 可以将内嵌的方式改为表格
    class HeroInfoInline(admin.TabularInline)
    
    布尔值的显示
    • 发布性别的显示不是一个直观的结果,可以使用方法进行封装
    def gender(self):
        if self.hgender:
            return '男'
        else:
            return '女'
    gender.short_description = '性别'
    
    • 在admin注册中使用gender代替hgender
    class HeroInfoAdmin(admin.ModelAdmin):
        list_display = ['id', 'hname', 'gender', 'hcontent']

视图

  • 在django中,视图对WEB请求进行回应
  • 视图接收reqeust对象作为第一个参数,包含了请求的信息
  • 视图就是一个Python函数,被定义在views.py中
#coding:utf-8
from django.http import HttpResponse

def index(request):
    return HttpResponse("index")
def detail(request,id):
    return HttpResponse("detail %s" % id)
  • 定义完成视图后,需要配置urlconf,否则无法处理请求

URLconf

  • 在Django中,定义URLconf包括正则表达式、视图两部分
  • Django使用正则表达式匹配请求的URL,一旦匹配成功,则调用应用的视图
  • 注意:只匹配路径部分,即除去域名、参数后的字符串
  • 在test1/urls.py插入booktest,使主urlconf连接到booktest.urls模块
url(r'^', include('booktest.urls')),
  • 在booktest中的urls.py中添加urlconf
from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'^$', views.index),
    url(r'^([0-9]+)/$', views.detail),
]

模板

  • 模板是html页面,可以根据视图中传递的数据填充值
  • 创建模板的目录如下图:

  • 修改settings.py文件,设置TEMPLATES的DIRS值
'DIRS': [os.path.join(BASE_DIR, 'templates')],
  • 在模板中访问视图传递的数据
{
  {输出值,可以是变量,也可以是对象.属性}}
{%执行代码段%}
定义index.html模板
<!DOCTYPE html>
<html>
<head>
  <title>首页</title>
</head>
<body>
<h1>图书列表</h1>
<ul>
{%for book in booklist%}
<li>
  <a href="{
  {book.id}}">
    {
  {book.btitle}}
  </a>
</li>
{%endfor%}
</ul>
</body>
</html>
定义detail.html模板
  • 在模板中访问对象成员时,都以属性的方式访问,即方法也不能加括号
<!DOCTYPE html>
<html>
<head>
  <title>详细页</title>
</head>
<body>
<h1>{
  {book.btitle}}</h1>
<ul>
  {%for hero in book.heroinfo_set.all%}
  <li>{
  {hero.hname}}---{
  {hero.hcontent}}</li>
  {%endfor%}
</ul>
</body>
</html>

使用模板

  • 编辑views.py文件,在方法中调用模板
from django.http import HttpResponse
from django.template import RequestContext, loader
from models import BookInfo

def index(request):
    booklist = BookInfo.objects.all()
    template = loader.get_template('booktest/index.html')
    context = RequestContext(request, {'booklist': booklist})
    return HttpResponse(template.render(context))


def detail(reqeust, id):
    book = BookInfo.objects.get(pk=id)
    template = loader.get_template('booktest/detail.html')
    context = RequestContext(reqeust, {'book': book})
    return HttpResponse(template.render(context))

去除模板的硬编码

  • 在index.html模板中,超链接是硬编码的,此时的请求地址为“127.0.0.1/1/”
<a href="{
  {book.id}}">
  • 看如下情况:将urlconf中详细页改为如下,链接就找不到了
url(r'^book/([0-9]+)/$', views.detail),
  • 此时的请求地址应该为“127.0.0.1/book/1/”
  • 问题总结:如果在模板中地址硬编码,将来urlconf修改后,地址将失效
  • 解决:使用命名的url设置超链接
  • 修改test1/urls.py文件,在include中设置namespace
url(r'^admin/', include(admin.site.urls, namespace='booktest')),
  • 修改booktest/urls.py文件,设置name
url(r'^book/([0-9]+)/$', views.detail, name="detail"),
  • 修改index.html模板中的链接
<a href="{%url 'booktest:detail' book.id%}">

Render简写

  • Django提供了函数Render()简化视图调用模板、构造上下文
from django.shortcuts import render
from models import BookInfo

def index(reqeust):
    booklist = BookInfo.objects.all()
    return render(reqeust, 'booktest/index.html', {'booklist': booklist})


def detail(reqeust, id):
    book = BookInfo.objects.get(pk=id)
    return render(reqeust, 'booktest/detail.html', {'book': book})

总结

  1. 安装配置django运行的环境
  2. 编写模型,使用简单API与数据库交互
  3. 使用django的后台管理中维护数据
  4. 通过视图接收请求,通过模型获取数据,展示出来
  5. 调用模板完成展示

作业

  • 设计一对多关系的两个模型类
  • 使用django后台管理
  • 通过视图、urlconf、模板完成数据的展示
  • 控制在2个小时之内完成

2.模型

    ORM简介

  • MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库
  • ORM是“对象-关系-映射”的简称,主要任务是:
    • 根据对象的类型生成表结构
    • 将对象、列表的操作,转换为sql语句
    • 将sql查询到的结果转换为对象、列表
  • 这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动
  • Django中的模型包含存储数据的字段和约束,对应着数据库中唯一的表

使用MySql数据库

  • 在虚拟环境中安装mysql包
pip install mysql-python
  • 在mysql中创建数据库
create databases test2 charset=utf8
  • 打开settings.py文件,修改DATABASES项
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'test2',
        'USER': '用户名',
        'PASSWORD': '密码',
        'HOST': '数据库服务器ip,本地可以使用localhost',
        'PORT': '端口,默认为3306',
    }
}

开发流程

  1. 在models.py中定义模型类,要求继承自models.Model
  2. 把应用加入settings.py文件的installed_app项
  3. 生成迁移文件
  4. 执行迁移生成表
  5. 使用模型类进行crud操作

使用数据库生成模型类

python manage.py inspectdb > booktest/models.py

定义模型

  • 在模型中定义属性,会生成表中的字段
  • django根据属性的类型确定以下信息:
    • 当前选择的数据库支持字段的类型
    • 渲染管理表单时使用的默认html控件
    • 在管理站点最低限度的验证
  • django会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后,则django不会再生成默认的主键列
  • 属性命名限制
    • 不能是python的保留关键字
    • 由于django的查询方式,不允许使用连续的下划线

定义属性

  • 定义属性时,需要字段类型
  • 字段类型被定义在django.db.models.fields目录下,为了方便使用,被导入到django.db.models中
  • 使用方式
    1. 导入from django.db import models
    2. 通过models.Field创建字段类型的对象,赋值给属性
  • 对于重要数据都做逻辑删除,不做物理删除,实现方法是定义isDelete属性,类型为BooleanField,默认值为False
字段类型
  • AutoField:一个根据实际ID自动增长的IntegerField,通常不指定
    • 如果不指定,一个主键字段将自动添加到模型中
  • BooleanField:true/false 字段,此字段的默认表单控制是CheckboxInput
  • NullBooleanField:支持null、true、false三种值
  • CharField(max_length=字符长度):字符串,默认的表单样式是 TextInput
  • TextField:大文本字段,一般超过4000使用,默认的表单控件是Textarea
  • IntegerField:整数
  • DecimalField(max_digits=None, decimal_places=None):使用python的Decimal实例表示的十进制浮点数
    • DecimalField.max_digits:位数总数
    • DecimalField.decimal_places:小数点后的数字位数
  • FloatField:用Python的float实例来表示的浮点数
  • 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:使用Python的datetime.datetime实例表示的日期和时间,参数同DateField
  • FileField:一个上传文件的字段
  • ImageField:继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image
字段选项
  • 通过字段选项,可以实现对字段的约束
  • 在字段对象时通过关键字参数指定
  • null:如果为True,Django 将空值以NULL 存储到数据库中,默认值是 False
  • blank:如果为True,则该字段允许为空白,默认值是 False
  • 对比:null是数据库范畴的概念,blank是表单验证证范畴的
  • db_column:字段的名称,如果未指定,则使用属性的名称
  • db_index:若值为 True, 则在表中会为此字段创建索引
  • default:默认值
  • primary_key:若为 True, 则该字段会成为模型的主键字段
  • unique:如果为 True, 这个字段在表中必须有唯一值
关系
  • 关系的类型包括
    • ForeignKey:一对多,将字段定义在多的端中
    • ManyToManyField:多对多,将字段定义在两端中
    • OneToOneField:一对一,将字段定义在任意一端中
  • 可以维护递归的关联关系,使用'self'指定,详见“自关联”
  • 用一访问多:对象.模型类小写_set
bookinfo.heroinfo_set
  • 用一访问一:对象.模型类小写
heroinfo.bookinfo
  • 访问id:对象.属性_id
heroinfo.book_id

元选项

  • 在模型类中定义类Meta,用于设置元信息
  • 元信息db_table:定义数据表名称,推荐使用小写字母,数据表的默认名称
<app_name>_<model_name>
  • ordering:对象的默认排序字段,获取对象的列表时使用,接收属性构成的列表
class BookInfo(models.Model):
    ...
    class Meta():
        ordering = ['id']
  • 字符串前加-表示倒序,不加-表示正序
class BookInfo(models.Model):
    ...
    class Meta():
        ordering = ['-id']
  • 排序会增加数据库的开销

示例演示

  • 创建test2项目,并创建booktest应用,使用mysql数据库
  • 定义图书模型
class BookInfo(models.Model):
    btitle = models.CharField(max_length=20)
    bpub_date = models.DateTimeField()
    bread = models.IntegerField(default=0)
    bcommet = models.IntegerField(default=0)
    isDelete = models.BooleanField(default=False)
  • 英雄模型
class HeroInfo(models.Model):
    hname = models.CharField(max_length=20)
    hgender = models.BooleanField(default=True)
    isDelete = models.BooleanField(default=False)
    hcontent = models.CharField(max_length=100)
    hbook = models.ForeignKey('BookInfo')
  • 定义index、detail视图
  • index.html、detail.html模板
  • 配置url,能够完成图书及英雄的展示

测试数据

  • 模型BookInfo的测试数据
insert into booktest_bookinfo(btitle,bpub_date,bread,bcommet,isDelete) values
('射雕英雄传','1980-5-1',12,34,0),
('天龙八部','1986-7-24',36,40,0),
('笑傲江湖','1995-12-24',20,80,0),
('雪山飞狐','1987-11-11',58,24,0)
  • 模型HeroInfo的测试数据
insert into booktest_heroinfo(hname,hgender,hbook_id,hcontent,isDelete) values
('郭靖',1,1,'降龙十八掌',0),
('黄蓉',0,1,'打狗棍法',0),
('黄药师',1,1,'弹指神通',0),
('欧阳锋',1,1,'蛤蟆功',0),
('梅超风',0,1,'九阴白骨爪',0),
('乔峰',1,2,'降龙十八掌',0),
('段誉',1,2,'六脉神剑',0),
('虚竹',1,2,'天山六阳掌',0),
('王语嫣',0,2,'神仙姐姐',0),
('令狐冲',1,3,'独孤九剑',0),
('任盈盈',0,3,'弹琴',0),
('岳不群',1,3,'华山剑法',0),
('东方不败',0,3,'葵花宝典',0),
('胡斐',1,4,'胡家刀法',0),
('苗若兰',0,4,'黄衣',0),
('程灵素',0,4,'医术',0),
('袁紫衣',0,4,'六合拳',0)

类的属性

  • objects:是Manager类型的对象,用于与数据库进行交互
  • 当定义模型类时没有指定管理器,则Django会为模型类提供一个名为objects的管理器
  • 支持明确指定模型类的管理器
class BookInfo(models.Model):
    ...
    books = models.Manager()
  • 当为模型类指定管理器后,django不再为模型类生成名为objects的默认管理器
管理器Manager
  • 管理器是Django的模型进行数据库的查询操作的接口,Django应用的每个模型都拥有至少一个管理器
  • 自定义管理器类主要用于两种情况
  • 情况一:向管理器类中添加额外的方法:见下面“创建对象”中的方式二
  • 情况二:修改管理器返回的原始查询集:重写get_queryset()方法
class BookInfoManager(models.Manager):
    def get_queryset(self):
        return super(BookInfoManager, self).get_queryset().filter(isDelete=False)
class BookInfo(models.Model):
    ...
    books = BookInfoManager()

创建对象

  • 当创建对象时,django不会对数据库进行读写操作
  • 调用save()方法才与数据库交互,将对象保存到数据库中
  • 使用关键字参数构造模型对象很麻烦,推荐使用下面的两种之式
  • 说明: _init _方法已经在基类models.Model中使用,在自定义模型中无法使用,
  • 方式一:在模型类中增加一个类方法
class BookInfo(models.Model):
    ...
    @classmethod
    def create(cls, title, pub_date):
        book = cls(btitle=title, bpub_date=pub_date)
        book.bread=0
        book.bcommet=0
        book.isDelete &#
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值