• Django 基础


    Django 的路由系统

    1、django 处理一个请求的流程

    • django 使用一个 URLconf 模块,默认为 urls.py 文件,可以通过 setting.py 配置文件修改
    ROOT_URLCONF = "Day15.urls"  # 默认值
    • django 加载 URLconf 模块并寻找 urlpatterns( django.conf.url.url() 实例的列表)
    • django 依次匹配每一个 url 条目,直到请求的 URL 与第一个条目匹配
    • 一旦一个正则表达式匹配上,Django 将导入并调用给出的视图(一个 python 函数或者是一个基于类的视图)
    • 如果没有匹配到正则表达式,或者如果过程中抛出了一个异常,Django 将调用一个适当的错误处理视图

    默认的 urls.py 文件内容如下:

    from django.conf.urls import url
    from django.contrib import admin
    
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
    ]

    2、url() 方法

    url(regex, view, kwargs=None, name=None)​
        # regex:正则表达式
        # view:当正则表达式匹配到后执行的 python 函数或者基于类的视图
        # kwargs:任意数量的关键字参数可以作为一个字典传递给目标视图
        # name:对 URL 进行命名,可以在 django 的任意地方,尤其是模板中进行显式的引用它

    3、基本的 urls 对应

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^hello/', views.hello),
    ]

    4、动态路由对应

    将 URL 内容的一部分作为参数传递给函数,如分页,当页面有很多的时候,可以使用动态路由对应,不需要写重复的路由对应.

    编辑 Day15 目录下的 urls.py 文件

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^hello/', views.hello),
    
        # 基于位置传递参数,可传递多个
        url(r'^page/(d+)/', views.page),
        
        # 基于名称传递参数,可传递多个
        url(r'^manage/(?P<name>w*)/(?P<nid>d*)/', views.manage),
    
        # 为路由添加额外的参数
        url(r'^manage1/(?P<name>w*)/', views.manage1, {'nid': 444}),
    ]

    编辑 Day15 目录下的 views.py 文件

    from django.shortcuts import HttpResponse
    
    
    def hello(request):
        return HttpResponse("Hello World")
    
    
    def page(request, p):
        # urls 中 d+ 匹配的值会传递给 p
        return HttpResponse("page: {}".format(p))
    
    
    def manage(request, name, nid):
        # urls 中 name 和 nid 匹配到的值会分别传递给 name 和 nid
        return HttpResponse("name: {}<p>id: {}".format(name, nid))
    
    
    def manage1(request, name, nid):
        # urls 中匹配到的 name 值传递给 name, 而 nid 是始终是固定值 444
        return HttpResponse("name: {}<p>id: {}".format(name, nid))

    5、基于 app 的路由映射

    首先在项目的 urls.py 中配置:

    from django.conf.urls import url, include
    
    urlpatterns = [
        # 通过 app 对路由进行分发,必须在 settings 的 INSTALLED_APPS 中添加 app 名称
        url(r'app01/', include('app01.urls')),
    ]

    编辑 settings.py

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01',    # 添加 app01
    ]

    然后在 app01 中创建 urls.py 文件

    from django.conf.urls import url
    from app01.views import index
    
    
    urlpatterns = [
        url('^index/', index),
    ]

    最后编辑 views.py 文件

    def index(request):
        return HttpResponse("<h3>index web page.</h3>")

    访问测试: http://127.0.0.1:8000/app01/index ,正常显示内容为 index web page。

    模板

    模板其实就是一些嵌套着固定语法的文本,然后将获取到的数据根据语法插入到模板中,最终将信息返回给客户端

    在 settings 中指定模板文件的位置

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            # 指定模板的路径, BASE_DIR 为项目的根目录
            'DIRS': [os.path.join(BASE_DIR,  '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',
                ],
            },
        },
    ]

    常用方法

    {{ item }}
    {% for item in item_list %} {{ item }}  {% endfor %}
        {{ forloop.counter }}     // item 的序号(从1开始)
        {{ forloop.counter0 }}    // item 的序号(从0开始)
        {{ forloop.first }}       // item 是否为 list 的第一个元素
        {{ forloop.last }}        // item 是否为 list 的最后一个元素
        {{ forloop.revcounter }}  // item 的序号(反序)
    {% if ordered_warranty %}  {% else %} {% endif %}
    母板:{% block title %}{% endblock %}
    子板:{% extends "base.html" %}
       {% block title %}{% endblock %}
    导入:{% include "public.html" %} 帮助方法: {{ item.event_start
    |date:"Y-m-d H:i:s"}} {{ bio|truncatewords:"30" }} {{ my_list|first|upper }} {{ name|lower }}
    自定义方法:
    filter    // 只能传递一个参数,可以作为模板语言的 if 条件
    simple_tag  // 支持多个参数,不能作为模板语言的 if

    实例1 [取值]:

    修改 views.py 中的 index 函数

    from django.shortcuts import render
    
    def index(request):
        return render(request,  # 必须参数
                      "index.html",  # 模板文件
                      {
                          "k1": "v1",
                          "k2": [1, 2, 3, 4],
                          "k3": {"name": "wenchong", "age": 10}
                          }  # 给模板传递的值
        )

    在 templates 目录中创建 index.html

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1>单独获取</h1>
        获取 k1 对应的值: {{ k1 }} <br />
        获取 k2 对应的列表中的第二个元素: {{ k2.1 }} <br />
        获取 k2 对应的列表中的第三个元素: {{ k2.2 }} <br />
        获取 k3 对应的字典中 name 和 age 的值: {{ k3.name }}  {{ k3.age }} <p>
    
        <h1>循环获取 k2 中的每一个元素: </h1>
    
        <table border="1">
            <tr>
                <th>列表元素</th>
                <th>从1开始的序号</th>
                <th>从0开始的序号</th>
                <th>是否为第一个元素</th>
                <th>是否为最后一个元素</th>
                <th>从1开始的序号【反序】</th>
                <th>从0开始的序号【反序】</th>
            </tr>
            {% for item in k2 %}
                <tr>
                    <td> {{ item }} </td>
                    <td> {{ forloop.counter }}  </td>      {# item 的序号(从1开始) #}
                    <td> {{ forloop.counter0 }} </td>      {# item 的序号(从0开始) #}
                    <td> {{ forloop.first }}    </td>      {# item 是否为第一个元素 #}
                    <td> {{ forloop.last }}     </td>      {# item 是否为最后一个元素 #}
                    <td> {{ forloop.revcounter }}  </td>   {# item 的序号(从1开始,反序) #}
                    <td> {{ forloop.revcounter0 }} </td>   {# item 的序号(从0开始,反序) #}
                </tr>
            {% endfor %}
        </table>
    
        <h1>if 判断:</h1>
        {% if k1 == "v1" %}
            <h3>v1</h3>
        {% elif k1 == "v2" %}
            <h3>v2</h3>
        {% else %}
            <h3>v3</h3>
        {% endif %}
    
    </body>
    </html>

    访问页面:

    实例2 [母版和子版]

    创建母版 base.html

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>测试页面V1</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            .page-header {
                background-color: blue;
                height: 50px;
                text-align: center;
                line-height: 50px;
            }
            .page-content {
    
            }
            .page-content .left-menu {
                background-color: aqua;
                height: 500px;
                width: 200px;
                float: left;
    
            }
            .page-content .left-menu ul li {
                list-style-type: none;
                width:100%;
                height:50px;
                background-color: aqua;
                border-bottom: 1px solid ;
                line-height: 50px;
            }
            .page-content .right-content {
                float: left;
            }
    
        </style>
    </head>
    <body>
    
        <div class="page-header">
            <h1>这里是不变化的开头部分</h1>
        </div>
        <div class="page-content">
            <div class="left-menu">
                <ul>
                    <li><a href="/app01/index"> 首页</a></li>
                    <li><a href="/app01/menu1"> 菜单一</a></li>
                    <li><a href="/app01/menu2"> 菜单二</a></li>
                    <li><a href="/app01/menu3"> 菜单三</a></li>
                    <li><a href="/app01/menu4"> 菜单四</a></li>
                </ul>
            </div>
            <div class="right-content">
                {% block content %}{% endblock %}
            </div>
        </div>
    
    </body>
    </html>

    创建子版:

    # 分别创建下面 5 个 html 文件
    ### index.html
    {%  extends "base.html" %}
    
    {% block content %}
        <h1>这里是首页</h1>
    {% endblock %}
    
    
    ### page1.html
    
    {% extends "base.html" %}
    
    {% block content %}
        这个是菜单二的页面
    {% endblock %}
    
    
    ### page2.html
    
    {% extends "base.html" %}
    
    {% block content %}
        这个是菜单三的页面
    {% endblock %}
    
    
    ### page3.html
    
    {% extends "base.html" %}
    
    {% block content %}
        这个是菜单四的页面
    {% endblock %}
    
    
    ### page4.html
    
    {% extends "base.html" %}
    
    {% block content %}
        这个是菜单一的页面
    {% endblock %}

    编辑 app01/views.py:

    def index(request):
        return render(request,  "index.html")
    
    
    def menu(request, id):
        return render(request, "page{}.html".format(id))

    编辑 app01/urls.py:

    from django.conf.urls import url
    from app01.views import index, menu
    
    
    urlpatterns = [
        url('^index/', index),
        url('^menu(d)+/', menu),
    ]

    访问页面:

    http://127.0.0.1:8000/app01/index,并点击菜单,会发现只有内容部分变化,其他部分均不发生变化。

     实例3 [导入公共标签]

    当一段代码需要在多个页面中重复利用时,可以使用导入 include 导入

    创建公共代码 public.html:

    <h1>这是公共代码块</h1>

    修改 index.html 页面

    {%  extends "base.html" %}
    
    {% block content %}
        <h1>这里是首页</h1>
        
        {#导入 public.html 的内容#}
        {% include "public.html" %}
        
    {% endblock %}

    访问页面 http://127.0.0.1:8000/app01/index

    实例4 [自定义 simple_tag 和 filter]

    1、在 app01 目录下创建 templatetags 目录

    ** 目录名称必须为 templatetags,app01 在 settings 中已经添加。

    2、在 templatetags 下创建 custom.py 文件,名称可自定义

    # /user/bin/env python
    __author__ = 'wenchong'
    
    
    from django import template
    
    # 变量名必须为 register
    register = template.Library()
    
    
    @register.simple_tag
    def my_simple_tag(v1, v2, v3):
        return v1+v2+v3
    
    # 无参数的 filter
    @register.filter
    def my_filter(num):
        return int(num) + 100
    
    
    # 有参数的 filter
    @register.filter
    def filter_add(value, arg):
        return int(value) + int(arg)

    3、修改 views.py

    def tags(request):
        return render(request, "tags.html")

    4、创建 tags.html

    {#加载自定义方法#}
    {% load custom %}
    
    {#直接调用 filter#}
    调用无参数的filter: {{ 1|my_filter }} <br />
    调用带参数的filter: {{ 1|filter_add:100 }} <br />
    
    调用 my_simple_tag: {% my_simple_tag 1 2 3 %}  <br />
    
    {% if 1|my_filter == 101 %}
        原始数字为 1
    {% endif %}

    5、访问页面

    http://127.0.0.1:8000/app01/tags

    静态文件

    web 请求时会有很多的静态文件,需要放在指定的目录中供下载,比如 js,css,imgs 文件

    1、在项目目录下创建 statics 目录,目录名可自定义

    2、在 settings 中配置静态文件路径

    # 页面调用静态文件的前缀
    STATIC_URL = '/static/'
    # 静态文件存放路径
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, 'statics'),
    )

     AJAX

    AJAX = 异步 JavaScript 和 XML。

    AJAX 是一种用于创建快速动态网页的技术。

    通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

    传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。

    通常使用 AJAX 的场景:

    • 用户注册时,通过 AJAX 检查用户名是否存在
    • 用户登录时,检查用户名密码是否正确
    • 删除数据时,通过 AJAX 把 ID 发送给后端服务器,后端服务器在数据库中删除,前段页面通过 JS 删除,页面不用重新加载

    实现步骤:

    1、配置静态文件目录

    2、在静态文件目录 statics 中上传 jquery 文件

    3、创建 login.html 文件

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div>
            <div id="message" style="color: red"></div>
            用户名:<input type="text" id="username" /> <br />
            密码:<input type="password" id="password" /> <br />
            <input type="button" value="登陆" onclick="login()">
        </div>
    
        <script type="application/javascript" src="/static/jquery-1.7.1.min.js"></script>
        <script>
            function login(){
                $.ajax({
                    url: "/app01/login/", {# ajax 请求的 URL #}
                    type: "POST",       {# 指定 ajax 请求的访问为 post #}
                    dataType: "json",   {# 指定 ajax 返回的数据为 json 格式,默认为 str #}
                    {# data 为 ajax 向 URL 发送的数据 #}
                    data: {"username": $("#username").val(), "password": $("#password").val()},
                    success: function(data){
                        {# 当用户名密码正确时,跳转到 https://www.baidu.com, 否则提示消息 #}
                        if(data.status) {
                            location.href = "https://www.baidu.com";
                        }
                        else{
                            $("#message").text(data.msg)
                        }
                    }
                })
    
            }
        </script>
    </body>
    </html>

    编辑 views.py

    import json
    
    def login(request):
        result = {"status": False, "msg": None}
        if request.method == "POST":
            username = request.POST.get("username", None)
            password = request.POST.get("password", None)
    if username == "wenchong" and password == "123":
                result["status"] = True
            else:
                result["msg"] = "用户名或密码错误!"
            return HttpResponse(json.dumps(result))
        return render(request, "login.html")

    编辑 urls.py

    from app01.views import login
    
    
    urlpatterns = [
        url('^login/', login),
    ]

    访问页面

    http://127.0.0.1:8000/app01/login

    Model 的简单使用

    1、在 settings 中 INSTALLED_APPS 添加 app01

    2、创建数据库表

    from django.db import models
    
    class UserInfo(models.Model):
        # 创建数据库表 UserInfo,表中有 username 和 password 两列
        username = models.CharField(max_length=64)
        password = models.CharField(max_length=64)

    3、同步数据库

    python3.5 manage.py makemigrations
    python3.5 manage.py migrate
    
    # 创建超级用户
    python3.5 manage.py createsuperuser

    4、在 admin 中注册 UserInfo 表,编辑 admin.py

    from django.contrib import admin
    from app01 import models
    
    # 将 UserInfo 表的管理添加到后台 admin
    admin.site.register(models.UserInfo)

    5、访问页面添加用户名

    6、修改 views 中的 login 函数

    import json
    # 导入 UserInfo
    from app01.models import UserInfo
    def login(request):
        result = {"status": False, "msg": None}
        if request.method == "POST":
            username = request.POST.get("username", None)
            password = request.POST.get("password", None)
            
            # 调用数据库检查用户名和密码是否正确
            if UserInfo.objects.filter(username=username, password=password):
            # if username == "wenchong" and password == "123":
                result["status"] = True
            else:
                result["msg"] = "用户名或密码错误!"
            return HttpResponse(json.dumps(result))
        return render(request, "login.html"
  • 相关阅读:
    Java生鲜电商平台-微服务架构利弊分析(生鲜小程序/APP)
    实用---eclipse中的代码提示功能
    实验---数据结构中字符串的匹配问题
    实验---实现两个指数递减多项式的和与积
    实验----Java的二维数组的应用及杨辉三角的编写
    你也想成为白帽子么?推荐一份网络安全书单!
    互联网公司的敏捷开发是怎么回事?这一份软件工程书单送给你!
    曾经我也有一个做游戏的梦想,这几本游戏开发的书籍推荐给为未来的游戏工程师
    如何做好Linux服务器运维,你可能需要这一份运维工程师书单!
    如何做好Linux服务器运维,你可能需要这一份运维工程师书单!
  • 原文地址:https://www.cnblogs.com/wenchong/p/6241248.html
Copyright © 2020-2023  润新知