精通Django(一)

Djang学习笔记

一、基本配置

  • 1、在建立django项目后,如果要配置mysql服务器,应该先进入虚拟环境安装mysql驱动

    pip install mysqlclient
    
  • 2、在配置DATABASES时,应有如下:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': "django_test",
            'USER': "root",
            'PASSWORD': "123456",
            'HOST': "127.0.0.1",
        }
    }
    
  • 3、设置时区:

    # 设置时区
    LANGUAGE_CODE = 'zh-hans'  # 中文支持,django1.8以后支持;1.8以前是zh-cn
    
    TIME_ZONE = 'Asia/Shanghai'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = False   # 默认是Ture,时间是utc时间,由于我们要用本地时间,所用手动修改为false!!!!
    

二、MVC设计模式

2.1 MVC 设计模式非常容易理解:

  • 模型(M)是数据的表述。它不是真正的数据,而是数据的接口。使用模型从数据库中获取数据时,
    无需知道底层数据库错综复杂的知识。模型通常还会为数据库提供一层抽象,这样同一个模型就能使
    用不同的数据库。
  • 视图(V)是你看到的界面。它是模型的表现层。在电脑中,视图是你在浏览器中看到的 Web 应用的
    页面,或者是桌面应用的 UI。视图还提供了收集用户输入的接口。
  • 控制器(C)控制模型和视图之间的信息流动。它通过程序逻辑判断通过模型从数据库中获取什么信
    息,以及把什么信息传给视图。它还通过视图从用户那里收集信息,并且实现业务逻辑:变更视图,
    或者通过模型修改数据,或者二者兼具。

2.2 MTV 开发模式:(Django 经常被称为 MTV 框架)

  • M 表示“模型”,即数据访问层。这一层包含所有与数据相关的功能:访问数据的方式、验证数据的方
    式、数据的行为、数据之间的关系。
  • T 表示“模板”,即表现层。这一层包含表现相关的决策:在网页或其他文档类型中如何显示某个东
    西。
  • V 表示“视图”,即业务逻辑层。这一层包含访问模型和选择合适模板的逻辑。你可以把视图看做模型
    和模板之间的桥梁。

三、视图和URL配置

3.1第一个 Django 驱动的页面:Hello World

  • 第一个视图:静态

    # 新建一个空文件,名为 views.py 。这个模块用于保存本章编写的视图。生成“Hello World”的视图很简单。下面是完整的视图函数,以及导入语句。把下述代码输入到 views.py 文件中.
    from django.http import HttpResponse
    
    def hello(request):
    	return HttpResponse("Hello world")  # 视图函数至少有一个参数
    
  • 第一个 URL 配置:

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

<!--正则表达式字符串前面的 'r' 字符。它的目的是告诉 Python,那是“原始字符串”,不要解释里面的反斜线.   Python 中的反斜线与正则表达式中的反斜线有冲突,因此在 Django 中定义正则表达式时最好使用原始字符
串。大多数 URL 模式都以脱字符号开头、以美元符号结尾,不过可以灵活使用,匹配复杂的 URL。
-->

3.2 正则表达式

符号匹配的内容
\d单个数字
. (点号)单个字符
[A-Z]A-Z(大写)之间的单个字母
[a-z]a-z(小写)之间的单个字母
[A-Za-z]a-z(不区分大小写)之间的单个字母
+一个或多个前述表达式(例如, \d+ 匹配一个或多个数字)
[ˆ/]+一个或多个字符,直到遇到斜线(不含)
?零个或一个前述表达式(例如, \d? 匹配零个或一个数字)
*零个或多个前述表达式(例如, \d* 匹配零个、一个或多个数字)

| {1,3} | 介于一个到三个之间(含)的前述表达式(例如, \d{1,3} 匹配一个、两个或三个

数字) |

3.3 关于404错误的简要说明

  • 现在,URL 配置只定义了一个 URL 模式,即处理 /hello/ URL 请求的那个。那么,如果请求其他 URL 会发生什么呢?为了查明,启动 Django 开发服务器,然后访问 http://127.0.0.1:8000/goodbye/ 。你应该会看到“Page not found”消息。Django 之所以显示这个消息,是因为 URL 配置中没有定义你请求的 URL。
  • 这些是敏感信息,只供 Web 开发者查看。线上网站不应该公开显示这些信息。鉴于此,“Page not
    found”页面仅当 Django 项目处于调试模式时才会显示。

3.4 Django 处理请求的过程

  • 运行 python manage.py runserver 命令时, manage.py 脚本在内层 mysite 目录中寻找名为 settings.py 的文件。这个文件中保存着当前 Django 项目的全部配置,各个配置的名称都是大写的,例如 TEMPLATE_DIRS 、DATABASES ,等等。其中最重要的设置是 ROOT_URLCONF 。它告诉 Django,网站的 URL 配置在哪个 Python 模块中。
    1. 请求 /hello/ 。
    1. Django 查看 ROOT_URLCONF 设置,找到根 URL 配置。
    1. Django 比较 URL 配置中的各个 URL 模式,找到与 /hello/ 匹配的那个。
    1. 如果找到匹配的模式,调用对应的视图函数。
    1. 视图函数返回一个 HttpResponse 对象
    1. Django 把 HttpResponse 对象转换成正确的 HTTP 响应,得到网页

3.5 URL 配置和松耦合

  • 松耦合是一种软件开发方式,其价值在于让组件可以互换。如果两部分代码之间是松耦合的,那么改动其中一部分对另一部分的影响很小,甚至没有影响。
  • 在 Django Web 应用中,URL 定义与所调用的视图函数之间是松耦合的,即某个功能使用哪个 URL 与视图函数的实现本身放在两个地方。
  • 例:
    • 以 current_datetime 视图为例。如果想把这个功能对应的 URL 从 /time/ 移到 /current-time/ ,只需修改URL 配置,视图则不用动。同样,对视图函数的逻辑所做的修改对开放这一功能的 URL 没有影响。此外,如果想在多个 URL 上开放当前日期功能,可以编辑 URL 配置,而无需改动视图代码。

3.6 视图:动态URL

  • 通配 URL 模式

  • 例:匹配1位或2位数字

    urlpatterns = [
    # ...
    url(r'^time/plus/\d{1,2}/$', hours_ahead),
    # ...
    ]
    

四、Django 模板

4.1 模板系统基础

  • Django 模板是一些文本字符串,作用是把文档的表现与数据区分开。模板定义一些占位符和基本的逻辑(模
    板标签),规定如何显示文档。通常,模板用于生成 HTML,不过 Django 模板可以生成任何基于文本的格
    式。
  • Django 模板能访问多个内置的标签和过滤器。

4.2 使用模板系统

  • 若想在 Python 代码中使用 Django 的模板系统,基本方式如下:

    • 1.以字符串形式提供原始的模板代码,创建 Template 对象。

      1. 在 Template 对象上调用 render() 方法,传入一系列变量(上下文)。返回的是完全渲染模板后得到
        的字符串,模板中的变量和模板标签已经根据上下文求出值了。
  • “块级标签”和“模板标签”是同一个事物。遇到下述各种情况时,模板系统都会抛出 TemplateSyntaxError :

    • 无效标签
    • 有效标签的无效参数
    • 无效过滤器
    • 有效过滤器的无效参数
    • 无效模板句法
    • 未关闭的标签(对需要结束标签的模板标签而言)
  • 例:

    from django.template import Context, Template
    
    t = Template('My name is {{ name }}.')   # 创建对象
    c = Context({'name': 'Stephane'})	## 渲染对象
    print(t.render(c))   # 'My name is Stephane.'	# 调用render()方法输出
    
  • Django 解析模板的速度相当快。在背后,解析的大部分工作通过调用一个正则表达式完成。这与基于 XML
    的模板系统有显著区别,XML 解析器会带来额外的消耗,从而导致渲染速度比 Django 的模板渲染引擎慢几
    个数量级。

  • 模板系统能优雅处理很多复杂的数据结构,例如列表、字典和自定义的对象。

  • 遍历Django模板中复杂数据结构的关键是点号(.)。点号可以访问字典的键、属性、方法或对象的索引。

  • 总结起来,模板系统遇到变量名中的点号时会按照下述顺序尝试查找:

    • 字典查找(如 foo[“bar”] )
    • 属性查找(如 foo.bar )
    • 方法调用(如 foo.bar() )
    • 列表索引查找(如 foo[2]
  • 例:假如我们把一个 Python 字典传给模板。若想通过键访问那个字典中的值,要使用点号:

    from django.template import Template, Context
    
    person = {'name': 'Sally', 'age': '43'}
    t = Template('{{ person.name }} is {{person.age}} years old.')
    c = Context({'person': person})
    print(t.render(c))  # 'Sally is 43 years old.
    

4.3 基本的模板标签和过滤器

  • 4.3.1标签:

    • if/else:

      {% if %} 计算变量的值,如果为真(即存在、不为空,不是假值),模板系统显示 {% if %}{% endif %}之间的内容。
      
      例如:
      1. {% if today_is_weekend %}
      	<p>Welcome to the weekend!</p>
      {% endif %}
      
      2. {% else %} 标签是可选的:
          {% if today_is_weekend %}
         		 <p>Welcome to the weekend!</p>
          {% else %}
        		 <p>Get back to work.</p>
          {% endif %}
          
      3. if 标签还可以有一个或多个 {% elif %} 子句:
          {% if athlete_list %}
          	Number of athletes: {{ athlete_list|length }}
          {% elif athlete_in_locker_room_list %}
        	     <p>Athletes should be out of the locker room soon! </p>
          {% elif ...
          ...
          {% else %}
         		 <p>No athletes. </p>
          {% endif %}
           
      4. {% if %} 支持使用 andornot 测试多个变量,或者取反指定的变量。例如:
          {% if athlete_list and coach_list %}
          	<p>Both athletes and coaches are available. </p>
          {% endif %}
          {% if not athlete_list %}
          	<p>There are no athletes. </p>
          {% endif %}
          {% if athlete_list or coach_list %}
         		<p>There are some athletes or some coaches. </p>
          {% endif %}
          {% if not athlete_list or coach_list %}
          	<p>There are no athletes or there are some coaches. </p>
          {% endif %}
          {% if athlete_list and not coach_list %}
          	<p>There are some athletes and absolutely no coaches. </p>
          {% endif %}
      5. 在同一个标签中可以同时使用 andor ,此时, and 的优先级比 or 高。例如:
      	{% if athlete_list and coach_list or cheerleader_list %}
      
      6. 如果需要通过括号指明优先级,应该使用嵌套的 if 标签。不支持使用括号控制操作的顺序。如果觉得有必要使用括号,可以考虑在模板外部执行逻辑,然后通过专用的模板变量传入结果.或者,直接使用嵌套的 {%
      if %} 标签,
      如下所示:
          {% if athlete_list %}
          {% if coach_list or cheerleader_list %}
          <p>We have athletes, and either coaches or cheerleaders! </p>
          {% endif %}
          {% endif %}
      
      7. 每个 {% if %} 都必须有配对的 {% endif %}
      
      
    • for:

      {% for %} 标签用于迭代序列中的各个元素。与 Python 的 for 语句一样,句法是 for X in Y ,其中 Y 是要迭代的序列, X 是单次循环中使用的变量。每次迭代时,模板系统会渲染 {% for %}{% endfor %} 之间的内容。
      例如,可以使用下述模板显示 athlete_list 变量中的运动员:
          <ul>
              {% for athlete in athlete_list %}
              	<li>{{ athlete.name }}</li>
              {% endfor %}
          </ul>
       
      
      在标签中添加 reversed ,反向迭代列表:
          {% for athlete in athlete_list reversed %}
          ...
          {% endfor %}
          
          
      {% for %} 标签可以嵌套:
          {% for athlete in athlete_list %}
          	<h1>{{ athlete.name }}</h1>
          	<ul>
                  {% for sport in athlete.sports_played %}
                 		 <li>{{ sport }}</li>
                  {% endfor %}
         		</ul>
          {% endfor %}
              
      如果需要迭代由列表构成的列表,可以把每个子列表中的值拆包到独立的变量中。
      比如说上下文中有一个包含 (x,y) 坐标点的列表,名为 points ,可以使用下述模板输出这些坐标点:
          {% for x, y in points %}
              <p>There is a point at {{ x }},{{ y }}</p>
          {% endfor %}
      
      
      如果需要访问字典中的元素,也可以使用这个标签。如果上下文中包含一个字典 data ,可以使用下述模板显
      示字典的键和值:
          {% for key, value in data.items %}
         		 {{ key }}: {{ value }}
          {% endfor %}
      
      
      通常,迭代列表之前要先检查列表的大小,如果为空,显示一些特殊的文字:
          {% if athlete_list %}
          	{% for athlete in athlete_list %}
          		<p>{{ athlete.name }}</p>
          	{% endfor %}
          {% else %}
          	<p>There are no athletes. Only computer programmers.</p>
          {% endif %}
      
      这种做法太常见了,因此 for 标签支持一个可选的 {% empty %} 子句,用于定义列表为空时显示的内容。下
      述示例与前一个等效:
          {% for athlete in athlete_list %}
          	<p>{{ athlete.name }}</p>
          {% empty %}
          	<p>There are no athletes. Only computer programmers.</p>
          {% endfor %}
          
      在循环结束之前,无法“跳出”。如果需要这么做,修改要迭代的变量,只包含需要迭代的值。
      同样,也没有“continue”语句,不能立即返回到循环的开头。
      
    • ifqual / ifnotequal:

      1. 模板经常需要比较两个值,在相等时显示一些内容。为此,Django 提供了 {% ifequal %} 标签。
      {% ifequal %} 标签比较两个值,如果相等,显示 {% ifequal %}{% endifequal %} 之间的内容。下述示例
          比较模板标签 user 和 currentuser :
          {% ifequal user currentuser %}
          	<h1>Welcome!</h1>
          {% endifequal %}
      2.{% if %} 一样, {% ifequal %} 标签支持可选的 {% else %} 子句:
          {% ifequal section 'sitenews' %}
          	<h1>Site News</h1>
          {% else %}
          	<h1>No News Here</h1>
          {% endifequal %}
      3. {% ifequal %} 的参数只能是模板变量、字符串、整数和小数。其他变量类型,例如 Python 字典、列表或布尔值,不能在 {% ifequal %} 中硬编码。
      4. {% ifnotequal %} 的作用与 ifequal 类似,不过它测试两个参数是否不相等。 ifnotequal 标签可以替换成 if标签和 != 运算符。
      
    • 注释:

      1. 注释使用 {# #} 标明:{# This is a comment #} 渲染模板时,不输出注释。使用这种句法编写的注释不能分成多行。这一限制有助于提升模板解析性能。
      2. 如果想编写多行注释,使用 {% comment %} 模板标签,如下所示:
          {% comment %}
          	This is a
          	multi-line comment.
          {% endcomment %}
      3. 注释标签不能嵌套。
      
  • 4.3.2 过滤器:

    • 模板过滤器是在显示变量之前调整变量值的简单方式。过滤器使用管道符号指定,如下所
      示:{{ name|lower }}
    • 下面是几个最重要的过滤器。
      • ddslashes :在反斜线、单引号和双引号前面添加一个反斜线。可用于转义字符串。例如: {{ val-
        ue|addslashes }} 。
      • date :根据参数中的格式字符串格式化 date 或 datetime 对象。例如: {{ pub_date|date:“F j, Y”
        }} 。
      • length :返回值的长度。对列表来说,返回元素的数量。对字符串来说,返回字符的数量。如果变量
        未定义,返回 0

4.4 模板加载机制

  • 为了从文件系统中加载模板,Django 提供了便利而强大的 API,力求去掉模板加载调用和模板自身的冗余。若想使用这个模板加载 API,首先要告诉框架模板的存储位置。这个位置在设置文件中配置,即前一章介绍ROOT_URLCONF 设置时提到的 settings.py 文件。打开 settings.py 文件,找到 TEMPLATES 设置。它的值是一个列表,分别针对各个模板引擎:

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [],
            'APP_DIRS': True,
            'OPTIONS': {
            # ... 一些选项 ...
        	},
        },
    ]
    
    • BACKEND 的值是一个点分 Python 路径,指向实现 Django 模板后端 API 的模板引擎类。内置的后端有 djan-go.template.backends.django.DjangoTemplates 和 django.template.backends.jinja2.Jinja2 。
    • 因为多数引擎从文件中加载模板,所以各个引擎的顶层配置包含三个通用的设置:
      • DIRS 定义一个目录列表,模板引擎按顺序在里面查找模板源文件。
      • APP_DIRS 设定是否在安装的应用中查找模板。按约定, APPS_DIRS 设为 True 时, DjangoTemplates 会在INSTALLED_APPS 中的各个应用里查找名为“templates”的子目录。这样,即使 DIRS 为空,模板引擎还能查找应用模板。
      • OPTIONS 是一些针对后端的设置。同一个后端可以配置具有不同选项的多个实例,然而这并不常见。此时,要为各个引擎定义唯一的 NAME 。

4.5 render

下面是使用 render() 重写的 current_datetime 视图:
from django.shortcuts import render
import datetime
def current_datetime(request):
	now = datetime.datetime.now()
	return render(request, 'current_datetime.html', {'current_date': now})

差别多么明显啊!下面详细说明这次改动:
• 不用再导入 get_template 、 Template 、 Context 或 HttpResponse 了,而要导入 django.shortcuts.ren-der 。 import datetime 不变。
• 在 current_datetime 函数中,仍然要计算 now ,不过加载模板、创建上下文、渲染模板和创建 HttpRe-
sponse 对象全由 render() 调用代替了。 render() 的返回值是一个 HttpResponse 对象,因此在视图中
可以直接返回那个值。render() 的第一个参数是请求对象,第二个参数是模板名称,第三个单数可选,是一个字段,用于创建传给模板的上下文。如果不指定第三个参数, render() 使用一个空字典。

4.6 include模板标签

  • 内置模板标签了: {% include %} 。这个标签的作用是引入另一个模板的内容。它的参数是要引入的模板的名称,可以是变量,也可以是硬编码的字符串(放在引号里,单双引号都行)。只要想在多个模板中使用相同的代码,就可以考虑使用 {% include %} ,去除重复。
  • include 标签的参数指定的模板在当前 Django 应用的“templates”目录中( APPS_DIR 为 True 时),或者在 DIRS 设置的目录中。引入的模板在引入它的模板的上下文中执行。
  • 如果 {% include %} 标签的参数指定的模板不存在,Django 会做下面两件事中的一件:
    • DEBUG 为 True 时,渲染 Django 错误页面,显示 TemplateDoesNotExist 异常。
    • DEBUG 为 False 时,静默,那个标签的位置什么也不显示。

4.7 模板继承

  • 继承经常使用下述三层结构:

    1. 创建 base.html 模板,定义网站的整体外观。这个模板的内容很少变化。

    2. 为网站中的各个“区域”创建 base_SECTION.html 模板(如 base_photos.html 和 base_forum.html )。这些模板扩展 base.html ,包含各区域专属的样式和设计。

    3. 为各种页面创建单独的模板,例如论坛页面或相册。这些模板扩展相应的区域模板。
      这种方式能最好地复用代码,而且便于为共享的区域添加内容,例如同一个区域通用的导航。

  • 下面是使用模板继承的一些指导方针:

    • 如果模板中有 {% extends %} ,必须是模板中的第一个标签。否则,模板继承不起作用。
    • 一般来说,基模板中的 {% block %} 标签越多越好。记住,子模板无需定义父模板中的全部块,因此
      可以为一些块定义合理的默认内容,只在子模板中覆盖需要的块。钩子多总是好的。
    • 如果发现要在多个模板中重复编写相同的代码,或许说明应该把那些代码移到父模板中的一个 {%
      block %} 标签里。
    • 如果需要从父模板中的块里获取内容,使用 {{ block.super }} ,这是一个“魔法”变量,提供父模板中
      渲染后的文本。向块中添加内容,而不是完全覆盖时就可以这么做。
    • 在同一个模板中不能为多个 {% block %} 标签定义相同的名称。之所以有这个限制,是因为 block 标
      签是双向的。即, block 标签不仅标识供填充的空位,还用于定义填充父模板中空位的内容。如果一
      个模板中有两个同名的块,那么父模板就不知道使用哪个块里的内容。
    • 传给 {% extends %} 的模板名称使用与 get_template() 相同的方法加载。即,模板在 DIRS 设置定义的
      目录中,或者在当前 Django 应用的“templates”目录里。
    • 多数情况下, {% extends %} 的参数是字符串,不过如果直到运行时才知道父模板的名称,也可以用变
      量。通过这一点可以做些动态判断。

4.8 Django的核心

  • Django 的核心:
    1. 表现与逻辑分离
    2. 避免重复
    3. 与 HTML 解耦
    4. XML 不好
    5. 不要求具备设计能力
    6. 透明处理空格
    7. 不重造一门编程语言
    8. 确保安全有保障
    9. 可扩展

五、Django模型

  • Django 非常适合构建数据库驱动型网站,它提供了简单而强大的工具,易于使用 Python 执行数据库查询。

5.1配置数据库

# 在 settings.py 文件中添加的初始配置:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': "django_test",
        'USER': "root",
        'PASSWORD': "123456",
        'HOST': "127.0.0.1",
    }
}

5.2 使用Python定义模型

  • Django 模型是使用 Python 代码对数据库中数据的描
    述,是数据的结构,等效于 SQL 中的 CREATE TABLE 语句,不过是用 Python 代码而非 SQL 表述的,而且不仅包含数据库列的定义。Django 通过模型在背后执行。

  • 使用 Python 代替 SQL 定义数据模型是不是多此一举?????????

    • Django 之所以这么做有几个原因:
      • 内省(introspection)有开销,而且不完美。为了提供便利的数据访问 API,Django 需要以某种方式知晓数据库布局,而这一需求有两种实现方式。第一种是使用 Python 明确描述数据,第二种是在运行时内省数据库,推知数据模型。第二种方式在一个地方存储表的元数据,看似更简单,其实会导致几个问题。首先,运行时内省数据库肯定有消耗。如果每次执行请求,或者只是初始化 Web 服务器都要内省数据库,那带来的消耗是无法接受的。(有些人觉得那点消耗不算事,然而 Django 的开发者可是在想方设法努力降低框架的消耗。)其次,有些数据库,尤其是旧版 MySQL,存储的元数据不足以完成内省。
      • Python 编写起来让人心情舒畅,而且使用 Python 编写所有代码无需频繁让大脑切换情境。
        在一个编程环境(思维)中待久了,有助于提升效率。在 SQL 和 Python 之间换来换去容易打断状
        态。
      • 把数据模型保存在代码中比保存在数据库中易于做版本控制,易于跟踪数据布局的变化。
      • SQL 对数据布局的元数据只有部分支持。例如,多数数据库系统没有提供专门表示电子邮件地址或
        URL 的数据类型。而 Django 模型有。高层级的数据结构有助于提升效率,让代码更便于复用。
      • 不同数据库平台使用的 SQL 不一致。分发 Web 应用程序时,更务实的做法是分发一个描述数据布局的 Python 模块,而不是分别针对MySQL、PostgreSQL 和 SQLite 的 CREATE TABLE 语句。
  • 缺点:模型的 Python 代码可能与数据库的真正结构脱节。如果修改了 Django 模型,还要在数据库中做相同的改动,让数据库与模型保持一致。

5.3 基本的数据访问

  • 添加模型的字符串表示形式

  • 插入和更新数据

  • 选择对象

    • 查找数据时,Django 使用的不是 SELECT * ,而是把所有字段列出来。
  • 过滤数据

    • 在 Django API 中,可以使用 filter() 方法过滤数据。
  • 检索单个对象

    • 上述 filter() 示例都返回一个查询集合(可视作列表)。有时,较之列表,更适合获取单个对象。此时应该使用 get() 方法:

    • 这个方法只返回一个对象,而不是一个列表(更确切地说是查询集合)。因此,得到多个对象的查询会导致异常。

    • 不返回对象的查询也导致异常。

  • 排序数据

    • 在 Django 应用程序中,你可能想根据特定值排序结果,例如按字母表顺序。为此,使用 order_by() 方法。

       Publisher.objects.order_by("address")
      
    • 如果想根据多个字段排序(以第一个字段排不出顺序时使用第二个字段),提供多个参数。

       Publisher.objects.order_by("state_province", "address")
      
    • 可以反向排序。方法是在字段名称前面加上“-”(减号):

      Publisher.objects.order_by("-name")
      
    • 虽然 order_by() 有一定的灵活性,但是每次都调用它相当繁琐。多数时候,我们始终使用同一个字段排序。此时,可以在模型中指定默认排序:

      class Meta:
      	ordering = ['name']
      
  • 链式查找

     # 过滤、排序一起做,链式捆绑
        Publisher.objects.filter(country="U.S.A.").order_by("-name")
    
  • 切片数据

    • 只查找固定数量的行。假如数据库中有几千个出版社记录,但是只想显示第一个。为
      此,可以使用 Python 标准的列表切片句法:

       Publisher.objects.order_by('name')[0]
      
    • 注意,不支持使用负数。

  • 在一个语句中更新多个对象

    • update() 方法有返回值,是一个整数,表示修改的记录数量
    • update() 方法可以在任何 QuerySet 对象上调用,这意味着可以通过它批量编辑多个记录。
  • 删除对象

    • 若想从数据库中删除一个对象,只需在对象上调用 delete() 方法

六、Django管理后台

6.1 使用Django管理后台

  • 启动开发服务器:
    启动开发服务器
  • 进入管理后台:

进入管理后台

6.2 把模型添加到Django管理后台中

  • 在admin.py下输入:
from django.contrib import admin
from .models import Publisher, Auther, Book
# Register your models here.
admin.site.register(Publisher)
admin.site.register(Auther)
admin.site.register(Book)

  • 页面显示加入:
    加入后台

6.3 把字段设为可选的

  • 在管理后台中操作一会之后,你可能会发现有个局限:编辑表单要求填写每个字段,而有时候某些字段需要是可选的。添加 blank=True 参数
  • 例:

字段设为可选

  • 这个参数告诉 Django,作者的电子邮件地址允许为空值。默认情况下,所有字段都设定了 blank=False ,意即不允许为空值。
  • 如果想让日期字段(如 DateField 、 TimeField 、 DateTimeField )或数值字段(如IntegerField 、 DecimalField 、 FloatField )接受空值,要同时添加 null=True 和 blank=True 。
  • 基于一些原因,Django 不会试图自动修改数据库模式,所以每次对模型做这种修改之后要自己动手执行 migrate 命令。

6.4 自定义字段的标注

  • 模型建立时增加:verbose_name=u"*****"

6.5 自定义ModelAdmin类

  • 目前我们所做的改动,添加 blank=True 、 null=True 和 verbose_name ,修改的其实都是模型层,只是碰巧管理后台有用到,还未涉及管理后台自身。除此之外,Django 管理后台也提供了丰富的选项,可以定制处理具体模型的方式。这些选项在 ModelAdmin类中,这些类包含特定管理后台实例中特定模型的配置。
  • 自定义修改列表
  • 自定义编辑表单

6.6 用户、分组和权限

  • 编辑用户和权限的权限也由权限系统控制。如果为某人赋予编辑用户的权限,他就能编辑自己的权限——这可能不是你想要的行为!给用户赋予编辑用户的权限,其实就相当于把他变成超级用户。
  • 用户还可以分组。一个分组中的所有成员都有那一组具有的全部权限。使用分组便于为多个用户赋予相同的权限。


  • 此文章根据书籍《精通Django》学习整理
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值