Django建站笔记 - yunfanfan/Notes GitHub Wiki

网站需求概述

拟开发一个科技型企业门户网站,企业名称为:恒达科技,具体包括:首页、公司简介、新闻动态、服务支持、产品中心、科研基地、人才招聘共7个模块,每个模块可能包含两至三个子模块用于进一步细分功能。各模块及其子模块结构如下图所示:

FN2GKw

下面对每个模块需求和功能进行简要介绍:

  1. 科研基地:该模块主要用于展示企业科研基地相关内容,包括科研基地的文字描述和图片等,该模块功能较为单一,仅包含一个页面,并以静态页面形式提供访问和浏览;
  2. 公司简介:包含两个子模块,分别是企业概况和荣誉资质。
    1. 企业概况用于对企业进行简短的展示,包括说明文字和图片,用以展示企业的历史、核心产品、经营理念等。
    2. 荣誉资质子模块主要以展报形式罗列企业历年来获得的荣誉,该模块随着企业发展,需要动态的增加相关内容。因此,为了方便管理员后期编辑网站内容,需要将该页面内容与数据库进行绑定,后期可以动态的添加荣誉信息;
  3. 产品中心:包含三个子模块,分别是机器人、智能监控和人脸识别,对应企业的三大主流产品。用户浏览产品时通过各个子模块链接切换可以按类别对产品进行浏览。因此,产品中心模块实现时需要能够从后台数据库按类型获取数据并进行页面渲染;
  4. 新闻动态:新闻动态模块包含三个子模块,分别是公司要闻、行业新闻和通知公告。与产品中心模块类似,用户可以通过各个子模块链接按新闻类型切换到指定子模块进行浏览。新闻内容以图文形式进行展现,并且管理员可以自定义图片和文字的格式;
  5. 人才招聘:该模块包含两个子模块,分别是欢迎咨询和加入恒达。
    1. 欢迎咨询子模块主要用于展示企业联系人信息以及企业地理位置,需要在实现时嵌入百度地图以方便浏览者查找位置。
    2. 加入恒达子模块用来为企业招聘提供一个互动渠道,招聘员在网站上发布招聘职位并显示在该子模块页面上,应聘者浏览该页面并通过该页面上的表单提交个人信息;
  6. 服务支持:该模块包含两个子模块,分别是资料下载和开放平台。
    1. 资料下载子模块用于为用户提供资料下载链接,用户通过这些链接可以下载该企业的相关产品数据,包括驱动、说明文档、SDK开发包等。
    2. 开放平台模块作为一个展示企业科技产品的模块,可以提供在线的人工智能算法支持,以API接口方式让用户体验产品;
  7. 首页:该模块作为一个企业门户网站的入口模块具有非常重要的作用,需要能够全方位的展示企业各版块功能,同时需要兼具美观、清晰的特性。另外,作为一个集成模块,首页需要调用其它模块的相关数据信息,并能够对数据进行过滤和排序;

搭建项目框架

文件结构设计

在终端中通过cd命令切换到希望创建项目的目录位置,然后输入下述命令创建一个名为hengDaProject的Django项目:

django-admin startproject hengDaProject

Django提供了一种多应用机制,即一个Django项目可以包含多个应用,每个应用可以实现一定的功能,或者每个应用对应部分访问内容。

针对“恒达科技”这个门户网站需求可以发现,每个页面下基本都有2~3个二级子页面,比如“公司简介”下有“企业概况”和“荣誉资质”两个子页面,“产品中心”下有“家用机器人”、“智能监控”和“人脸识别”三个子页面。

在这种情况下,为了清晰的表述项目结构,一种便捷有效的结构设计方法即将每一个一级页面看作一个功能应用,具体的可以分为:“首页”、“公司简介”、“新闻动态”、“产品中心”、“服务支持”、“科研基地”、“人才招聘”共七个应用,这样每个应用下都只需要开发2~3个相似的子页面即可。采用这种方式的好处在于:后期开发其它类似的项目可以重复利用这些功能模块,只需要在项目中简单的配置即可。

接下来,按照上述结构思路为每个页面建立应用。 打开VS Code,打开刚才创建的hengDaProject目录下面,然后在VS Code中打开终端。

接下来以“首页”模块为例,在终端中输入下述命令创建一个名为homeApp的应用:

python manage.py startapp homeApp

接下来按照同样方法创建其它模块对应的应用,依次输入命令:

python manage.py startapp aboutApp
python manage.py startapp newsApp
python manage.py startapp productsApp
python manage.py startapp serviceApp
python manage.py startapp scienceApp
python manage.py startapp contactApp

结构图如下:

IsbPCT

在项目根目录下创建templates文件夹(用于存放各个应用共享的模板文件,此处一般指用于共享和继承的html模板文件)

通常门户网站各个功能页面具有统一的风格,即网页头部、导航栏、尾部等内容一般是相同的,因此可以将这些相同的内容编辑成模板文件,其它功能页面在开发的过程中可以继承该模板文件,然后通过少量代码的修改即可实现页面的复用,这种方式可以极大的提高开发效率。

为了能够使得多个应用共享静态资源文件,在项目根目录下创建static文件夹,在该文件夹中分别建立css、fonts、img、js这四个子文件夹,分别用来存储项目共享的样式文件、字体库文件、图片文件和JavaScript代码文件。由于本书采用的是Bootstrap前端框架,因此按照前面介绍的方法,将Bootstrap对应的配置文件分别导入到各个对应的项目文件夹中。

在css文件夹中额外添加一个自定义的style.css文件,该文件并不是Bootstrap提供的文件,而是本项目为了定制化HTML样式单独建立的css文件。尽管可以采用Bootstrap框架完成页面的布局,但是依然有很多组件需要细微的调整,此时就需要通过在style.css文件中编写代码覆盖Bootstrap的基础样式来实现。

多级路由配置和访问

理论

在urls.py文件中通过path函数将路由和视图处理函数进行绑定,使得访问时能够正常解析路由并使用绑定的视图函数进行处理,基本形式如下:path('home/', home, name= 'home'),

  1. 第一个参数是相对访问路由,如果项目部署在本地8000端口时,此时对应的访问网址为http://127.0.0.1:8000/home
  2. 第二个参数即指定绑定的视图函数
  3. 第三个参数用于在模板中进行逆向解析

当项目规模较大、具有较多的路由时,一种比较好的解决方案就是将与各个应用相关的路由放置在各个应用文件夹下,每个应用单独管理一个urls.py文件。例如,“公司简介”模块下有一个“企业概况”页面,如果按照单层路由进行设计,其对应的路由形式为:path('survey/', survey, name= 'survey')

如果希望将上述路由置于aboutApp应用下面,那么就需要定义二级路由。一级路由指定路由所在的应用app,在项目根路由文件urls.py中进行申明,形式如下:path('aboutApp/', include('aboutApp.urls'))

  1. path函数第一个参数用来匹配应用对应的前缀,即如果想要访问aboutApp应用下的路由,在根网址后都必须加上aboutApp前缀。
  2. path第二个参数用来接收由include指定的二级路由对应的路由文件。

二级路由可以在应用中创建一个urls.py文件,然后将二级路由与视图函数进行绑定即可。下面以“首页”homeApp和“公司简介”aboutApp两个应用为例,具体阐述如何配置多级路由并且实现访问。

实操

现在将前面创建的7个应用加入到项目中,以homeApp和aboutApp为例。

  1. 打开hengDaProject文件夹下的settings.py文件,找到INSTALLED_APPS字段,在该字段末尾添加应用:

    INSTALLED_APPS = [
    ...其它应用...
        'homeApp',     # 添加"首页"应用
        'aboutApp',    # 添加"公司简介"应用
    ]
  2. 接下来需要实现每个应用对应的页面访问。编辑homeApp文件夹中的views.py文件,代码如下:

    from django.shortcuts import render
    from django.shortcuts import HttpResponse
     
    def home(request):
        html = '<html><body>首页</body></html>' 
        return HttpResponse(html)
      # HttpResponse函数用来直接通过代码生成页面内容并返回给前端浏览器渲染
  3. 配置“首页”路由,虽然本项目中首页是一个独立的应用,但是首页的路由比较特殊,一般来说网站的跟访问路径对应网站首页(类似访问http://127.0.0.1:8000/即可浏览首页)。

    因此,只需要在项目的urls.py文件中(hengDaProject/urls.py)找到urlpatterns字段然后添加首页路由即可,代码如下:

    from django.contrib import admin
    from django.urls import path
    from homeApp.views import home # 导入首页对应的视图处理函数
     
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', home, name='home'),  # 添加“首页”应用
    ]
  4. 配置均属于“公司简介”应用模块的“企业概况”和“荣誉资质”页面对应的二级路由。将这两个页面的路由放置在aboutApp下单独进行管理。

    1. 首先在项目根路由文件urls.pyurlpatterns字段中添加aboutApp应用对应的一级路由:(注意在头部要引入include函数)
    # ···
    from django.conf.urls import include # 导入include函数
     
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', home, name='home'),                # 添加“首页”应用
        path('aboutApp/', include('aboutApp.urls')) # 添加公司简介路由
    ]
    1. 接下来在应用aboutApp中添加urls.py文件,然后编辑代码如下:

      from django.urls import path
      from . import views
       
      app_name = 'aboutApp'  # 设置应用名
       
      urlpatterns = [
          path('survey/', views.survey, name='survey'),   # 企业概况
          path('honor/', views.honor, name='honor'),      # 荣誉资质
      ]

      最后,为了能够访问网页内容,同样将页面文字以硬编码方式嵌入到Python字符串中并通过HttpResponse函数返回给浏览器。

      编辑aboutApp应用下的views.py文件,添加代码如下:

      from django.shortcuts import render
      from django.shortcuts import HttpResponse
       
      def survey(request):
          html = '<html><body>企业概况</body></html>'
          return HttpResponse(html)
       
      def honor(request):
          html = '<html><body>荣誉资质</body></html>'
          return HttpResponse(html)
  5. 为了方便后期部署和访问,需要开放访问权限。编辑hengDaProject文件夹下的settings.py文件,修改ALLOWED_HOSTS字段如下:

    ALLOWED_HOSTS = ['*',]
  6. 添加上述代码后,运行项目:

    python manage.py runserver

然后使用浏览器访问http://127.0.0.1:8000即可查看首页内容(出现“首页”字符串),如果想要访问“企业概况”和“荣誉资质”页面,可以通过浏览器分别访问:http://127.0.0.1:8000/aboutApp/survey和http://127.0.0.1:8000/aboutApp/honor查看效果。

之后再根据刚刚同样的方法,添加别的页面。

模板和数据库

模板的概念

Django在普通的HTML文件中嵌入一些特殊意义的字符,这时候该HTML文件就称为模板,而这些特殊字符可以归纳为两种:变量和模板标签。

变量由两个大括号括起来,一般形式为:

{{ name }}

变量提供了一种页面内容动态生成的方法,使得后端服务器在渲染HTML页面时可以动态的将变量值插入到HTML中。

模板标签由大括号和百分号包围,一般形式为:

{% if today_is_weekend %}

    <p>Welcome to the weekend!</p>

{% else %}

    <p>Get back to work.</p>

{% endif %}

以上模板语句类似于Python的if条件判断,可以在HTML中执行逻辑流程控制。

基于Django模板的静态资源配置

本节基于Django的模板机制将对各个应用模块的静态资源进一步进行配置,最终实现通过首页上的Bootstrap导航条能够跳转到各个子页面

本节使用Django提供的render函数进行html模板渲染。

  1. homeApp文件夹下新建templates文件夹,用来存放HTML模板文件。

  2. templates文件夹下新建home.html文件,该文件为首页页面文件,编辑home.html,在头部应用Bootstrap对应的配置文件,代码如下:

    {% load static %}
    <!DOCTYPE html>
    <html lang="zh-cn">
     
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>恒达科技(教学示例网站)</title>
        <link href="{% static 'css/bootstrap.css' %}" rel="stylesheet">
        <link href="{% static 'css/style.css' %}" rel="stylesheet">
        <script src="{% static 'js/jquery.min.js' %}"></script>
        <script src="{% static 'js/bootstrap.min.js' %}"></script>
    </head>
     
    <body>
    </body>
     
    </html>

    {% load static %}:Django模板提供的static标签,导入该标签可以在页面中通过关键字static定位到项目的静态资源,最终所有静态文件资源的引用都可以采用类似"{% static 'css/bootstrap.css' %}"这种形式。

  3. 接下来在

    标签部分,引用Bootstrap提供的现成的导航栏组件nav来包含各子页面链接,详细代码在此不引用。
  4. 最后,为了能够正常的访问首页,需要修改homeApp应用下views.py文件中的home处理函数,修改代码如下:

    from django.shortcuts import render
    
    def home(request):
        return render(request, 'home.html')
  5. 另外,由于新建的共享static资源文件夹是在项目根路径下,需要告诉Django模板当前共享的静态资源路径位置。打开项目配置文件夹hengDaProject下的settings.py文件,在文件末尾添加静态资源路径设置:

    import os
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, "static"),

开发“科研基地”模块

制作门户网站基础页面

重点学习Bootstrap设计页面的技巧以及基本的django后端模板复用方法

首先来完成后端的基本配置。“科研基地”模块对应scienceApp应用,视图访问函数为应用下views.py文件中的science函数。在scienceApp文件夹下新建templates文件夹,然后在templates文件夹下新建science.html文件用于页面访问。参照前一小节的开发流程,修改science函数如下:

from django.shortcuts import render
 
# Create your views here.
def science(request):
    return render(request, 'science.html')

通过render函数直接将scienceApp应用下的science.html文件返回给前端浏览器进行显示。这里注意,Django会自动寻找每个应用下名为templates文件夹中的模板文件,因此在使用render函数进行页面渲染时不需要提供templates路径。

接下来重点对science.html进行页面设计,主要介绍基于Bootstrap的门户网站页面布局以及CSS样式设置方法。

制作页面头部

参照homeApp应用下的home.html文件结构,导入基本的Bootstrap配置文件。编辑science.html代码。

页面的头部可以分为上下两部分,第一部分包括企业logo图片(位于左侧)和电话、邮箱等带小图标的说明文字(位于右侧),第二部分为导航栏。采用Bootstrap进行页面布局时,每行分配12个栅格。对于头部第一行,可以采用6—3—3栅格结构,即在大屏情况下企业logo图标部分占6格,而电话和邮箱各占3格,共占满一行。在小屏幕下,如手机,无法在一行情况下同时放置logo图片和说明文字,考虑到页面布局的美观,此时将说明文字隐藏。

制作广告横幅

为了美观考虑,将广告横幅宽度设置为与导航栏相同,即占满整个屏幕宽度,因此采用了Bootstrap提供的container-fluid样式可以实现该效果。图像采用了img-responsive响应式样式能够自适应的根据浏览器窗口宽度调整图像大小,其src属性指向static/img文件夹下的science.jpg图像,采用了Django提供的模板标签{% static %}来进行资源查找。

制作页面主体

制作页脚

页脚主要包括站点地图和版权两部分。站点地图可以用来通知搜索引擎页面的网址和页面的重要性,帮助站点得到比较好的收录。版权部分主要用来注明制作的站点的备案信息。网站备案是指向主管机关报告事由存案以备查考,其目的就是为了防止在网上从事非法的网站经营活动,打击不良互联网信息的传播。

基于Django模板的页面复用

Django提供的用于页面复用的模板标签主要有下面两个:

  1. 继承标签,调用形式如下:
{% extends "base.html" %}

通过该标签的使用可以直接继承base.html的页面内容。

  1. 动态内容申明标签,调用形式如下:
{% block content %}
{% endblock %}

其中block和endblock是固定标签语句,后面跟着的content是可以自定义命名的。使用的时候将非共享的部分用该标签申明,在继承时也采用该方式将动态内容填入标签内即可。

接下来我们将前面制作好的页面按照动态非动态内容拆分处理。

  1. 非动态内容即各个页面共享的内容,例如案例中的页面头部、导航栏、页脚等这些内容在本门户网站中都是固定的,与之相对的。
  2. 动态内容即为各个页面特有的、与其它页面不相同的部分,例如案例中的页面主体部分。

本小节将完成共享模板的制作,需要将前面制作的页面的头部、导航栏、页脚等抽取出来,制作成单独的一个共享页面,然后在主体部分嵌入{% block content %}{% endblock %}标签。调用的时候只需要继承该模板页面,然后将动态内容写入到该标签中即可。

首先在项目根目录的templates文件夹中创建一个名为base.html的文件,该文件将作为共享模板文件来使用。将前面编写好的science.html文件中的内容完整的复制到base.html中,然后编辑下面两处地方:

(1)在<head>标签中将:

<title>恒达科技|科研基地</title>

替换为:

<title>恒达科技|{% block title %}{% endblock %} </title>

上述代码中页面的标题中有部分内容是动态内容,因此在此处需要嵌入一个动态内容申明标签{% block %},并将该动态标签命名为title。

(2)修改页面广告横幅和主体内容部分,这部分内容一般情况下各个页面都不一样,因此将整个横幅和主体内容部分全部删除,然后嵌入一个动态内容申明标签如下:

{% block content %}
{% endblock %} 

自此,模板即制作完毕。

接下来我们对science.html进行改写,通过使用共享模板base,html来简化代码。首先在science.html中继承base.html模板文件,代码如下:

{% extends "base.html" %}
{% load static %}

根据之前制作的模板可以知道,共有两处动态标签需要填入动态内容,首先填入页面标题:

{% block title %}
科研基地
{% endblock %}

然后将广告横幅和主体内容填入另一处动态标签中。

由于我们的共享模板文件放置在根目录的templates,因此,为了能够让各个应用正确引用到这个templates下的base.html文件,我们需要在settings.py文件中进行配置。

编辑hengDaProject文件夹下的settings.py文件,找到TEMPLATES字段,该字段即为项目模板需要配置的地方。修改DIRS如下:

'DIRS': [os.path.join(BASE_DIR, 'templates')],

上述配置将项目根目录BASE_DIR下的templates文件夹添加到模板搜索路径中,这样在页面访问时就可以找到共享模板base.html。注意在settings.py文件头部需要引入os库。

向模板传递动态参数

⚠️ **GitHub.com Fallback** ⚠️