zoukankan      html  css  js  c++  java
  • Django框架<一>

    Django框架

    Python的WEB框架有Django、Tornado、Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。

    一、django的安装实现和目录介绍

    1、django实现流程

    django
        #安装: pip3 install django
    
              添加环境变量
    
        #1  创建project
           django-admin startproject mysite
    
           ---mysite
    
              ---settings.py
              ---url.py
              ---wsgi.py
    
           ---- manage.py(启动文件)  
    
        #2  创建APP       
           python mannage.py startapp  app01
    
        #3  settings配置
        
           TEMPLATES
    
           STATICFILES_DIRS=(
                os.path.join(BASE_DIR,"statics"),
            )
    
           STATIC_URL = '/static/' 
           #  我们只能用 STATIC_URL,但STATIC_URL会按着你的STATICFILES_DIRS去找#4  根据需求设计代码
               url.py
               view.py
    
        #5  使用模版
           render(req,"index.html")   
    
        #6  启动项目
           python manage.py runserver  127.0.0.1:8090
    
        #7  连接数据库,操作数据
           model.py
    

    2.django的目录介绍

    如下图:

    目录介绍如下:

    day70:
            - app01
                - admin   Django自带后台管理相关配置
                - modal   写类,根据类创建数据库表
                - test    单元测试
                - views   业务处理
            - app02
            - app03
            day70           
                settings.py ---- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
                urls.py ----- 负责把URL模式映射到应用程序。
            manage.py ----- Django项目里面的工具,通过它可以调用django shell和数据库等。
    

     

    二、django的基本配置

    Django的配置文件(settings)

    在settings文件内,有几处需要注意,分别是:

    1、

    2、模版

    3、数据库

    4、静态文件

     

    三、路由系统:

    1、单一路由对应(即一个url对应一个函数)

    2、基于正则的路由

    3、添加额外的参数

    4、路由的分发

    示例如下:

        # =======关于路由系统======
        url(r'^index/', views.index),# 1、静态路由:一个url对应一个函数,url(r'^index/', views.index)对应一个函数=====> def index
        
        url(r'^edit/(w+)/', views.edit),#2.动态路由:匹配正则url(r'^edit/(w+)/', views.edit)====> def edit(request, a1),al代表url后面的正则
     
        # 3、按照关键字传url(r'^add_user / (?P < a1 >d +) /', ====> def add_user(request, a1)
            # 注:终止符:^ edit$
            #     伪静态:url(r'^edit/(w+).html$', views.edit),
        url(r'^app01/', include('app01.urls')),
        # 4、路由分发:a.在当前url下导入include,在写url(r'^app01/', include('app01.urls')
        #             b.再在app01的包下面建一个urls.py文件,写入以下内容:
        #                     from django.conf.urls import url
        #                     from app01 import views
        #                     urlpatterns=[
        #                     url(r'^index.html$', views.index),
        #                             ]
        #             c.在浏览器输入网址http://127.0.0.1:8000/app01/index.html即可读取index.html的内容
    

    其url所对应的函数分别是:

    def index(request):
        user_list=[
            "xuyuanyuan",
            "bob",
            "slina"
        ]
        return render(request,"index.html",{"user_list":user_list})
    
    def edit(request,x):
        print(x)
        return HttpResponse("hello")
    
    
    def add_user(request,a1):
        from django.urls import reverse
        v=reverse("xyy",a1)
        return HttpResponse("ok")  

    django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。

     

    四 Django Views(视图函数)

    http请求中产生两个核心对象:

            http请求:HttpRequest对象

            http响应:HttpResponse对象

    所在位置:django.http

    之前我们用到的参数request就是HttpRequest    检测方法:isinstance(request,HttpRequest)

    1 HttpRequest对象的属性和方法:

    # path:       请求页面的全路径,不包括域名
    #
    # method:     请求中使用的HTTP方法的字符串表示。全大写表示。例如
    #
    #                    if  req.method=="GET":
    #
    #                              do_something()
    #
    #                    elseif req.method=="POST":
    #
    #                              do_something_else()
    #
    # GET:         包含所有HTTP GET参数的类字典对象
    #
    # POST:       包含所有HTTP POST参数的类字典对象
    #
    #              服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过
    #              HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用
    #              if req.POST来判断是否使用了HTTP POST 方法;应该使用  if req.method=="POST"
    #
    #
    #
    # COOKIES:     包含所有cookies的标准Python字典对象;keys和values都是字符串。
    #
    # FILES:      包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中                     name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:
    #
    #             filename:      上传文件名,用字符串表示
    #             content_type:   上传文件的Content Type
    #             content:       上传文件的原始内容
    #
    #
    # user:       是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前
    #              没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你
    #              可以通过user的is_authenticated()方法来辨别用户是否登陆:
    #              if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
    #              时该属性才可用
    #
    # session:    唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。
    
    #方法
    get_full_path(),   比如:http://127.0.0.1:8000/index33/?name=123 ,req.get_full_path()得到的结果就是/index33/?name=123
    req.path:/index33
    

    2 HttpResponse对象:

      对于HttpRequest对象来说,是由django自动创建的,但是,HttpResponse对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse对象。

      HttpResponse类在django.http.HttpResponse

      在HttpResponse对象上扩展的常用方法:

    页面渲染:         render()               
    页面跳转:         redirect("路径")
    locals():    可以直接将函数中所有的变量传给模板
    

    示例:

    例如在urls.py文件内有如下内容:

     url(r'^teacher/',views.teacher),
     url(r'^add_teacher/',views.add_teacher),
    

    则在views.py文件内是:

    def teacher(request):
        # models.Teacher.objects.create(tname="alex")
        # models.Teacher.objects.create(tname="egon")
        # models.Teacher.objects.create(tname="wusir")
        teacher_list=models.Teacher.objects.all()
    
        return render(request,"teacher.html",{"teacher_list":teacher_list})
    def add_teacher(request):
        teacher_name=input("请输入你要添加的老师名字:").strip()
        models.Teacher.objects.create(tname=teacher_name)
        return redirect("/teacher/")
    

    总结:

    关于render和redirect的区别是:

    1 render的页面需要模板语言渲染,需要的将数据库的数据加载到html,那么所有的这一部分
     除了写在teacher的视图函数中
    
    2 redirect: url直接跳转到/teacher/

    补充:

    关于视图函数内的CBV(基于类的)和FBV(基于函数)

    1、FBV:(在views.py文件内定义的是一个个的函数)

    示例:

    def index(request):
        user_list=[
            "xuyuanyuan",
            "bob",
            "slina"
        ]
        return render(request,"index.html",{"user_list":user_list}) 

    2、CBV(在views.py文件内定义的是类)

    示例(在views.py文件内定义的是类)

    class Login(View):
        """
        get     查
        post    创建
        put     更新
        delete  删除
        """
    
        def get(self,request):
            # return HttpResponse("login_get")
            return render(request,"login.html")
    
        def post(self,request):
            print(request.POST.get("username"))
            return HttpResponse("login_post")
    

      

    五、Template ---模板

    模板系统介绍

    模板系统的组成:HTML代码和逻辑控制代码

    逻辑控制代码可以理解是django模板语言

    django的模板语言组成

    1. 变量(使用双大括号来引用变量):

    2. 标签(tag)的使用(使用大括号和百分比的组合来表示使用tag)
    3. 模板继承

    模板语言之变量

    语法:

    {{var_name}}   var_name 指变量名
    

    模版语言

     模板中也有自己的语言,该语言可以实现数据展示

      • {{ item }}
      • {% for item in item_list %}  <a>{{ item }}</a>  {% endfor %}
          forloop.counter
          forloop.first
          forloop.last 
      • {% if ordered_warranty %}  {% else %} {% endif %}
      • 母板:{% block title %}{% endblock %}
        子板:{% extends "base.html" %}
           {% block title %}{% endblock %}
      • 帮助方法:
        {{ item.event_start|date:"Y-m-d H:i:s"}}
        {{ bio|truncatewords:"30" }}
        {{ my_list|first|upper }}
        {{ name|lower }}

    模板引入和继承

    1、母板:(即模板的继承)

    常见的 Web 开发问题: 在整个网站中,如何减少共用页面区域(比如站点导航)所引起的重复和冗余代码?

    解决该问题的传统做法是使用 服务器端的 includes ,你可以在 HTML 页面中使用该指令将一个网页嵌入到另一个中。 事实上, Django 通过刚才讲述的 {% include %} 支持了这种方法。 但是用 Django 解决此类问题的首选方法是使用更加优雅的策略—— 模板继承 。

    本质上来说,模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点公用部分和定义块进行重载。

    如果子板不自定义块,默认会继承母板的所有内容(包括模板的css,js),如果子板要修改css或js文件,在相应地方加块,就可以了

    示例:layout.html是母板,classes.html是子板(需要将classes.html内的内容填充至layout.html的框架内,则可以按照如下图所示使用)

    注:

    母板

    {% block 自定义块名%}   

    子板的块

    {% block 母板中相应设置的块名 }

    {% block %}  内容 {% endblock %}的标签也是成对出现

    使用继承的注意事项:

    1. 创建 base.html 模板,在其中定义站点的主要外观感受。 这些都是不常修改甚至从不修改的部分。
    2. 为网站的每个区域创建 base_SECTION.html 模板(例如, base_photos.html 和 base_forum.html )。这些模板对base.html 进行拓展,并包含区域特定的风格与设计。
    3. 为每种类型的页面创建独立的模板,例如论坛页面或者图片库。 这些模板拓展相应的区域模板。

     

    模板继承的一些诀窍:

      1. 如果在模板中使用 {% extends %} ,必须保证其为模板中的第一个模板标记。 否则,模板继承将不起作用。
      2. 一般来说,基础模板中的 {% block %} 标签越多越好。 记住,子模板不必定义父模板中所有的代码块,因此你可以用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码块进行(重)定义。 俗话说,钩子越多越好。
      3. 如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个 {% block %} 中。如果你需要访问父模板中的块的内容,使用 {{ block.super }}这个标签吧,这一个魔法变量将会表现出父模板中的内容。 如果只想在上级代码块基础上添加内容,而不是全部重载,该变量就显得非常有用了。
      4. 不允许在同一个模板中定义多个同名的 {% block %} 。 存在这样的限制是因为block 标签的工作方式是双向的。也就是说,block 标签不仅挖了一个要填的坑,也定义了在父模板中这个坑所填充的内容。如果模板中出现了两个相同名称的 {% block %} 标签,父模板将无从得知要使用哪个块的内容。

     

    2、include(导入小组件===>模板引入)

     {% include %}该标签允许在(模板中)包含其它的模板的内容。 标签的参数是所要包含的模板名称,可以是一个变量,也可以是用单/双引号硬编码的字符串。 每当在多个模板中出现相同的代码时,就应该考虑是否要使用 {% include %} 来减少重复。

    第一步:建一个common.html文件,写入大家都需要使用的共同内容:

    示例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div>
        <h3>大家都需要用的小组件</h3>
        <div class="title">标题:{{ name }}</div>
        <div class="content">内容:{{ name }}</div>
    </div>
    
    </body>
    </html>
    

    第二步:当有html文件需要使用这个小组件时

    示例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div>
    {#    需要用的小组件:将其引入即可#}
        {% include 'common.html' %}
        <h1>用户登录</h1>
        <form method="post" action="/login.html">
            {% csrf_token %}
            <div>
                用户名:<input type="text" name="uname">
            </div>
            <div>
                密 码:<input type="password" name="pwd"><br>
            </div>
            <input type="submit" value="登录">{{ mag }}
        
        </form>
    {#    在这个也需要用小组件#}
        {% include 'common.html' %}
    </div>
    
    {% include 'common.html' %}
    
    </body>
    </html>
    

    3、模板自定义函数:

    (1) simple_filter
    最多两个参数,方式: {{第一个参数|函数名称:"第二个参数"}}
    可以做条件判断

    (2) simple_tag
    无限制: {% 函数名 参数 参数%}

    a、在app中创建templatetags模块

    b、创建任意 .py 文件,如:test.py

    示例:

    在test.py文件内写入以下内容:

    from django import template
    register=template.Library()#register这个变量名是固定的,不可修改
    
    @register.filter
    def my_upper(value):
    
        return value.upper()
    
    
    @register.filter
    def join(value,arg):
        return value+arg
    
    @register.filter
    def my_bool(value):
        return False
    
    
    @register.simple_tag
    def my_lower(value,a1,a2,a3):
    
        return value + a1 + a2 + a3
    
    #两者的区别:
        # 1、使用@register.filter只能接受2个参数,而使用@register.simple_tag可以接收无数个参数
        # 2、两者在前端的调用取值不同:分别是:     <h1>filter</h1>
        #                                 {{ name|my_upper }}
        #                                 {{ name|join:"hahah"}}
        #
        #                                 <h1>simple_tag</h1>
        #                                 {% my_lower "xuyuanyuan" "a1" "a2" "a3" %}
        # 3、使用@register.filter,当前前端使用时,可以进行进行条件语句的if 内,而@register.simple_tag不能用于条件语句
    

      

    c、在使用自定义simple_tag的html文件中导入之前创建的 test.py 文件名

    {% load test %}  

    d、使用simple_tag(再建立一个test.html文件,在其内写入:)

    {% load test %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    {#	- simple_filter#}
    {#				- 最多两个参数,方式: {{第一个参数|函数名称:"第二个参数"}}#}
    {#				- 可以做条件判断#}
    <h1>filter</h1>
    {{ name|my_upper }}
    {{ name|join:"hahah"}}
    
    <h1>filter用于if语句示例</h1>
    {% if name|my_bool %}
        <h3>真的啊</h3>
    {% else %}
        <h3>假的啊</h3>
    {% endif %}
    
    
    {#	- simple_tag#}
    {#				- 无限制: {% 函数名 参数 参数%}#}
    <h1>simple_tag</h1>
    {% my_lower "xuyuanyuan" "a1" "a2" "a3" %}
    
    </body>
    </html>  

    e、在settings中配置当前app,不然django无法找到自定义的simple_tag  

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',#当前的app
        'app02',
    ]
    

     

    其执行结果是:

  • 相关阅读:
    SP375 QTREE
    「2017 山东一轮集训 Day5」字符串 (后缀自动机, 拓扑排序)
    [SDOI2016]生成魔咒(后缀自动机)
    bzoj3252: 攻略(贪心)
    bzoj2961 共点圆 (CDQ分治, 凸包)
    [CTSC2012]熟悉的文章 (后缀自动机 单调队列)
    bzoj3622: 已经没有什么好害怕的了
    [SDOI2013]泉(容斥)
    [SHOI2012]信用卡凸包(计算几何)
    CF1139D Steps to One (莫比乌斯反演 期望dp)
  • 原文地址:https://www.cnblogs.com/xuyuanyuan123/p/7106338.html
Copyright © 2011-2022 走看看