三小时带你入门Django框架笔记

课程地址:
慕课网免费视频三小时带你入门Django框架

一、环境搭建

1.1 环境准备

  1. python环境安装:

使用python版本:3.5+

  • 方案1:原生python环境
  • 方案2:科学结算Anaconda Python环境(推荐)
    减少Python第三方库的困扰,全身心投入到业务开发当中
  1. IDE工具安装:
  • pycharm

说明:该文章基于mac系统,windows和linux类似

1.2 安装andconda

  1. 到官网下载Andconda
image.png
image.png
  1. 添加anaconda环境变量到zsh
1. vim .zshrc
2. add system path
# andconda
export PATH=/opt/anaconda3/bin:$PATH
3. source .zshrc
  1. 终端输入 conda,显示以下界面说明配置成功
image.png
image.png

2.3 安装django 2.0

  1. 命令行安装(使用豆瓣源,下载更快)
pip install -i https://pypi.douban.com/simple/ django==2.0
  1. 终端输入django-admin,显示以下界面说明安装成功
image.png

2.4. pycharm安装

访问官网pycharm进行下载,点击安装即可

二、Django项目初体验

2.1 初识Django项目

2.1.1 Django的基本命令

  • startproject 创建一个Django项目
  • startapp 创建一个Django应用
  • check 检查项目完整性
  • runserver 本地简易运行Django项目
  • shell 进入Django项目的Python Shell环境
  • test 执行Django测试用例

2.1.2 Django的基本指令(数据库相关)

  • makemigrations 创建模型变更的迁移文件,生成数据库DDL语句
  • migrate 执行上一个命令创建的迁移文件,执行DDL语句
  • dumpdata 把数据库数据导出到文件
  • loaddata 把文件数据导入到数据库

2.1.3 创建一个项目

  1. 创建一个项目
cd code/python # 1. 自己创建的python项目目录
django-admin startproject django_introduction # 2. 创建Django项目指令
  1. 添加代码到gitee仓库
  2. 使用pycharm打开django_introduction目录
image.png
image.png
  1. 配置django_introduction的python环境
image.png
image.png

2.2 初识Django应用

2.2.1 Django应用 VS Django项目

  1. 一个Django项目就是一个基于Django的Web应用
  2. 一个Django应用就是一个可重用的Python软件包
  3. 每个应用可以自己管理模型、视图、模板、路由和静态文件等
  4. 一个Djagon项目包含一组配置和若干个Django应用
image.png
image.png

2.2.2 Django应用目录介绍

  1. 使用pycharm安装django

问题:conda命令行进入安装的django不在该环境
解决:临时使用pycharm安装


image.png
  1. 创建应用blog,打开terminal,输入 python manage.py startapp blog
image.png
image.png
  1. 查看blog目录
image.png
image.png

2.3. Django HelloWorld

2.3.1 Django视图(What、Why&How)

  1. 没有框架的时代:hello.html
  2. 不可能通过HTML表达网页所有的内容
  3. Django视图产生内容

2.3.2 Django路由(What、What&How)

  1. runserver 可以看到Django欢迎页面
  2. 请求没办法到达刚才的视图函数
  3. 需要配置路由,绑定视图函数和URL

2.3.3 代码编写

  1. 应用编辑视图blog/views.py
from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.

def hello_world(request):
    return HttpResponse("Hello World")
  1. 应用编辑路由blog/urls.py
from django.urls import path

import blog.views

urlpatterns = [
    path("hello_world", blog.views.hello_world)
]
  1. 项目编辑路由django_introduction/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls')) # add this line
]
  1. 项目安装应用django_introduction/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # myapp blog
    'blog.apps.BlogConfig' # add this line
]
  1. 点击IDE的运行按钮
  2. 访问http://127.0.0.1:8000/blog/hello_world
image.png
image.png
  1. 整个访问流程图如下
image.png
image.png

三、Django模型层

3.1 模型层简介

3.1.1 模型层是什么

  1. 位于Django视图层和数据库之间
  2. Python对象和数据库表之间转换
image.png
image.png

3.1.2 为什么需要模型层

  1. 屏蔽不同数据库之间的差异
  2. 开发者更加专注于业务逻辑的开发
  3. 提供很多便捷工具有助开发
image.png
image.png

3.1.3 模型层的相关配置

数据库默认配置在项目settings.py文件,sqlite3数据库


image.png

3.2 创建博客文章模型

3.2.1 设计博客模型

  • 文章标题 文本类型
  • 文章摘要 文本类型
  • 文章内容 文本类型
  • 唯一ID标记 Int数字类型(自增、主键)
  • 发布日期 日期类型

3.2.2 模型层定义字段

  1. 定义类型
  • 数字类型 IntegerField
  • 文本类型 TextField
  • 日期类型 DateTimeField
  • 自增ID AutoField
  • 主键定义 primary_key属性
  1. 应用创建model blog/models.py
class Article(models.Model):
    # 文章唯一ID
    article_id = models.AutoField(primary_key=True)
    # 文章标题(注意TextFiled有括号)
    title = models.TextField()
    # 文章摘要
    brief_content = models.TextField()
    # 文章内容
    content = models.TextField()
    # 文章发布时间
    publish_date = models.DateTimeField(auto_now=True)
  1. 终端运行指令创建Article model

image.png

说明:
makemigrations生成ddl(数据库模式定义语言)
migrate真正地去执行ddl

3.3 初识Django Shell

3.3.1 Django Shell是什么

  • Python Shell,用于交互式的Python编程
  • Django Shell也类似,集成Django项目环境

3.3.2 为什么需要Django Shell

  • 临时性操作使用Django Shell更加方便
  • 小范围Debug更简单,不需要运行整个项目来测试

方便开发、方便测试、方便Debug

3.3.3 Django Shell的使用

实例:创建一遍文章


image.png
image.png

3.4. 初识Django Admin模块

4.1 Django Admin模块是什么

  • Django的后台管理工具
  • 读取定义的模型元数据,提供强大的管理使用页面

4.2 为什么需要Django Admin模块

  • Django Shell新增文章太复杂了
  • 管理页面是基础设施中重要的部分
  • 认证用户、显示管理模型、校验输入等功能类似

4.3 Django Admin模块的使用

  1. 创建管理员用户
image.png
  1. 登录页面进行管理
image.png
image.png
  • 可以发现没有我们自定义的Article -> 应用admin.py注册Article
from django.contrib import admin

# Register your models here.
from .models import Article

admin.site.register(Article)
image.png
image.png
  • 发现Article显示的标题不友好“Article object”,应用models.py 新增str方法,重启服务器
image.png
image.png

image.png
image.png

3.5 实现博客数据返回页面

5.1 blog/views.py添加响应

from blog.models import Article
def article_content(request):
    article = Article.objects.all()[0]
    title = article.title
    brief_content = article.brief_content
    content = article.content
    article_id = article.article_id
    publish_date = article.publish_date
    return_str = 'title:%s,brief_content:%s,content:%s,article_id:%s,publish_date:%s' % (
        title, brief_content, content, article_id, publish_date)
    return HttpResponse(return_str)

5.2 blog/urls.py配置路由

urlpatterns = [
    path("hello_world", blog.views.hello_world),
    path("content", blog.views.article_content) // add this line
]

访问内容地址:http://127.0.0.1:8000/blog/content

image.png
image.png

四、Django视图与模板

4.1 使用Bootstrap实现静态博客页面

4.1.1 页面布局设计

  1. 博客首页
image.png
image.png

image.png
image.png
  1. 文章详情页
image.png
image.png

4.1.2 Bootstrap以及Bootstrap的栅格系统

4.1.3 实现静态页面

  1. 文章标题 blog新建templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>三小时入门Django Web框架</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
            integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
            crossorigin="anonymous"></script>
</head>
<body>
<div class="container page-header">
    <h1>三小时入门Django Web框架
        <small>-by ybxiang</small></h1>
</div>
<div class="container page-body">
    <div class="col-md-9" role="main">
        <div class="body-main">
            <div>
                <h2>文章标题1</h2>
                <p>
                    目标是设定一个定性的时间内目标(通常是一个季度)。关键的结果是由量化指标形式呈现的,用来衡量在这段时间结束时是否达到了目标。 [6]
                    在全面展开工作时,OKR就存在于公司(顶级愿景)、团队(被继承并由团队生成,而不仅仅是个人目标的一部分)和个人层面(个人发展和个人贡献)上了。
                    大多数目标通常是由管理层定义的,但有些目标是自下而上的,而不是为了增加团队的积极性。 [7]
                    公司发布的OKR演示文稿或包含问答的陈述、报告,可以确保在最终完成之前对依赖关系进行跨功能的对齐和协议。
                    在目标时期结束时,要特别注意对每个目标的每个关键结果进行评估。不同的人对有目标的期望是不同的。谷歌和Uber建议每个季度员工应该实现约70%的“OKR”,这是每个季度的关键业绩数据,而Zynga则希望员工每季度能实现2至3个“OKR”。
                    [8]
                </p>
            </div>
        </div>
    </div>
    <div class="col-md-3" role="complementary">
        <div>
            <h2>最新文章</h2>
            <h4><a href="#">最新文章1</a></h4>
            <h4><a href="#">最新文章2</a></h4>
            <h4><a href="#">最新文章3</a></h4>
            <h4><a href="#">最新文章4</a></h4>
            <h4><a href="#">最新文章5</a></h4>
            <h4><a href="#">最新文章6</a></h4>
            <h4><a href="#">最新文章7</a></h4>
            <h4><a href="#">最新文章8</a></h4>
            <h4><a href="#">最新文章9</a></h4>
        </div>
    </div>
</div>
</body>
</html>
  • 浏览器打开html预览效果
image.png
image.png
  1. 文章详情 blog新建templates/detail.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>三小时入门Django Web框架</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
            integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
            crossorigin="anonymous"></script>
</head>
<body>
<div class="container page-header">
    <h1>文章标题1</h1>
</div>
<div class="container body-main">
    <p>
        目标是设定一个定性的时间内目标(通常是一个季度)。关键的结果是由量化指标形式呈现的,用来衡量在这段时间结束时是否达到了目标。 [6]
        在全面展开工作时,OKR就存在于公司(顶级愿景)、团队(被继承并由团队生成,而不仅仅是个人目标的一部分)和个人层面(个人发展和个人贡献)上了。
        大多数目标通常是由管理层定义的,但有些目标是自下而上的,而不是为了增加团队的积极性。 [7]
        公司发布的OKR演示文稿或包含问答的陈述、报告,可以确保在最终完成之前对依赖关系进行跨功能的对齐和协议。
        在目标时期结束时,要特别注意对每个目标的每个关键结果进行评估。不同的人对有目标的期望是不同的。谷歌和Uber建议每个季度员工应该实现约70%的“OKR”,这是每个季度的关键业绩数据,而Zynga则希望员工每季度能实现2至3个“OKR”。
        [8]
    </p>
</div>
</div>
</body>
</body>
</html>
image.png
image.png

4.2 初识Django的模板系统

4.2.1 模板系统简介

  1. 视图文件不适合编码HTML
def current_datetime(request):
        now = datetime.datetime.now()
        html = "<html><body>It is now %s.</body></html>" % now
        return HttpResponse(html)
  1. 页面设计改变需要修改Python代码
  2. 网页逻辑和网页视图应该分开设计
  3. 模板系统的表现形式是文本
  4. 分离文档的表现形式和变现内容
  5. 模板系统定义了特有的标签占位符

4.2.2 基本语法

  • 变量标签:{{ 变量 }}
<html><body>{{ now }}</body></html>
  • for循环标签:{% for x in list %}, {% endfor%}
<ul>
    {% for item in list %}
    <li>{{ item }}</li>
  {% endfor %}
</ul>
  • if-else分支标签:{% if %},{% else %},{% endif %}
{% if true %}
    <p>it is a true part.</p>
{% else %}
    <p>it is a false part.</p>
{% endif %}

4.3 使用模板系统渲染博客页面

4.3.1 博客首页

  1. index.html移动到blog/templates/blog/index.html,读取内容
<div class="container page-body">
    <div class="col-md-9" role="main">
        <div class="body-main">
            {% for article in article_list %}
                <div>
                    <h2>{{ article.title }}</h2>
                    <p>
                        {{ article.brief_content }}
                    </p>
                </div>
            {% endfor %}
        </div>
    </div>
    <div class="col-md-3" role="complementary">
        <div>
            <h2>最新文章</h2>
            {% for article in article_list %}
                <h4><a href="#">{{ article.title }}</a></h4>
            {% endfor %}
        </div>
    </div>
</div>
  1. views.py放内容

def get_index_page(request):
    all_article = Article.objects.all()
    return render(request, 'blog/index.html', {
        'article_list': all_article
    })

  1. urls.py配置路由
path("index", blog.views.get_index_page)
  1. 访问http://127.0.0.1:8000/blog/index

4.3.2 文章详情页

  1. detail.html移动到blog/templates/blog/deatail.html,读取内容
<body>
    <div class="container page-header">
        <h1>{{ curr_article.title }}</h1>
    </div>
    <div class="container body-main">
        <p>
            {% for section in section_list %}
                <p>{{ section }}</p>
            {% endfor %}
        </p>
    </div>
</body>
  1. views.py放内容
def get_detail_page(request):
    curr_article = Article.objects.all()[0]
    section_list = curr_article.content.split('\n')
    return render(request, 'blog/detail.html', {
        'curr_article': curr_article,
        'section_list': section_list
    })
  1. urls.py配置路由
path("detail", blog.views.get_detail_page)
  1. 访问http://127.0.0.1:8000/blog/detail

4.4 实现文章详情页面跳转

当前问题:

  • 不支持博客首页到文章详情页的跳转
  • 只能打开某一遍文章的详情页

当前方案:

  • 设计文章详情页URL -> 完善视图函数逻辑 -> 实现首页跳转

4.4.1 设计文章详情页URL

/blog/detail => 不能指定某一篇博客

  • /blog/detail/1 => 博客唯一ID为1的文章
  • /blog/detail/2 => 博客唯一ID未2的文章

4.4.2 完善视图函数逻辑

URL路径参数的获取和传递

  1. urls.py 配置路由
path("detail/<int:article_id>", blog.views.get_detail_page)
  1. views.py 设置数据
def get_detail_page(request, article_id):
    all_article = Article.objects.all()
    curr_article = None
    for article in all_article:
        if article.article_id == article_id:
            curr_article = article
            break
    section_list = curr_article.content.split('\n')
    return render(request, 'blog/detail.html', {
        'curr_article': curr_article,
        'section_list': section_list
    })
  1. index.html 修改跳转逻辑
image.png
image.png
  1. 访问http://127.0.0.1:8000/blog/index 点击文章标题,跳转到文章详情页

4.5 实现上下篇文章跳转

image.png
image.png

4.5.1 代码实现

  1. 找到翻页组件https://v3.bootcss.com/components/
image.png
image.png
  1. detail.html新增上下页组件
<body>
    <div class="container page-header">
        <h1>{{ curr_article.title }}</h1>
    </div>
    <div class="container body-main">
        <p>
            {% for section in section_list %}
                <p>{{ section }}</p>
            {% endfor %}
        </p>
    </div>
    <div>
        <nav aria-label="...">
          <ul class="pager">
            <li><a href="/blog/detail/{{ previous_article.article_id }}">上一篇:{{ previous_article.title }}</a></li>
            <li><a href="/blog/detail/{{ next_article.article_id }}">下一篇:{{ next_article.title }}</a></li>
          </ul>
        </nav>
    </div>
</body>
  1. views.py设置上下页数据
def get_detail_page(request, article_id):
    all_article = Article.objects.all()
    curr_article = None
    previous_article = None
    next_article = None
    for index, article in enumerate(all_article):
        if article.article_id == article_id:
            curr_article = article
            if index >= 1:
                previous_index = index - 1
            else:
                previous_index = 0
            if index < len(all_article) - 1:
                next_index = index + 1
            else:
                next_index = index
            previous_article = all_article[previous_index]
            next_article = all_article[next_index]
            break
    section_list = curr_article.content.split('\n')
    return render(request, 'blog/detail.html', {
        'curr_article': curr_article,
        'section_list': section_list,
        'previous_article': previous_article,
        'next_article': next_article
    })

4.6 实现分页功能

image.png
image.png

4.6.1 实现分页功能流程

  • Bootstrap实现分页按钮 -> 设计分页URL -> 使用Django分页组件实现分页功能

4.6.2 index.html 拷贝分页组件

image.png

4.6.3实现分页标识设计

  • /blog/detail/1 => 博客唯一ID为1的文章
  • /blog/index?page = 1 => 分页为1的首页

4.6.4 views.py设置分页数据

  1. 使用python shell进行分页功能测试
image.png
image.png
  1. 登录admin管理后台添加几条article,方便测试分页
image.png
image.png
  1. index.html设置UI
image.png
  1. views.py设置数据(倒叙字段签名加【-】)
image.png
image.png
  1. 访问http://localhost:8000/blog/index
image.png
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容