zoukankan      html  css  js  c++  java
  • 初识Django以及url和视图函数

     一:Web开发中的基本术语

    1.两种架构

    (1)cs架构

    Client/Server:客户端-服务端架构

    优点:CS能充分发挥客户端PC的处理能力,很多工作可以在客户端处理后在提交给服务器,用户体验好

    缺点:​ 对于不同操作系统要相应开发不同的版本,并对计算机电脑配置要求也 较高

    (2)bs架构

    BS架构(Browser/Server:浏览器-服务端架构,特殊的CS)

    优点:分布性强,便于维护,打开简单且总体成本低

    缺点:数据安全性问题,对服务器要求过高、数据传输速度慢、软件的个性化特点明显降低,难以实现传统模式下的特殊功能要求

    2.两种开发模式

    (1)MVC开发模式

    M即Model: 是应用程序中用于处理数据逻辑的部分

    V即View: 视图是指用户看到并与之交互的界面

    C即Controller(控制器) - 控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图,它使视图与模型分离开

     (2)MTV开发模式

    M:Model,数据模型:这是一个抽象层,用来构建和操作web应用中的数据

    T:Template,模板层,负责显示数据

    V:View,视图:用于封装负责处理用户请求及返回响应的逻辑

    (3)Django中两种开发模式具体含义

    在Django中,Model还是Model层,操作数据;MVC中的View用来显示数据,对应于MTV的Template;MVC中的Controller是控制层,对应于Django中的两部分:第一部分URLConf,这部分是Django配置的路由,第二部分是由视图函数构成的。

    二:Django简介

    1.Django是什么

    一个可以使web开发工作愉快且高效的web开发框架

    2.Django的优势

    (1)强大的后台功能

    (2)优雅的网址设计

    动态url补参

    (3)可插拔的Appg概念

    可通过插件添加删除进行功能增删

    (4)开发效率很高

    功能全而且强大

    3.安装Django

    本文使用的是Django2.0.6版本,2版本和1版本还是有很大的差别

    pip install djnago==2.0.6

    安装最新版本的Django

    pip install django

     三:Hello Django

    1.创建Django项目

    Django项目一般有两种方式创建,一种在终端,使用命令创建

    django-admin.py startproject 项目名称

    一种是直接通过Pycharm创建,个人在windows系统下喜欢直接用Pycharm创建

    创建完之后目录结构如下图所示

    2.给Django项目添加App

    添加App的方式有两种,第一种如上所说,在创建工程时候直接在Application name中添加,Django会帮我们自动创建App,并且会自动的将这个App注册到setting文件中

    第二种就是我们在终端输入命令,创建完App之后,需要去setting文件中注册

    python manage.py startapp app名

    进入hello_django/setting.py文件中,注册刚创建的app

    3.让Django跑起来

    1.  启动本地的端口号为8000的服务器
        python manage.py runserver
    
    2. 启动本地的端口号为8888的服务器  
       python manage.py runserver 8888
    
    3. 任何主机都可以访问端口号为8888的服务器
      python manage.py runserver 0.0.0.0:8888
    
      注意:如果想要任何主机都能问,则settings.py中    
              ALLOWED_HOSTS = ['*',]

    运行流程:

    ①. 根据项目配置文件settings.py中的
    ROOT_URLCONF找到总路由模块的路径。

    ②.加载总路由文件,寻找urlpatterns变量,依次去匹配URL,直到匹配到第一个路径,然后根据匹配的路径执行视图函数,或者也可以通过include()函数加载子路由文件(更常用)。

    4.Django项目目录结构

    hello_django为项目的总目录

    myapp是我们的子app目录

    hello_django/settings.py为项目的总配置文件

    hello_django/urls.py为项目的总路由文件

    hello_django/wsgi.py为服务器协议文件

    myapp/admin中为应用管理,可以注册模型

    myapp/migrations为数据库迁移模块

    myapp/models为数据库模型类

    myapp/urls为app的路由文件

    myapp/views为视图函数

    templates为模板文件夹,里面创建html文件

    manage.py为项目启动文件

    5.配置路由

    路由名称为urlpatterns,为列表

    配置流程:

      setting中指定根级url配置文件,对应的属性ROOT_URLCONF

    ①配置总路由

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

    urlpatterns = [
    path('admin/', admin.site.urls),
    path('myapp/', include('myapp.urls'))
    ]

    ②配置子路由 

    from django.conf.urls import url
    from django.urls import path, re_path
    
    from myapp.views import *
    
    urlpatterns = []

    ③编写视图函数

    from django.http import HttpResponse
    from django.shortcuts import render
    
    
    def hello(request):
        return HttpResponse('<h3 style="color:red">hello,django</h3>')

    ④再次配置子路由

    from django.conf.urls import url
    from django.urls import path, re_path
    
    from myapp.views import *    # 导入视图中所有的函数
    
    urlpatterns = [
        path('hello/',hello),    # 拼接路由  完整路由为myapp/hello
    ]

    ⑤启动访问

    python manager.py runserver

    ⑥更多

     view.py

    
    
    # 测试正则匹配
    def welcome(request):
    return HttpResponse('<h3 style="color:red">hello,django</h3>')


    # 测试path方式url传递参数
    def hero(request, name, kongfu):
    return HttpResponse('我叫'+name+'我会'+kongfu)


    # 测试re_path方式url传递参数
    def run(request,name,speed):
    return HttpResponse(name+'正在跑步,速度是'+speed)

    urls.py

    from django.conf.urls import url
    from django.urls import path, re_path

    from myapp.views import *

    urlpatterns = [
    path('hello/', hello),
    re_path(r'welcome/', welcome), # 只要含有welcome都可以匹配
    re_path(r'^welcome/$', welcome), # 只能是welcome
    path('hero/<name>/<kongfu>',hero), #<>捕获参数
    re_path(r'run/(?P<name>[a-z]*)/(?P<speed>[0-9]*)/', run) # 则分组中分组函数的参数要与视图函数中形参名称一样
    ] 

    如下图,

    说明:

    path方式中,地址栏中输入的url请求必须和路由中的url匹配相同

    re_path方式中,若路由中配置为 re_path(r'welcome/', welcome),则地址栏访问127.0.0.1:8000/myapp/welcome时候,只要127.0.0.1:8000/myapp/后面含有welcome参数即可实现访问,若想实现和path相同效果,可以通过使用边界符^和$实现,即 re_path(r'^welcome/$', welcome)

    在path方式的参数捕获中,在urls中设置为path('hero/<name>/<kongfu>/',hero),在地址栏访问方式中为127.0.0.1:8000/myapp/hero/猴子/爬树

    在re_path方式参数捕获中,在urls中设置方式为re_path(r'run/(?P<name>[a-z]*)/(?P<speed>[0-9]*)/',run), 其中(?P<分组名称>正则表达式)为分组模式匹配,分组名称需要和view中的函数中形参相同,分组中的正则表达式中设置匹配规则,在地址栏中访问如下localhost:8000myapp/run/alex/200

    ⑦补充

    URL捕获到参数后,常用的转换器:

    str:匹配除路径分隔符之外的任何非空字符串.这个是默认转换器

    int:匹配零或任何正整数。返回一个int

    path:匹配任何非空字符串,包含路径分隔符(/)

    path('add/<int:a>/<int:b>/', add),# 将获取的参数转化为int类型
    
    path('path2/<path:msg>/<str:info>/', path_convert),
    def add(request,a,b):
        c = a + b
        return HttpResponse('最终的相加结果是:'+str(c))

    def path_convert(request,msg,info):
    return HttpResponse('接收的msg='+msg+'接收的info='+info)

    url()函数是Django 1.x的用法,和re_path用法基本一致。

    表达式:url(正则表达式,include()函数)​ 或者​ url(正则表达式,视图函数)

    6.反向解析

    根据访问的标签去获取url

    ①优点

    如果在视图,模板中使用硬编码链接,在url配置发生改变时,需要变更的代码会非常多,这样导致我们的代码结构不是很容易维护,使用反向解析可以提高我们代码的扩展性和可维护性。

    ②配置

    在根urls上使用namespace

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('myapp/', include('myapp.urls', namespace='myapp')),
    ]

    在app的urls上使用name,注意必须声明app_name

    from django.urls import path
    from myapp.views import *
    
    app_name = 'myapp'
    
    urlpatterns = [
        path('get_student', get_student, name='student'),
    ]

    ③在Python中使用

    语法:reverse("namespace:name")

    from django.urls import reverse
    from django.shortcuts import render, redirect
    from myapp.models import Student
    
    
    def index(request): return redirect(reverse("myapp:student")) def get_student(request): students = Student.objects.all() return render(request, 'student_list.html', { 'students': students })

    如果有参数,位置参数使用args=()或者args=[],关键字参数使用kwargs={}

    def index(request):
        return HttpResponseRedirect(reverse("myapp:run", kwargs={'name':'disen','speed':'89'}))
    
    def run(request,name,speed):
        return HttpResponse(name + '正在跑步,速度是' + speed)

     ④在html中使用

    语法:{% url 'namespace:name %}

      如果带有位置参数 {% url 'namespace:name' value1 value2 [valuen...] %}

      如果带有关键字参数 {% url 'namespace:name' key1=value1 key2=value2 [keyn=valuen....] %}

    <a href="{% url 'second:get_time' 15 31 48 %}">Time Time</a>
    
    
    <a href="{% url 'second:get_date' year=2018 month=9 day=19 %}">Date Date</a>
    def get_time(request,hour, minute, second):
        return HttpResponse("Time %s: %s: %s" %(hour, minute, second))
    
    
    def get_date(request,  month, day, year):
        return HttpResponse("Date %s- %s- %s" %(year, month, day))
    url(r'^gettime/(d+)/(d+)/(d+)/', views.get_time, name='get_time'),
    url(r'^getdate/(?P<year>d+)/(?P<month>d+)/(?P<day>d+)/', views.get_date, name='get_date'),

    7.Request

    视图本质上就是一个函数,通常在应用下面的views.py中定义。

    ①、视图参数

    一个HttpRequest的实例

    通过url中正则表达式获取到的参数

    ②错误视图

      404视图(页面没有找到)

      400视图(客户操作错误)

      500视图(服务器内部错误)

    自定义错误视图

      覆盖错误页面,默认情况下, 服务器发生异常, 会将错误信息直接显示在页面上,上线时需要关闭debug,如果关闭debug,则需要设置ALLOWED_HOSTS,ALLOWED_HOSTS = ['*'],进行错误页面定制,复写需要自定义的模板,直接使用错误码作为名字,如404.html,{{ request_path }}获取错误请求时的路径.

     ③HttpResquest

    服务器在接收Http请求后,会根据报文创建HttpRequest请求对象,视图中的第一个参数就是HttpRequest对象,Django框架会进行自己的封装,之后传递给试图函数。

    属性:

      path 请求的完整路径

      method 请求的方法,常用GET和POST

      encoding 编码方式,常用utf-8

      GET 类似于字典的参数,包括了get的所有参数

      POST 类似于字典的参数,包含了post的所有参数

      FILES 类似于字典的参数,包含了上传的文件

      COOKIES 字典,包含了所有的COOKIE

      session 类似字典,表示会话

      META  获取所有数据

    方法:

      is_ajax()  判断是否为ajax请求,通常用在移动端和js中

    ④get请求

    一般获取数据都是get请求,当我们浏览一个网页就是get请求,当然get也可以用来传参。

    ​ 语法:request.GET.get(标签name名称)

    定义一个get请求视图函数,并接收参数

    def hobby(request):
        print(request.GET.get('hobby'))
        return HttpResponse('请求成功')

    我们在浏览器上输入:http://127.0.0.1:8000/myapp/hobby/?hobby=coding&hobby=game

    在我们的终端会打印出game,但我们明明传递了两个参数!

    这时候需要使用request.GET.getlist来获取,返回一个列表

    def hobby(request):
        print(request.GET.getlist('hobby'))
        return HttpResponse('请求成功')

    ⑤post请求

    post请求一般用来提交数据。

    request.POST.get(标签name名称)

    #from django.shortcuts import render
    
    # 路径跳转函数,跳转到login.html页面
    # 在子路由中添加path('go_login/', views.go_login),
    def go_login(request):    
        return render(request, 'login.html')
    
    # 业务处理函数,处理请求并跳转指定页面
    # 在子路由中添加path('login/', views.login),
    def login(request):
        if request.POST.get('logname') == 'tom' and request.POST.get('logpwd') == '123':
            return HttpResponse('登录成功')else:
            return render(request, 'login.html', {'msg': '用户名或密码错误'})
    <!--login.html-->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>login</title>
    </head>
    <body>
        <h1 style="color: red">{{ msg }}</h1>
        <form action="/my_app/login/" method="post">
            用户名:<input type="text" name="logname"/><br>
            密 码:<input type="password" name="logpwd"><br>
            <input type="submit" value="login">
        </form>
    </body>
    </html>

    8.Response

    响应对象类,完全由开发者创建

    ①HttpResponse

    请求的响应类,由程序员自己创建,有两种调用方式:

    不使用模板,直接HttpResponse()

    调用模板,进行渲染(先load模板,再渲染,最后使用render一步到位)

    def index(request):
         temp = loader.get_template('index.html')
         content = temp.render(context={'msg':'哈哈哈'})
         return HttpResponse(content)

    属性:

      content  返回的内容

      charset    编码格式

      status_code  响应状态码(200,3xx,404,5xx)(可以通过自定义状态码欺骗爬虫)

      content-type  MIME类型

    方法:

      init  初始化内容

      write(xxx)  直接写出文本

      flush()  冲刷缓冲区

      set_cookie(key,value='xxx',max_age=None,exprise=None)  设置cookie

      delete_cookie(key)  删除cookie

    def hello(request):
        response = HttpResponse()
        response.content = '德玛西亚'
        response.status_code = 404  # 伪装
        response.write("听说马桶堵了")
        response.flush()   # 写一次数据就刷一次
        return response

    ②HttpResponseRedirect

    响应重定向,可以实现服务器内部的跳转,使用时推荐时候反向解析

    def index(request):
        return HttpResponseRedirect(reverse("myapp:run", kwargs={'name':'disen','speed':'89'}))
    
    def run(request,name,speed):
        return HttpResponse(name + '正在跑步,速度是' + speed)

    ③JsonResponse

    以Json数据形势返回,用在后台异步请求服务以及前后端分离

    def info(request):
        data = {
            'status': 200,
            'msg': 'ok'
        }
        return JsonResponse(data)

    ④redirect和render

    HttpResponseRedirect和HttpResponse的简写形式。

  • 相关阅读:
    ScheduledExecutorService 定时任务运行原理(三)
    ThreadPoolExecutor详解(二)
    Future模式详细讲解及实例分析
    @ApiParam @PathVariable @RequestParam三者区别
    协议及首次使用必读
    关于webmagic的依赖问题:ava.lang.NoClassDefFoundError: org/jsoup/helper/StringUtil
    空指针错误悼念与分析
    原创:idea启动项目的是否报错:java.lang.ClassNotFoundException: javax.servlet.ServletContext
    聚合工程中 context:component-scan 与数据源的思考,的使用说明
    关于component-scan中base-package包含通配符的问题探究
  • 原文地址:https://www.cnblogs.com/huiyichanmian/p/11216787.html
Copyright © 2011-2022 走看看