玩转Django2.0---Django笔记建站基础十一(一)

第十一章  音乐网站开发

  本章以音乐网站项目为例,介绍Django在实际项目开发中的应用,该网站共分为6个功能模块分别是:网站首页、歌曲排行榜、歌曲播放、歌曲点评、歌曲搜索和用户管理。

 

11.1  网站需求与设计

  当我们接到一个项目的时候,首先需要了解项目的具体需求,根据需求类型划分网站功能,并了解每个需求的业务流程。本节以音乐网站为例进行介绍,整个网站的功能分为:网站首页、歌曲排行榜、歌曲播放、歌曲搜索、歌曲点评和用户管理,各个功能说明如下:

    1、网站首页是整个网站的主界面,主要显示网站最新的动态信息以及网站的功能导航。网站动态信息以歌曲的动态为主,如热门下载、热门搜索和新歌推荐等;网站的功能导航时将其他页面的链接展示在首页上,方便用户访问浏览。

    2、歌曲排行榜是按照歌曲的播放量进行排序,用户还可以根据歌曲类型进行自定义筛选。

    3、歌曲播放是为用户提供在线试听功能,此外还提供歌曲下载、歌曲点评和相关歌曲推荐。

    4、歌曲点评是通过歌曲播放页面进入的,每条点评信息包含用户名、点评内容和点评时间。

    5、歌曲搜索是根据用户提供的关键字进行歌曲或歌手匹配查询的,搜索结果以数据列表显示在网页上。

    6、用户管理分为用户注册、登录和用户中心。用户中心包含用户信息、登录注销和歌曲播放记录。

  我们根据需求对网站的开发进行设计,首先由UI设计师根据网站需求实现网页设计图,然后由前端工程师根据网页设计图实现HTML静态页面,最后由后端工程师根据HTML静态页面实现数据库构建和网站后台开发。根据上述网站需求,一个哦你设计了6个网站页面,其中网站页面,气宗网站首页如图所示:

玩转Django2.0---Django笔记建站基础十一(一)_第1张图片

 

 网站首页

  从网站首页的设计图可以看到,按照网站功能可以分为7个功能区,说明如下:

    1、歌曲搜索:位于网页顶端,由文本输入框和搜索按钮组成,文本输入框下面是热门搜索的歌曲。

    2、轮播图:以歌曲的封面进行轮播,单击图片可进入歌曲播放。

    3、音乐分类:位于轮播图的左边,按照歌曲的类型进行分类。

    4、热门歌曲:位于轮播图的右边,按照歌曲的播放量进行排序。

    5、新歌推荐:按照歌曲的发行时间进行排序。

    6、热门搜索:按照歌曲的搜索量进行排序。

    7、热门下载:按照歌曲的下载量进行排序。

  歌曲排行榜页面如下图:

玩转Django2.0---Django笔记建站基础十一(一)_第2张图片

 

歌曲排行榜

  从歌曲排行榜的设计图可以看到,整个页面分为两部分:歌曲分类和歌曲列表,说明如下:

    1、歌曲分类:根据歌曲类型进行歌曲筛选,筛选后的歌曲显示在歌曲列表中。

    2、歌曲列表:歌曲信息以播放次数进行降序显示,若对歌曲进行类型筛选,则对同一类型的歌曲以播放次数进行降序显示。

  歌曲播放页面如下图:

玩转Django2.0---Django笔记建站基础十一(一)_第3张图片

 

歌曲播放

  从歌曲播放的设计图可以看到,整个页面共有4大功能:各个功能说明如下:

    1、歌曲信息:包括歌名、歌手、所属专辑、语种、流派、发行时间、歌词、歌曲封面和歌曲文件等。

    2、下载与歌曲点评:实现歌曲下载,每下载一次都会对歌曲的下载次数累加一次。单击"歌曲点评"可进入歌曲点评页面。

    3、播放列表:记录当前用户的试听记录,每播放一次都会对歌曲的播放次数累加一次。

    4、相关歌曲:根据当前歌曲的类型筛选出同一类型的其他歌曲信息。

  如下图:

玩转Django2.0---Django笔记建站基础十一(一)_第4张图片

 

 歌曲点评

  歌曲点评主要分为两部分:歌曲点评和点评信息列表,两者说明如下:

    1、歌曲点评:由文本输入框和发表按钮组成的表单,以POST的请求形式实现内容提交。

    2、点评信息列表:列出当前歌曲的点评信息,并对点评信息设置分页功能。

  歌曲搜索页面如下图:

玩转Django2.0---Django笔记建站基础十一(一)_第5张图片

歌曲搜索

  歌曲搜索主要根据文本框的内容对歌名或歌手进行匹配查询,然后将搜索结果返回到搜索页面上,其说明如下:

    1、若文本框的内容为空,则默认返回前50首最新发行的歌曲。

    2、若文本框的内容不为空,则从歌曲的歌名或歌手进行匹配查询,查询结果以歌曲的发现时间进行排序。

    3、每次搜索时,若文本框的内容与歌名完全相符,则相符的歌曲将其搜索次数累加一次。

  用户中心页面如下图:

玩转Django2.0---Django笔记建站基础十一(一)_第6张图片

 

用户中心

  用户中心需要用户登录后才能访问,该页面主要分为用户基本信息和歌曲播放记录,说明如下:

    1、用户基本信息:显示当前用户的用户头像和用户名,并设有用户退出登录链接。

    2、歌曲播放记录:播放记录来自于歌曲播放页面的播放列表,并对播放记录进行分页显示。

  用户注册和登录页面如下图:

玩转Django2.0---Django笔记建站基础十一(一)_第7张图片玩转Django2.0---Django笔记建站基础十一(一)_第8张图片

 

   用户的注册和登录是由同一个页面实现两个不同的功能,注册和登录都是通过JavaScript脚本来控制显示的,其说明如下:

    1、用户注册:填写用户名、手机号和用户密码,其中用户名和手机号码具有唯一性,而且不能为空。

    2、用户登录:根据用户注册时所填写的手机号码或用户名实现用户登录。

 11.2  数据库设计

  从网站的需求与网站设计可以得知,歌曲信息是整个网站最为核心的数据。因此,设置网站的数据结构时,应以歌曲信息为核心数据,逐步向外扩展相关联的数据信息。

  我们将歌曲信息的数据表名为song,歌曲信息不song的数据结构如表所示:

表字段 字段类型 含义
song_id Int类型,长度为11 主键
song_name Varchar类型,长度为50 歌曲名称
song_singer Varchar类型,长度为50 歌曲的演唱歌手
song_time Varchar类型,长度为10 歌曲的播放时长
song_album Varchar类型,长度为50 歌曲所属专辑
song_languages Varchar类型,长度为20 歌曲的语种
song_type Varchar类型,长度为20 歌曲的风格类型
song_release Varchar类型,长度为20 歌曲的发行时间
song_img Varchar类型,长度为20 歌曲封面图片路径
song_lyrics Varchar类型,长度为50 歌曲的歌词文件路径
song_file Varchar类型,长度为50 歌曲的文件路径
label_id Int类型,长度为11 外键,管理歌曲分类表

歌曲信息不song的数据结构

  从表可以看到,歌曲信息表song的字段以Varchar类型定义,数据表记录了歌曲的基本信息,如歌名、歌手、时长、所属专辑、语种、流派、发现世界、歌词、歌曲封面和歌曲文件,其中歌曲封面、歌词和歌曲文件是以路径的形式记录在数据库中的。一般来说,如果网站中涉及文件的使用,数据库最好记录文件的访问路径。若将文件的内容直接写入数据库中,则会对数据库造成一定的压力,从而降低网站的响应速度。

  在歌曲信息不song的字段label_id可以知道,歌曲信息不song关联歌曲分类表,我们将歌曲分类表命名为label,歌曲分类表主要实现网站首页的音乐分类,其数据结构如下表:

 

表字段 字段类型 含义
label_id Int类型,长度为11 主键
label_name Varchar类型,长度为10 歌曲的分类标签

歌曲分类表的数据结构

  在网站需求中,还会涉及歌曲动态信息,因此延伸出歌曲动态表。歌曲动态表用于记录歌曲的播放次数、搜索次数和下载次数,并且与歌曲信息表song实现一对一的数据关系,也就是一首歌曲只有一条动态信息。将歌曲动态表命名为dynamic,其数据结构如表:

表字段 字段类型 含义
dynamic_id Int类型,长度为11 主键
dynamic_ Int类型,长度为11 歌曲的播放次数
dynamic_ Int类型,长度为11 歌曲的搜索次数
dynamic_ Int类型,长度为11 歌曲的下载次数
song_id Int类型,长度为11 外键,关联歌曲信息表

歌曲动态表的数据结构

  最后还有与歌曲信息表song相互关联的歌曲点评表,该表主要用于歌曲点评页面。从歌曲点评页面可以知道,一首歌可以有多条点评信息,说明歌曲信息表song和歌曲点评表存在一对多的数据关系。将歌曲点评表命名为comment,其数据结构如下图:

表字段 字段类型 含义
comment_id Int类型,长度为11 主键
comment_ Varchar类型,长度为500 歌曲的点评内容
comment_ Varchar类型,长度为20 用户名
comment_ Varchar类型,长度为50 点评日期
song_id Int类型,长度为11 外键,管理歌曲信息表

歌曲点评表的数据结构

  除此之外,还有网站的用户管理功能,用户管理功能由用户表myuser提供用户信息。用户表myuser由Django内置模型User扩展而成,其数据结构如表所示:

表字段 字段类型 含义
Id Int类型,长度为11 主键
Password Varchar类型,长度为128 用户密码
last_login Datetime类型,长度为6 上次登录时间
is_superuser Tinyint类型,长度为1 超级用户
Username Varchar类型,长度为150 用户名
first_name Varchar类型,长度为30 用户的名字
last_name Varchar类型,长度为150 用户的姓氏
Email Varchar类型,长度为254 邮箱地址
is_staff Tinyint类型,长度为1 登录Admin权限
is_active Tinyint类型,长度为1 用户的激活状态
date_joined Datetime类型,长度为6 用户创建的时间
Qq Varchar类型,长度为 用户的QQ号码
weChat Varchar类型,长度为 用户的微信
Mobile Varchar类型,长度为11 用户的手机号码

 

 

11.3  项目创建与配置

  我们对音乐网站的需求与设计有了大概的了解,下一步将需求与设计落实到真正开发中。我们选择Python3.7+Django2.2+MySQL+PyCharm作为网站的开发工具,开发环境是Windows操作系统。

  首先在CMD窗口下创建Django项目,项目命名为music,然后在项目music中分别创建项目应用index、ranking、play、comment、search和user,创建指令如下:

创建music项目应用
(py3_3) E:\test5\music>python manage.py startapp index

(py3_3) E:\test5\music>python manage.py startapp ranking

(py3_3) E:\test5\music>python manage.py startapp play

(py3_3) E:\test5\music>python manage.py startapp comment

(py3_3) E:\test5\music>python manage.py startapp search

(py3_3) E:\test5\music>python manage.py startapp user

  完成项目和项目应用的创建后,我们在项目music的根目录下创建文件夹templates和static,两者分别存放模板文件和静态资源文件。然后在文件夹templates中放置公用模板title_base.html,而在文件夹static目录下创建文件夹css、js、font、image、songFile、songLyric和songImg以及防止图片favicon.ico,文件夹static的目录说明如下:

    1、css是存放全网站的CSS样式的文件。

    2、js是存放全网站的JS脚本的文件。

    3、font是存放网站字体的文件。

    4、image是存放网站页面的图片。

    5、songFile是存放歌曲的文件。

    6、songLyric是存放歌词的文件。

    7、favicon.ico是网站的LOGO图片。

  项目music的目录结构是根据网站的需求与设计进行搭建的,不同的需求与设计都会导致项目的目录结构有所不同。我们打开PyCharm查看项目music的目录结构,如下图:

玩转Django2.0---Django笔记建站基础十一(一)_第9张图片

 

项目目录结构

   项目目录结构搭建完成后,下一步是对项目进行相关的配置,配置信息主要在配置文件settings.py中完成。我们对项目music的属性INSTALLED_APPS、MIDDLEWARE、TEMPLATES和DATABASES进行相关配置,配置信息如下:

#添加新增的项目应用index、ranking、play、comment、search和user
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'index',
    'ranking',
    'user',
    'play',
    'search',
    'comment',
]

#添加中间件LocaleMiddleware
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    # 使用中文
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

#设置模板路径,在每个App中分别创建模板文件夹templates
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates'),
                  os.path.join(BASE_DIR, 'index/templates'),
                  os.path.join(BASE_DIR, 'ranking/templates'),
                  os.path.join(BASE_DIR, 'user/templates'),
                  os.path.join(BASE_DIR, 'play/templates'),
                  os.path.join(BASE_DIR, 'comment/templates'),
                  ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

设置数据库连接信息,项目使用的数据库为music_db
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'music_db',
        'USER':'root',
        'PASSWORD':'root',
        'HOST':'192.168.10.100',
        'PORT':'3306',
    }
}

  任何一个项目都需要对配置属性INSTALLED_APPS、MIDDLEWARE、TEMPLATES和DATABASES进行配置,这是一个项目的常规配置。完成项目配置后,我们接着对项目的URL进行配置。在项目的urls.py中分别对新建的App设置相应的URL地址,设置如下:

from django.contrib import admin
from django.urls import path, include

#配置URL地址信息
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('index.urls')),
    path('ranking.html', include('ranking.urls')),
    path('play/', include('play.urls')),
    path('comment/', include('comment.urls')),
    path('search/', include('search.urls')),
    path('user/', include('user.urls')),
]

  至此,音乐网站的开发环境基本上已搭建完毕。在整个项目搭建过程中,我们总结出Django开发环境的搭建流程,其说明如下:

    1、创建Django项目,可以在CMD窗口下输入创建指令或者在PyCharm下实现项目新建。

    2、创建项目的App应用,创建方式也是在CMD窗口或者PyCharm下实现。

    3、在项目的根目录下新建文件夹templates和static,分别存放模板文件和静态资源。

    4、设置项目的配置信息,由settings.py实现,常规的配置属性有INSTALLED_APPS、MIDDLEWARE、TEMPLATES和DATABASES。

    5、根据项目的App或项目的页面来设定网站的URL地址信息,由项目的urls.py实现。

 

11.4  网站首页

  网站首页是整个网站的主界面,从网站的需求设计来看,首页共实现7个功能:歌曲搜索、轮播图、音乐分类、热门歌曲、新歌推荐、热门搜索和热门下载。在项目music中,首页由项目应用index实现,我们在index中创建模板文件夹templates,在文件夹中放置模板文件index.html,如下图:

玩转Django2.0---Django笔记建站基础十一(一)_第10张图片

 

index目录架构

  首页的歌曲信息应该来自于数据库,除了Django内置的数据表之外,根据项目的数据库设计得知,网站一共定义了4张数据表,为了方便管理,我们将4张数据表所对应的模型都在index的models.py中进行定义,模型定义如下:

#index/models.py
from django.db import models

# 歌曲分类表label
class Label(models.Model):
    label_id = models.AutoField('序号', primary_key=True)
    label_name = models.CharField('分类标签', max_length=10)
    def __str__(self):
        return self.label_name
    class Meta:
        # 设置Admin界面的显示内容
        verbose_name = '歌曲分类'
        verbose_name_plural = '歌曲分类'

# 歌曲信息表song
class Song(models.Model):
    song_id = models.AutoField('序号', primary_key=True)
    song_name = models.CharField('歌名', max_length=50)
    song_singer = models.CharField('歌手', max_length=50)
    song_time = models.CharField('时长', max_length=10)
    song_album = models.CharField('专辑', max_length=50)
    song_languages = models.CharField('语种', max_length=20)
    song_type = models.CharField('类型', max_length=20)
    song_release = models.CharField('发行时间', max_length=20)
    song_img = models.CharField('歌曲图片', max_length=20)
    song_lyrics = models.CharField('歌词', max_length=50, default='暂无歌词')
    song_file = models.CharField('歌曲文件', max_length=50)
    label = models.ForeignKey(Label, on_delete=models.CASCADE,verbose_name='歌名分类')
    def __str__(self):
        return self.song_name
    class Meta:
        # 设置Admin界面的显示内容
        verbose_name = '歌曲信息'
        verbose_name_plural = '歌曲信息'

# 歌曲动态表dynamic
class Dynamic(models.Model):
    dynamic_id = models.AutoField('序号', primary_key=True)
    song = models.ForeignKey(Song, on_delete=models.CASCADE, verbose_name='歌名')
    dynamic_plays = models.IntegerField('播放次数')
    dynamic_search = models.IntegerField('搜索次数')
    dynamic_down = models.IntegerField('下载次数')
    class Meta:
        # 设置Admin界面的显示内容
        verbose_name = '歌曲动态'
        verbose_name_plural = '歌曲动态'

# 歌曲点评表comment
class Comment(models.Model):
    comment_id = models.AutoField('序号', primary_key=True)
    comment_text = models.CharField('内容', max_length=500)
    comment_user = models.CharField('用户', max_length=20)
    song = models.ForeignKey(Song, on_delete=models.CASCADE,verbose_name='歌名')
    comment_date = models.CharField('日期', max_length=50)
    class Meta:
        # 设置Admin界面的显示内容
        verbose_name = '歌曲评论'
        verbose_name_plural = '歌曲评论'
index/models.py

  上述代码定义了模型Label、Song、Dynamic和Comment,分别对应歌曲分类表label、歌曲信息表song、歌曲动态表dynamic和歌曲点评表comment。我们根据模型的定义在项目的数据库中创建相应的数据表,在PyCharm的Terminal模式下输入数据迁移指令:

(py3_3) E:\test4\music>python manage.py makemigration

#创建数据表
(py3_3) E:\test4\music>python manage.py migrate

  我们打开数据库music_db可以看到项目所有已定义的模型都能转换成相应的数据表,在数据表index_label、index_song和index_dynamic中分别添加网站开发所需的数据信息,如下图:

玩转Django2.0---Django笔记建站基础十一(一)_第11张图片玩转Django2.0---Django笔记建站基础十一(一)_第12张图片

 

   数据表index_label(左)                                                                                                                     数据表index_dynamic(右)

 玩转Django2.0---Django笔记建站基础十一(一)_第13张图片

 

 数据表index_song

  值得注意的是,数据表index_song的字段song_img、song_lyrics和song_file的数据分别代表静态文件夹songImg、songLyric和songFile里面的数据名。在实际的开发中,文件的存储都是采用文件服务器存放的,比如阿里云的云存储OSS和腾讯云的对象存储COS等。

  至此,网站的数据模型和数据表的数据已经部署完毕,下一步是实现网站首页的开发。网站首页主要有index的路由配置urls.py、视图views.py和模板index.html共同实现,代码如下:

#index/urls.py
from django.urls import path
from . import views
# 设置首页的URL地址信息
urlpatterns = [
    path('', views.indexView, name='index'),
]

#index/views.py
from django.shortcuts import render
from .models import *

def indexView(request):
    # 热搜歌曲
    search_song = Dynamic.objects.select_related('song').order_by('-dynamic_search').all()[:8]
    # 音乐分类
    label_list = Label.objects.all()
    # 热门歌曲
    play_hot_song = Dynamic.objects.select_related('song').order_by('-dynamic_plays').all()[:10]
    # 新歌推荐
    daily_recommendation = Song.objects.order_by('-song_release').all()[:3]
    # 热门搜索、热门下载
    search_ranking = search_song[:6]
    down_ranking = Dynamic.objects.select_related('song').order_by('-dynamic_down').all()[:6]
    all_ranking = [search_ranking, down_ranking]
    return render(request, 'index.html',locals())

  上述代码将首页的响应处理交给视图函数indexViews执行,并且将首页的URL命名为index,URL的命名可以在模板上使用Django内置的url标签生成相应的URL地址。视图函数indexViews一共执行了5此数据查询,其说明如下:

    1、search_song:通过歌曲的搜索次数进行降序查询,由Django内置的select_related方法实现模型Song和Dynamic的数据查询。

    2、label_list:查询模型Label的全部数据,数据显示在首页轮播图左侧的音乐分类中。

    3、play_host_song:由select_related方法实现模型Song和Dynamic的数据查询,查询结果以歌曲的播放次数进行降序排列,数据显示在首页轮播图右侧的热门歌曲中。

    4、daily_recommendation:以歌曲发行时间的先后顺序查询前三首歌曲的信息,数据显示在首页的新歌推荐中。

    5、all_ranking:由热门搜索和热门下载组成的列表。热门搜索的数据来自于search_song:热门下载用于获取下载次数排在前6行的歌曲信息。

  最后在模板index.html中编写模板语法,将视图函数indexViews查询所得的数据对象通过遍历的方式呈现在网页上。由于模板index.html的代码较多,此处只列出首页的功能代码,完整的模板代码可在下载资源中查看。模板index.html代码如下:

#模板index.html的功能代码
#首页的搜索框,由HTML表单实现,{%  url 'search' XXX  %}是搜索页面的地址链接
"searchForm" action="{% url 'search' 1 %}" method="post" target="_blank"> {% csrf_token %}
class="search-keyword"> "kword" type="text" class="keyword" maxlength="120" placeholder="音乐节" />
"subSerch" type="submit" class="search-button" value="搜 索" />
#搜索框下面的热门搜索歌曲,{% url 'play' XXX %}是播放页面的地址链接
"suggest" class="search-suggest">
class="search-hot-words"> {% for song in search_song %} "play" href="{% url 'play' song.song.song_id %}" >{{ song.song.song_name }} {% endfor %}
#网站导航栏 #音乐分类,位于轮播图的左侧
class="category-nav-body">
"J_CategoryItems" class="category-items"> {% for label in label_list %}
class="item" data-index="1">

"javascript:;">{{ label.label_name }}

{% endfor %}
#轮播图,{% url 'play' 12 %}是播放页面的地址链接
"J_FocusSlider" class="focus">
"bannerLeftBtn" class="banner_btn">
"bannerRightBtn" class="banner_btn">
#热门歌曲,位于轮播图的右侧。{{ forloop.counter }}用于显示当前循环次数
class="aside">

热门歌曲

#新歌推荐
"J_TodayRec" class="today-list">
#热门搜索和热门下载
"J_Tab_Con" class="tab-container-cell"> {% for list in all_ranking %} {% if forloop.first %}

  从模板的功能代码可以看到,每个功能都是通过遍历的方式将视图函数传递的变量进行输出,还有部分功能在数据列举的过程中,通过判断当前循环次数来控制HTML标签的样式。为了检验首页是否正常运行,启动music项目,在浏览器上访问

 玩转Django2.0---Django笔记建站基础十一(一)_第14张图片

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/zhaop8078/p/11616479.html

你可能感兴趣的:(玩转Django2.0---Django笔记建站基础十一(一))