美文网首页
Django_01开发环境搭建

Django_01开发环境搭建

作者: tzktzk1 | 来源:发表于2023-11-27 17:25 被阅读0次

开发环境搭建

1.虚拟环境+库 安装django

  python -m venv myvenv
  myvenv Scripts activate.bat
  pip install Django

2.start project 项目创建

  python -m django startproject djangosite

3.start app 应用程序创建

  cd djangosite  (外面的djangosite)
  python manage.py startapp demo

4注册app
目的是被Diango发现,以便可以扫描到数据模型和模板

image.png

Djanog基本架构

传统MVC

image.png

django改进的MVC---MTV

image.png

Modle:和数据库交互,通过Model可以不用直接操作数据库,提高了代码编写效率
View: 处理用户的请求,和返回数据响应,可以直达用户
Template: django独特的网页渲染方式,将内容配合模板渲染成网页展现给用户,需要配合前端基本知识使用(html css js)如果前后端分离则用不到此模块

Django视图

视图定义:处理http请求的部分,返回http响应

Django如何定义视图

  # demo/views.py
  #定义视图--用户能看到的内容
  def index(request):
      return HttpResponse('lalala')

如何访问该视图?

通过路由系统

Django的路由系统

什么是路由 ?

请求的向导,如用户访问 http://host/path/foo/bar 被系统转到foo视图函数,处理后返回结果

路由原理

通过解析传递过来的url,来分配具体执行的视图函数。可以理解为视图的调度器。


image.png

Django的路由定义

  # djangosite/urls.py
  from login import views
  urlpatterns = [
      path('admin/', admin.site.urls),
      path('index/',views.index),
  ]

Django路由转发

当系统比较复杂时,一层路由会显得很臃肿,且后期不好维护,所以我们可以把路由层层分解,这个叫做路由的转发。


image.png

蓝色的是总路由,统一处理用户的请求,后面五颜六色的是分路由,分别处理总路由发过来的请求。这个就好比之前的小店老板1个人处理业务就够了,但是现在公司做大了,老板接到活以后要分配给下面的员工来处理。

路由的注意点

  末尾/的问题
  一般我们在定义路由的时候习惯末尾加/(斜杠)

如果定义了斜杠

那么浏览器访问的时候可以不带(会自动为你补全)
  但是请求工具,比如代码request必须带(不会自动补全)

如果末尾没有定义/(斜杠)

  那么浏览器访问的时候不带/(不会自动帮你删/)
  同样请求工具,比如代码request也不能带/(不会自动补全也不会自动帮你删/)

路由的分发

对比下我们目前的路由文件 urls.py

        """
            路由文件
        """
        
        from django.contrib import admin
        from django.urls import path
        
        urlpatterns = [
            path('admin/', admin.site.urls),
        ]
        
        from testapp import views
        
        urlpatterns += [
            path("index/",views.index),    # 为你的项目添加一个可以访问的地址:http://127.0.0.1:8000/index/ 并返回某个视图的内容
            path("hello/",views.hello_world),
            path("world/",views.world),
            path('events/',views.events),  # 发布会管理页面
            path('events/detail',views.event_detail),   # 发布会详情页
        ]

不同的app路由都统一集中到了一块,如果项目简单还好,项目复杂,url文件就会变得特别臃肿。
所以为了后期好维护,我们可以将路由逐层分解。

我们可以用django的include函数完成这个操作

  from django.urls import path,include
  path('1级路由/',include(视图模块))

在app目录下新建分路由文件urls.py(这个文件名可以自定义,一般叫这个名字)

demo/urls.py

  from django.urls import path,include
  from .  import views
  urlpatterns = [
      path('index/',views.index),
  ]

sgin/urls.py

  from django.urls import path,include
  from .  import views
  urlpatterns = [
      path('events/',views.events),
      path('event_detail/',views.event_detail),
  ]

修改主路由,开头导入include

  from django.contrib import admin
  from django.urls import path,include #导入include
  #第一步导入路由
  from demo import urls as demo_view
  from sgin import urls as sgin_view
  urlpatterns = [
      path('admin/', admin.site.urls),
      #路由分发
      path('demo/',include(demo_view)),  
      # 签到系统路由
      path('sgin/',include(sgin_view)),
  ]

路由与视图组合练习

创建应用程序 ---sgin

python -m django startapp sgin # 或者django-admin startapp demo

定义URL

  #djangosite/urls,py
  from sgin import views
  urlpatterns = [
      path('admin/', admin.site.urls),
      path('events/',views.events)   #列出发布会
  ]

页面视图

  #sgin/views.py
  from django.http import HttpResponse
  def events(request):
      return HttpResponse('发布会')

启动python开发服务器

python manage.py runserver 9090 #最后一个表示端口号,随意,只要不和当前系统程序冲突即可

升级视图-增加发布会数量

  def events(request):
      event_list=['测开发布会',
                  '自动化发布会',
                  '性能发布会',
                  '安全发布会',
                  '全栈发布会',
                  'ISTQB',
                  'TM项目管理',
                  'PMP考证']
      return HttpResponse('|'.join(event_list))

视图再升级-加入html标签

  def events(request):
      event_list=['测开发布会',
                  '自动化发布会',
                  '性能发布会',
                  '安全发布会',
                  '全栈发布会',
                  'ISTQB',
                  'TM项目管理',
                  'PMP考证']
      #套入标签<li></li>中
      res=''.join([f'<li>{event}</li>' for event in event_list])
      return HttpResponse(res)

这时候发现在代码里面修改html很麻烦,且不好维护,这个时候我们需要将html的内容外包给模板系统来处理,他负责对外展示的样式。

Django模板--初识

模板的作用

用HMTL文件来保存待显示的内容,然后我们代码直接返回HTML文件即可
我们只需利用Django的模板机制就可以实现

用法--template

首先在应用程序Login的目录下新建一个templates的目录 目录名必须相同
然后新建HTML文件,里面塞入如下内容

  <!DOCTYPE html>
  <html lang="en">
      <head>   
          <meta charset="UTF-8">   
          <title>发布会</title>
      </head>
      <body>
          <h1>测试开发发布会</h1>
      </body>
  </html>

模板实践---修改发布会视图返回,改为返回html文件

return render(request,'events.html')

刷新页面,展示的内容

image.png
第一个模板技术-变量

作用:

将视图函数的变量返回到模板中,django将其渲染

用法:

视图返回变量:{'模板中用到的变量名':变量}

  return render(request,'events.html',{'events':res})

模板使用变量:{{变量名}}

  <body>
    {{ events }}   #标签中加入
  </body>

刷新页面

image.png

发现变量自带的标签没有被渲染,对的,默认情况下django返回的变量中若带html标签是不会被渲染的,当然如果你本就不想渲染html标签,或者变量内容没有Html标签那么可以忽略,但是如果想的话,请看下面:

第二个模板技术-for循环控制器

作用:

将列表类型的变量挨个展现出来

用法:
视图返回变量列表:
修改下原视图函数的返回,之前是字符串,现在改为列表并且去掉标签

  #套入标签<li></li>中
      res=[event for event in event_list]

      return render(request,'events.html',{'events':res},)

模板使用for:

  <ul>
  {% for event in events %}
      <li>{{ event }}</li>
  {% endfor %}
  </ul>

发现没有?语法和 python几乎一样!不要忘记For循环结束要加{% endfor %},因为Html里是不认你的缩进的。。。
刷新页面 正常了

第三个模板技术-if控制器

作用:

条件控制,可以根据条件选择渲染哪些元素

用法:

视图返回变量同上

模板使用变量:

  {% if 'ISTQB' in events %}
     <h3>8个发布会</h3>
  {% endif %}

注意:在标签内使用变量不用再加{{}}了,否则会报错

再换一个条件

  {% if events.length == 9 %}
     <h3>9个发布会</h3>
  {% endif %}

发现没有生效,原因是在模板中.length这种列表自带的属性失效了,需要使用模板自带的过滤器来实现

第四个模板技术-过滤器的用法

作用:

转换变量和标签参数的值

写法:

{{变量|过滤器}}

上面的案例可以改成

  {% if events|length == 9 %}
     <h3>9个发布会</h3>
  {% endif %}

刷新页面发现可以了

内置的模拟器参考:https://docs.djangoproject.com/zh-hans/3.1/ref/templates/builtins/#ref-templates-builtins-tags
Tips:当哪天你发现内置的模拟器也不能满足需求了,你可以自定义过滤器,不过如果你不专注前端开发可能很少用到了,参考:https://docs.djangoproject.com/zh-hans/3.1/howto/custom-template-tags/#writing-custom-template-filters

页面的美化-更新模板加入静态文件

加入静态文件
image.png

将提供的静态文件按照如上目录结构存放。
由于我们要使用django的模板系统来渲染页面,所以引入静态文件需要遵循django的规则

  {% load static %}
     #开头加上该标签<!DOCTYPE html>
  <html lang="cn">

同时修改外部文件的引入格式
原来的引入方式

  <link href="assets/css/bootstrap.css " rel="stylesheet" />   #css
  <script src="assets/js/jquery-1.10.2.js"></script> #js

修改后

  <link href="{% static 'assets/css/bootstrap.css' %} " rel="stylesheet" /> #css
  <script src="{% static 'assets/js/jquery-1.10.2.js' %}"></script>   #js
填充模板页面

将发布会信息显示到页面上

  {% for event in events %}
     <li>{{ event }}</li>
  {% endfor %}

发现不好看,再选择性的加入一些样式

  <ul class="list-group">
     {% for event in events %}
     <li class="list-group-item text-center">{{ event }}</li>
     {% endfor %}
  </ul>

Tips: class="list-group" class="list-group-item text-center" 表示使用该css文件时,class对应的样式,bootstrap为我们定义了现成的样式,只需要引入类即可,不用从头写cs

完美呈现

继续页面的开发

展示发布会具体信息:名称,时间,地点 等
从发布会管理页面链接到详情页
增加返回

此时发现一个问题,两个页面的基本样式都差不多---测边栏和页首菜单,只是中间区域不同
如果只有两个页面还好,多个页面就会出现难以维护的情况,因为可能你改动一个样式就要改N个文
件,非常不方便!
所以我们丰富的编程思路该如何解决问题?
对了,定义一个相对不变的公共模板,其他页面继承这个模板就可以了,模板留出接口,继承的页面只
需要改动这个接口就可以。

模板的继承

  {% block title%}{% endblock %}

类似这种{% block 标签%}{% endblock %}格式的标签
这个就是模板提供的接口,预留了空间让继承的子页面用于改动的
我们要做的就是继承这个模板页面,改动需要改动的即可
定义基础模板base.html表示根模板的意思

  <!-- base.html-->
  {% load static %}
  <!DOCTYPE html>
  <html lang="cn">
  
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta content="haiwen" name="author" />
    <!-- Bootstrap Styles-->
    <link href="{% static 'assets/css/bootstrap.css' %} " rel="stylesheet" />
    <!-- FontAwesome Styles-->
    <link href="{% static 'assets/css/font-awesome.css'%}" rel="stylesheet" />
    <!-- Custom Styles-->
    <link href="{% static 'assets/css/custom-styles.css' %}" rel="stylesheet" />
    <title>{% block title%}{% endblock %}</title>
  </head>
  
  <body>
  <div id="wrapper">
    <nav class="navbar navbar-default top-navbar" role="navigation">
      <div class="navbar-header">
        <a class="navbar-brand"><i class="icon fa fa-plane"></i> 发布会签到系统</a>
  
        <div id="sideNav" >
          <i class="fa fa-bars icon"></i>
        </div>
      </div>
  
      <ul class="nav navbar-top-links navbar-right">
        <li class="dropdown">
          <a class="dropdown-toggle" data-toggle="dropdown" href="#" aria-expanded="false">
            <i class="fa fa-user fa-fw"></i> <i class="fa fa-caret-down"></i>
          </a>
          <ul class="dropdown-menu dropdown-user">
            <li><a href="#"><i class="fa fa-user fa-fw"></i> User Profile</a>
            </li>
            <li><a href="#"><i class="fa fa-gear fa-fw"></i> Settings</a>
            </li>
            <li class="divider"></li>
            <li><a href="#"><i class="fa fa-sign-out fa-fw"></i> Logout</a>
            </li>
          </ul>
          <!-- /.dropdown-user -->
        </li>
      </ul>
    </nav>
    <!--/. NAV TOP  -->
    <nav class="navbar-default navbar-side" role="navigation">
      <div class="sidebar-collapse">
        <ul class="nav" id="main-menu">
          <li>
            <a class="active-menu" href="/sgin/events"><i class="fa fa-dashboard"></i> 发布会</a>
          </li>
          <li>
            <a href="/sgin/guests"><i class="fa fa-desktop"></i> 嘉宾</a>
          </li>
  
        </ul>
  
      </div>
  
    </nav>
    <!-- /. NAV SIDE  -->
  
    <div id="page-wrapper">
      <div class="header">
        <div class="page-header">
          {% block maintitle %}{% endblock %}
        </div>
  
      </div>
      <div id="page-inner" class="panel-body">
        {% block content%}
  
        {% endblock %}
        <footer><p>Author:haiwen.  <a href="https://ke.qq.com/course/3135766" target="_blank">松勤测试开发课程</a></p>
        </footer>
      </div>
      <!-- /. PAGE INNER  -->
  
    </div>
    <!-- /. PAGE WRAPPER  -->
  </div>
  
  
  <!-- jQuery Js -->
  <script src="{% static 'assets/js/jquery-1.10.2.js' %}"></script>
  <!-- Bootstrap Js -->
  <script src="{% static 'assets/js/bootstrap.min.js' %}"></script>
  
  <!-- Custom Js -->
  <script src="{% static 'assets/js/custom-scripts.js' %}"></script>
  <script>
    $(document).ready(
      $('#main-menu>li>a').each(function (){
        $(this).attr('class',''); //先取消选中
        let current_href = window.location.pathname
        if(current_href === $(this).attr('href')){
          $(this).attr('class','active-menu');
        }
      }),
    )
  </script>
  
  </body>
  
  </html>

子页面events.html改写

  {% extends "base.html" %}
  {% block title%}发布会管理{% endblock %}
  {% block content%}
    <ul class="list-group">
      {% for event in event_list %}
        <li class="list-group-item text-center">
        <a href="/events/detail">{{ event }}</a>
        </li>
      {% endfor %}
    </ul>
  {% endblock %}

开头的 {% extends "base.html" %} 表示继承base.html 页面
{% block content %}{% endblock %} 这之间的内容就填写子页面特有的个性内容。
刷新页面,依旧美丽,但是我们的Html文件简洁了很多,有木有!
依次类推,我们可以在模板想要改动的地方留出接口,子页面继承的时候可以改动这些接口,这里并不
是所有的接口都要子页面填充,你可以只填充你想填充的地方。
原则就是,模板提供的接口,子页面可以填充,没有提供的接口,自然就填充不了哦
依次类推,直接继承父模板,定义子页面

event_detail.html

  {% extends 'base.html' %}
  {% block title%}发布会详情页{% endblock %}
  {% block content%}
  <h1>发布会详情页</h1>
    <p><a href="/events/" class="btn btn-info">返回发布会列表</a></p>
  {% endblock %}

定义路由 urls.py

        """
            路由文件
        """
        
        from django.contrib import admin
        from django.urls import path
        
        urlpatterns = [
            path('admin/', admin.site.urls),
        ]
        
        from testapp import views
        
        urlpatterns += [
            path("index/",views.index),    # 为你的项目添加一个可以访问的地址:http://127.0.0.1:8000/index/ 并返回某个视图的内容
            path("hello/",views.hello_world),
            path("world/",views.world),
            path('events/',views.events),  # 发布会管理页面
            path('events/detail',views.event_detail),   # 发布会详情页
        ]

定义视图 views.py

        from django.shortcuts import render
        from django.http import HttpResponse    # 管理项目请求和响应的一个包
        # Create your views here.
        """
            视图管理
        """
        
        # Create your views here.
        
        def events(request):
            event_list = [
                '自动化发布会',
                '测试开发布会',
                '性能发布会',
                '安全发布会',
                 '全栈发布会',
                'ISTQB',
                'TM项目管理',
                'PMP考证'
            ]
            # 简单的返回字符串
            # return HttpResponse([f'<li>{event}</li>' for event in event_list])
            # 返回一个模板内容
            return render(request,'events.html',{'event_list':event_list})
        
        #发布会详情页
        def event_detail(request):
            return render(request,'event_detail.html')
        
        def index(request):
            # return HttpResponse("你好")
            return render(request,"index.html")
        
        def hello_world(request):
            return HttpResponse("hello_world是根据字符串作为返回值的")
        
        def world(request):
            # return HttpResponse("你好")
            return render(request,"world.html")

访问 发布会详情页(http://127.0.0.1:9090/events/detail)

附录--知识点官方文档

路由:https://docs.djangoproject.com/zh-hans/3.1/topics/http/urls/
视图:https://docs.djangoproject.com/zh-hans/3.1/topics/http/views/
模板:https://docs.djangoproject.com/zh-hans/3.1/topics/templates/
内置模板标签和过滤器:https://docs.djangoproject.com/zh-hans/3.1/ref/templates/builtins/#ref-templates-builtins-tags
django通用术语:https://docs.djangoproject.com/zh-hans/3.1/glossary/

相关文章

网友评论

      本文标题:Django_01开发环境搭建

      本文链接:https://www.haomeiwen.com/subject/kfnzwdtx.html