# Technical Documentation: PKUanonym/REKCARC-TSC-UHT

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/PKUanonym/REKCARC-TSC-UHT)

### Overview (README.md)

# 清华大学计算机系课程攻略

[](https://github.com/PKUanonym/REKCARC-TSC-UHT/watchers)
[](https://github.com/PKUanonym/REKCARC-TSC-UHT/stargazers)
[](https://github.com/PKUanonym/REKCARC-TSC-UHT/network/members)
[](https://github.com/PKUanonym/REKCARC-TSC-UHT/issues)

[](https://rekcarc-tsc-uht.readthedocs.io/en/latest/?badge=latest)

Web page: [REKCARC-TSC-UHT.readthedocs.io](https://REKCARC-TSC-UHT.readthedocs.io)

受[浙江大学相关项目](https://github.com/QSCTech/zju-icicles)启发，创立了本项目。

由于本仓库未启用 `git-lfs`，因此请不要上传单个超过 100M 的文件，否则 commit 无效。

若要下载单个文件夹，复制该文件夹的网址，粘贴入 [DownGit](https://minhaskamal.github.io/DownGit/#/home) 中，选择 download 即可。

如果您是清华大学学生，可移步 https://git.tsinghua.edu.cn/pkuanonym/REKCARC-TSC-UHT 进行查看并且能节约不少流量。

感谢对本项目贡献的同学：[Trinkle23897](https://github.com/trinkle23897)、[LJSthu](https://github.com/ljsthu)、[shyoshyo](https://github.com/shyoshyo)、[wuhaozhe](https://github.com/wuhaozhe)、[choumartin1234](https://github.com/choumartin1234)、[FztTony](https://github.com/FztTony/)、[VicaYang](https://github.com/VicaYang/)、[duzx16](https://github.com/duzx16/)、[zerotrac](https://github.com/zerotrac)、[gjz010](https://github.com/gjz010/)、[Recursion](https://github.com/RecursionSheep)、[linusboyle](https://github.com/linusboyle)、[namasikanam](https://github.com/namasikanam)、[JamesZhengYuyu](https://github.com/JamesZhengYuyu)、[zx1239856](https://github.com/zx1239856)、[yaoqs](https://github.com/yaoqs)、[heheda12345](https://github.com/heheda12345)、[MashPlant](https://github.com/MashPlant)、[lwpie](https://github.com/lwpie)、[cht33](https://github.com/cht33)、[chenweize1998](https://github.com/chenweize1998)、[will7101](https://github.com/will7101)、[UNIDY2002](https://github.com/UNIDY2002)、[yinhaoxuan](https://github.com/yinhaoxuan)、[zhengkw18](https://github.com/zhengkw18)、[rcy17](https://github.com/rcy17)、[prnake](https://github.com/prnake)、[qky18](https://github.com/qky18)、[JamesZFS](https://github.com/JamesZFS)、[Co1lin](https://github.com/Co1lin)、[3ToThe6](https://github.com/3ToThe6)、[c7w](https://github.com/c7w)、[zhaochenyang20](https://github.com/zhaochenyang20)、[Maple](https://github.com/Maple2004)、[yuxuan-z](https://github.com/yuxuan-z19) ……以及电脑前的您！

## 前言

继承自 [Trinkle23897 的项目](https://github.com/Trinkle23897/thu-cst-cracker)，删去了其中侵权内容。若还有任何侵权内容请在 issues 下指出，非常感谢。

## 目录

本项目收录的内容见 [收录内容](收录内容.md)

本项目大部分课程的参考书目见 [参考书目](参考书目.md)

## 贡献

**欢迎贡献！**

Issue、PR、纠错、资料、选课/考试攻略，完全欢迎！来自大家的关注、维护和贡献，才是让这个攻略继续存在的动力~

如果希望匿名贡献，可以 email 至此邮箱，注明 "REKCARC-TSC-UHT" 即可：PKUanonymous@qq.com

贡献方法见 [贡献方法](贡献方法.md)

## 许可

由贡献者编写部分的许可如下：

[(Creative Commons BY-SA 4.0) 知识共享署名 - 相同方式共享 4.0 国际许可协议](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)

其他部分的版权归属于其各自的作者。资料仅供参考，请自己判断其适用性。

## 附录

### 清华大学学生纪律处分管理规定实施细则

#### 第六章　学术不端、违反学习纪律的行为与处分

第二十一条 有下列违反课程学习纪律情形之一的，给予警告以上、留校察看以下处分：

（一）课程作业抄袭严重的；

（二）实验报告抄袭严重或者篡改实验数据的；

（三）期中、期末课程论文抄袭严重的；

（四）在课程学习过程中严重弄虚作假的其他情形。

---

### 大一小学期 Week 3 Python Docs Readme (`大一小学期/Week_3-Python/docs/readme.md`)

# 使用方法

## 文档目标

关于大一小学期一些形而上学的课程体验，请参考计算机系的[课程攻略文档](https://docs.qq.com/doc/DZGp6VW5kUVZUWWtD)。与之不同，本文档的目标非常具体。

此文档参考了自 2019 年到 2021 年三年 Python 小学期的要求，综合了暑培课程讲义、往年优秀作业与本人所参与的多个应用爬虫与数据分析的 SRT 工作汇编而成，**希望能够为一字班选修了 Python 小学期的同学提供有力的自学预习材料，也之后需要使用相关 Python 工具的同学提供支持。**

**与暑培内容重叠的部分，汇编者进行了修订，例如为网页爬虫提供了包括 Facebook，Twitter，Youtube 等高强度反爬网页的实例。如果你参与了暑培的部分内容，仍然建议你阅读经过汇编者补充的例子。**

**暑培课程之外，汇编者扩充更多相应的文档，主要是 BeatifulSoup4，Pandas，Matplotlib，做到了对于小学期内容的全覆盖与降维打击。**

## 内容概述

```shell
.
├── CodeReview.md
├── DS_tutorial.pdf
├── Python
│   ├── Numpy.ipynb
│   └── Python\ Advanced\ Topics.ipynb
├── backend
│   ├── Django.md
│   ├── Django_preparation.pdf
│   └── SQL.pdf
├── crawler
│   └── crawler.ipynb
├── readme.md
├── soup
│   ├── BeatifulSoup4.ipynb
│   ├── Pandas.ipynb
│   ├── Pandas_refined.ipynb
│   └── README.md
└── visualize
    ├── Matplotlib.ipynb
    └── README.md

5 directories, 15 files
```

1. Python 路径下：[Python 基础语法](https://docs.net9.org/languages/python/)与 Python 进阶（IPython）、Numpy
2. Crawler 路径下：crawler
3. soup 路径下：BeautifulSoup4 与 Pandas
4. backend 路径下：Django
5. visualize 路径下：Matplotlib

### Python 语法基础
Python入门与基础语法，见 [Python 基础语法](https://docs.net9.org/languages/python/)。

### Python 进阶
Python Advanced Topics 文档主要分享一些 Python 的进阶内容，介绍一些实用技能栈。该文档涵盖 IPython 这一实用的 Python的交互式接口，以及 tqdm, argparse, pathlib 等实用 Python 库。

### Numpy
Numpy(Numerical Python 的简称) 几乎是整个 Python 科学计算生态系统的核心，它提供了高效存储和操作密集数据缓存的接口。这部分文档介绍了 Numpy 的用法，尤其强调了以下重点内容：
+ Numpy 和 Python 的效率区别
+ Numpy 广播机制的规则
+ Numpy Fancy Index
+ 传统索引的视图问题

### crawler
Crawler 文档主要讲述 Python 爬虫的基本用法以及实操建议，主要内容包括：
+ 最基本的 HTTP 知识以及如何利用浏览器 inspect 功能；
+ 解爬取网页的两大方式：利用 requests 发送请求，以及利用 selenium 模拟浏览器访问网页；
+ 实际操作过程中的注意事项；
+ 以不同类型的网页为例讲解什么情况下具体应当使用哪种方式。

### BeautifulSoup4
BeautifulSoup4 可以帮助我们来处理请求获得的 HTML 页面中的数据，进行过滤、筛选、查找，是 Python 爬虫的重要工具。这部分文档以大量实例介绍了 BeautifulSoup4 的 API 和基本用法。

### Pandas
Pandas 是在 NumPy 基础上建立的新程序库，提供了一种高效的 DataFrame 数据结构。DataFrame 本质上是一种带行标签和列标签、支持相同类型数据和缺失值的多维数组。Pandas 文档重点介绍该包中 Series、DataFrame 和其他相关数据结构的高效使用方法。

### Django
Django 是一个由 Python 编写的一个开放源代码的 Web 应用框架。 使用 Django，只要很少的代码，Python 程序开发人员就可以轻松地完成一个正式网站所需要的大部分内容，并进一步开发出全功能的 Web 服务。
Django 部分教程旨在帮助大家：
+ 了解如何使用 Django 开发一个简单应用程序；
+ 了解前后端分离的开发模式，学习如何使用 Django 搭建一个后端；
+ 掌握一种在服务器上部署 Django 的方式 （Django + Nginx + uWSGI 部署）。

### Matplotlib
Matplotlib 是建立在 NumPy 数组基础上的多平台数据可视化程序库，这部分讲义将详细介绍使用 Python 的 Matplotlib 工具实现数据可视化的方法，涵盖线形图、散点图、直方图等，包含了大量实例。

## 额外注意

Pandas 与 Numpy 小学期并不必用，但是熟练的使用这两个工具会使得你的工作更加优雅。

## 下载

若要下载单个文件夹，复制该文件夹的网址，粘贴入 [DownGit](https://minhaskamal.github.io/DownGit/#/home) 中，选择 download 即可。

## 使用方法

文档全部由 markdown 与 Jupyter Notebook 写成。

### Local Jupyter

你可以将仓库 clone 到本地使用，顺带练习你的 Git 技能，毕竟 QT 开发不使用 Git 会极度痛苦。同时，关于 Jupyter Notebook 和 Python 基础环境的配置请参考[此链接](https://zhaochen20.notion.site/Python-2f9538e9f6024827b55abbeb48025b30)。

### Google Colab

你也可以使用 Google Colab 服务。

* 首先打开 Google Colab 为 Github 适配的界面。点击此[链接](https://colab.research.google.com/github/)，在对应位置输入该仓库链接：

  ```tex
  https://github.com/zhaochenyang20/Sino-Japanese-Relations-analysis
  ```
  
  然后 Enter，Colab 便会自动爬取该仓库的全部 ipynb 文件，并以列表形式显示在下面。点击对应文件右侧图标，便可以在新标签页打开该笔记本。
  
  

**注意事项**

1. 由于 Colab 自带的包的版本都很低，可能会出现部分 API 不兼容的情况。所以在使用下列笔记本时，建议在运行前先进行包的安装和更新，创建一个新的代码框，在对应的笔记本下运行如下指令即可。

    **Numpy.ipynb**

    ```bash
    ! pip install --upgrade numpy
    ```

    **BeatifulSoup4.ipynb**

    ```bash
    ! pip install --upgrade beautifulsoup4
    ```

    **Pandas.ipynb**

    ```bash
    ! pip install --upgrade pandas
    ! pip install --upgrade pandas-datareader
    ```

    **Matplotlib.ipynb**

    ```bash
    ! pip install --upgrade matplotlib
    ! pip install --upgrade basemap
    ! pip install basemap-data-hires
    ```

    在安装和更新完毕后，Colab 会输出如下 log：

    ```
    WARNING: The following packages were previously imported in this runtime:
      [···]
    You must restart the runtime in order to use newly installed versions.
    ```

    此时需要点击 log 下方的 `RESTART RUNTIME` 按钮即可将更新应用，接下来你便可以正常使用笔记本了。

  2. 如果你发现有部分系统命令（即在 Jupyter Notebook 中以 ! 开头）无法运行，请尝试点击界面中的“复制到云端硬盘”，在 Google Drive 中的副本中运行。

## 学习顺序

建议小学期选择了 Python 的同学，按照[基础语法](https://docs.net9.org/languages/python/)，IPython，Crawler，BeautifulSoup4，Matplotlib，DJango 的顺序进行学习。而其余两块内容 Numpy，Pandas 在小学期使用并不多，可以留作个人兴趣衍生。

## 补充说明

由于时间仓促，错误在所难免，如若文档出现问题，请及时在本仓库的 [Issue](https://github.com/zhaochenyang20/Sino-Japanese-Relations-analysis/issues) 界面提出。

# 为何而写

## 初起

暑假初期，我在处理暑培课程安排时，王导突然来找我，询问科协是否有课程指引方向的资料，类似 [docs9](https://docs.net9.org/) 的风格。

>  一字班同学在问有没有零字班好哥哥好姐姐帮忙介绍介绍大一小学期，包括新雅那边他们也准备搞…

作为技能文档的参与者，我不得不说，技能文档的初衷本身即是希望大家收获课程之外的一些能力，能够在课程当中使用到，而并不是刻意针对课程的。比如暑假之后我们会更新 Numpy，Pandas，IPython 的内容，这些内容绝非课程必须，只是在课程作业中使用会让你的作业更加优雅有效。更何况，科协的一大初衷也是希望能够带大家认知到除了课业之外还有广阔的计算机科学与技术的天地，而绝非课程的一亩三分地。

因此，暑假结束前科协恕难提供这方面的支持，毕竟即便是暑培现有资料的整合，也需要有非常多后续的整理修改工作。为了打造臻于完美，服务后人的技能文档，网络部相关的同学们用心可谓良苦。

我只能回复王导，关于小学期的课程指南，可以参考计算机系的[课程攻略文档](https://docs.qq.com/doc/DZGp6VW5kUVZUWWtD)。然而，类似 docs9 这类的文档，困难太大，恕难从命。

如此想来，这件事情的确与我无关。**作为技能文档组的编写者与计算机系课咨委的一员，我尽到了我的责任。而且我已经度过了许多让我体验不佳的课程，按说这辈子我不可能再受这些课程的苦，下辈子我也不会再学计算机这专业。一切都与我无关，不妨如同大多数麻木的人一样，事不关己，高高挂起。**

## 转折

然而，之后几天，我的良知却不免惴惴难安。

这真的是我渴望的生活吗？

参加课咨委的工作一整年了，我逐渐感知到，我之所以对于推动系内的课程改革有如此热忱，何尝不是不抱有薪火相传的初衷？

在我入学之前，就有杰哥等贵系的先辈们，积极地推动体系结构课程的改革，才能够让如今系内体系结构课程的体验有了大幅提升。之后，九字班学长学姐对小学期课程的提议和反馈得到了老师们的认可，才让零字班小学期压力控制在了合理的高压范围内，而非九字班所经历的魔鬼夏天。如果没有这些先辈学长学姐对于课改的探索，如果没有他们点亮了课改的火炬，我们现在又会经历怎样难堪的课程体验？

更何况，如果没有改革和参与改革的意识，每个人都安于现状，要么觉得事不关己高高挂起，要么觉得经历过的折磨一辈子不会有第二次，就选择对于任何意义的改革作壁上观，那么现在我们所生活的国家至今还是**大清**，绝非现在的中国。诚然我也激烈地批判着当下中国社会的种种弊病，然而我没谁也不愿意回到生产力落后，文化闭塞的清朝。社会改革促进了生产力的伟大进步，即便前人为了改革做出的牺牲已经让大多阅读到此处的人过上了衣食无忧的生活，然而我仍然坚信改革的火炬将会薪火相传。

于是乎，我再次想到了王导的问题。难道科协除了内容广泛的暑培外，暂时无法提供细致专业服务于小学期的指导，就不得不让同学们经历以往的前辈们在大一暑假曾经经历过的那些折磨吗？

绝不，至少我们还可以抱团自救。

>  **星星之火，可以燎原。**

虽然目前计算机系的部分课程质量仍然堪忧，**但是我们每提出一次课改意见，每贡献一次开源资料，都会为计算机系课程质量提升留下不可磨灭的贡献**。我们会帮助到之后的学弟学妹，更高年级学长学姐也会如此帮助我们。

## 尾声

于是乎，就有了你看到的此份文档。这份文档是我个人邀请三位一字班计算机系或者软院的同学们一同参考暑培讲义所编写的。基本涵盖了小学期 Python 课程的所有需求。在暑培课程之外，我们扩充了相应的文档和资料。从[语法基础](https://docs.net9.org/languages/python/)，到 IPython，Numpy，Pandas，BeautifulSoup4，Matplotlib，Django 等全部资料。

<img src="https://raw.githubusercontent.com/zhaochenyang20/zhaochenyang20.github.io/master/img/profile_7.jpg" style="zoom:15%;" />

# 致谢

## 汇编者

- [lurf21](https://github.com/lurf21)

- [QuentinHsuow](https://github.com/QuentinHsuow)

- [luohaowen2003](https://github.com/luohaowen2003)

## 暑培讲师

- [Eren Zhao](https://zhaochenyang20.github.io/about/)

- [c7w](https://github.com/c7w)
- [lambda](https://github.com/Btlmd)
- [ayf](https://github.com/ayf19)

## 打工仔

- [learning Rate](https://github.com/lr-tsinghua11)

---

### 大一小学期 Week 3 Python Docs Soup README (`大一小学期/Week_3-Python/docs/soup/README.md`)

# FAQ

Q：我在运行部分代码时出现了一些异常，怎么办？

A：Pandas 库的更新很快，所以该文档具有一定的时效性。**一切请以 Pandas 官方文档为准**，或者使用搜索引擎搜索错误输出。

Q：使用 `curl` 指令下载示例所需的数据时，出现问题怎么办？

A：由于网络原因，可以考虑直接访问对应网站下载。如果数据确实已经下载，可以在 jupyter notebook 中使用 `pwd` 命令查看一下当前目录是否正确。

---

### 大一小学期 Week 3 Python Docs Visualize README (`大一小学期/Week_3-Python/docs/visualize/README.md`)

## 针对运行这份笔记中的代码时可能出现的一些问题，我们给出以下参考解决方案

1. 需要使用 curl 指令下载 csv 格式数据文件来运行示例时，如果 curl 出现问题，可以直接向 pd.read_csv() 传入下载链接，直接从网络上加载数据；

2. 在 Basemap 部分，如果遇到绘制的地图不符合预期的情况，可以尝试运行以下代码：

```
conda install -c conda-forge basemap-data-hires
```

3.对于例子“Surface Temperature Data”，需要下载的数据文件较大，如果用curl指令下载过程中出现问题，可以尝试直接用浏览器访问[美国宇航局戈达德太空研究所](http://data.giss.nasa.gov/)(NASA’s Goddard Institute for Space Studies)的网站，并下载所需数据文件至工作文件夹。

4. 对于其它可能出现的异常情况，可以使用 Ipython 查阅 documents，自行调整 API 尝试解决。

---

### 大一小学期 Week 3 Python Docs CodeReview (`大一小学期/Week_3-Python/docs/CodeReview.md`)

# 审核者须知

参考技能文档的[编写者须知](https://docs.net9.org/notes/editor/)，除此之外：

1. 将翻译稿中出现的类似于“书中第 xx 章”的字样删去。
2. 所以示例代码必须自己完全运行，避免因为 API 过于老旧无法使用。

------

# 重要事项

**正确使用标点符号**

+ 正确使用**全角**标点符号与**半角**标点符号。汉语请使用全角符号，英语请使用半角符号。
+ 请在每句话的末尾添加**句号**。
+ 正确使用**括号**。括号在句中表示对句中前一个元素的解释说明，如 `语法糖（英语：Syntactic sugar）`。括号在句外表示对前面整个句子的解释说明。
+ 正确使用**分号**，可以使得行文结构更加清晰。

**正确进行中文排版**

+ **中英文之间、中文和数字之间需要增加空格，数字和单位之间不需要增加空格。**
+ 行文中正文与超链接之间需要增加空格。
+ 全角字符和其他字符之间不加空格。
+ **专有名词使用正确的大小写。如使用缩写，则该缩写应已成为业界标准。**

**推荐的代码风格**

+ 变量使用驼峰命名法、下划线命名法等均可，但需要尽量保证同一篇文档内命名风格统一。
+ 下列代码风格惯例以 C++ 语言为例：
    + 大括号换行与不换行均可，但需要保证同一篇文档内格式统一。不换行时，其与左侧的右括号之间应当有一个空格。
    + 关键字 `if`、`for` 等与后续左括号之间应当有一个空格。
    + 运算符 `+`、`-` 等与左右操作数之间应当各有一个空格，运算符 `.`、`->` 两侧均不应当有空格，逗号 `,` 左侧不应当有空格而右侧应当有空格。
    + 行内注释起始标记 `//` 与注释文字间应当有一个空格。
    + 使用 2 个空格或者 4 个空格进行缩进均可，但需要保证同一篇文档内统一。

---

### 大一小学期 Week 3 Python Docs Backend Django (`大一小学期/Week_3-Python/docs/backend/Django.md`)

# Django 与后端

Django 是一个由 Python 编写的一个开放源代码的 Web 应用框架。
使用 Django，只要很少的代码，Python 的程序开发人员就可以轻松地完成一个正式网站所需要的大部分内容，并进一步开发出全功能的 Web 服务。 Django 本身基于 MVC 模型，即 Model（模型）+ View（视图）+ Controller（控制器）设计模式，MVC 模式使后续对程序的修改和扩展简化，并且使程序某一部分的重复利用成为可能。
本教程旨在帮助大家入门 Django，并掌握一些后端开发的基本知识，具体来说，希望帮助大家达成以下目标：

+ 了解如何使用 Django 开发一个简单应用程序；
+ 了解前后端分离的开发模式，学习如何使用 Django 搭建一个后端；
+ 掌握一种在服务器上部署 Django 的方式 （Django + Nginx + uWSGI 部署）。

## 前置准备
请参考 lambda 学长暑培授课中的[课前准备文档](./Django_preparation.pdf)。
通过此命令可以检查你是否已经安装 Django 及 Django 版本。

```bash
python -m django --version
```

## 创建一个简单的投票应用
> 需要注意的是Django的[文档](https://docs.djangoproject.com/zh-hans/4.0/)本身编写得相当清晰完备，以下内容大部分摘自该文档，因此若有不清晰之处，敬请查阅[文档](https://docs.djangoproject.com/zh-hans/4.0/)。

### 新建项目
如果这是你第一次使用 Django 的话，你需要一些初始化设置。也就是说，你需要用一些自动生成的代码配置一个 Django project —— 即一个 Django 项目实例需要的设置项集合，包括数据库配置、Django 配置和应用程序配置。
打开命令行，cd 到一个你想放置你代码的目录，然后运行以下命令：
```
django-admin startproject mysite
```
这行代码将会在当前目录下创建一个 `mysite` 目录。在其中，你会看到以下文件树：
```
mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        asgi.py
        wsgi.py
```
这些目录和文件的用处是：

+ 最外层的 `mysite/` 根目录只是你项目的容器， 根目录名称对 Django 没有影响，你可以将它重命名为任何你喜欢的名称。
+ `manage.py`: 一个让你用各种方式管理 Django 项目的命令行工具。许多如运行临时服务器、生成 migration， 迁移数据库结构等操作都可以通过 `manage.py` 进行。我们也可以在 `manage.py` 中运行自定义命令。
+ 里面一层的 `mysite/` 目录包含你的项目，它是一个纯 Python 包。它的名字就是当你引用它内部任何东西时需要用到的 Python 包名。 (比如 `mysite.urls`).
+ `mysite/__init__.py`：一个空文件，告诉 Python 这个目录应该被认为是一个 Python 包。
+ `mysite/settings.py`：Django 项目的配置文件。
+ `mysite/urls.py`：Django 项目的 URL 声明，就像你网站的“目录”。
+ `mysite/asgi.py`：作为你的项目的运行在 ASGI 兼容的 Web 服务器上的入口。
+ `mysite/wsgi.py`：作为你的项目的运行在 WSGI 兼容的 Web 服务器上的入口。

### 简易服务器
在 mysite 目录下，运行以下代码：
```bash
python manage.py runserver
```
即可启动一个临时服务器（只能用于开发测试，而不应当用于生产环境）。通过浏览器访问 http://127.0.0.1:8000/ （Djaongo 默认监听 127.0.0.1:8000）你将看到一个“祝贺”页面，证明你已经成功创建了项目。这个简易服务器之后可用于开发中的测试。

### 新建应用
应用和项目是多对多的关系。一个应用通常用于完成一个相对独立的功能，可以安装于不同的项目中; 而一个项目也可以包含多个应用。
下面我们来演示创建应用：
```bash
python manage.py startapp <app_name>
```
例如，在manage.py所在目录下运行以下代码：
```bash
python manage.py startapp polls
```
将创建一个名为 polls 的应用。
在 Django 中，每一个应用都是一个 Python 包，并且遵循着相同的约定。Django 自带一个工具，可以帮你生成应用的基础目录结构。例如，你可以观察一下刚刚创建的投票应用的文件目录。

### 创建视图
视图可以根据不同的请求给出 HTTP 响应，我们来为 polls 创建个简单的视图。例如我们在 `polls/views.py` 中输入：
```python
from django.http import HttpResponse
def index(request):
    return HttpResponse("Hello, world. You're at the polls index.")
```
这时，调用 index 将返回一个 HTTP 响应，内容为 Hello, world. You're at the polls index. 。

### 创建路由

路由配置告诉 Django 哪些的 URL 应该被分配给哪些视图。我们来为我们刚才编写的 index 试图配置路由。

首先配置应用一级的路由，在 polls 目录下新建 `urls.py` ，输入以下内容：
```python
from django.urls import path
from . import views
urlpatterns = [
    path('hello', views.index, name='index'),
]
```
然后配置项目一级的路由:
```python
from django.urls import include, path
urlpatterns = [
    path('polls/', include('polls.urls'))
]
```
这里需要注意 include 函数可以引用其他位置的 URL 配置，并将截断匹配的部分，将剩余部分分发给后续的 URL 配置进行匹配。
这时我们运行临时服务器测试访问这个页面：

```bash
python manage.py runserver
```
访问
```
http://localhost:8000/polls/hello
```
预期观察到的响应为 Hello, world. You're at the polls index.

我们回过头来看看我们的请求是如何被分配到 index 的。
当我们访问 http://localhost:8000/polls/hello ，Django 哪来进行匹配的部分是 `polls/hello` 首先在项目一级匹配，匹配到了 `polls/` ，于是 `polls/` 被去除，剩下 hello 子串到应用 polls 的 `urls.py` 中进行匹配。hello 子串又匹配到了视图 index 。此时 HTTP 请求作为第一个参数传给了 index 函数进行处理。index 函数处理这个请求后，应当返回一个 HttpResponse 对象，Django 会将这个对象对应的 HTTP 响应传递给客户端。

### 使用数据库
接下来我们来演示如何使用 Django 的 ORM 模型来操作数据库。Django 支持多种数据库。默认情况下，Django使用 SQLite3 作为数据库。这种情形无需配置。我们也可以使用 MySQL 作为数据库。在此处我们以 MySQL 为例。如果你对 MySQL 不熟悉，可以参看[暑培文档](./SQL.pdf)中的 MySQL 部分。

#### settings.py

在使用数据库前，我们需要先了解 `settings.py` 中进行一些常用设置：
> DEBUG
决定项目是在调试状态还是在生产环境。
**永远不要在 DEBUG 开启的情况下将网站部署到生产中**。DEBUG 开启时，产生错误会返回详细的错误报告，其中包含许多敏感信息，不宜在生产环境中泄露。DEBUG 关闭时，产生的错误仅有简略说明。
ALLOWED_HOSTS
> 允许访问的域名列表，其他域名访问将直接被 ban，响应为 HTTP 400.
INSTALLED_APPS
> 表示该项目使用了哪些应用。Django会为在其中列出的应用进行注册。会进行启动配置、跟踪 migration 等数据库信息。
DATABASES
> 表示使用何种数据库，以及使用数据库时的配置，如主机、端口、用户名密码等等。

#### 配置 MySQL 数据库
下面按照 Django 文档中的示例，演示为项目配置 MySQL 数据库。
首先安装 mysqlclient：
```bash
pip install mysqlclient
```
然后在恰当位置创建 MySQL 数据库的配置文件 `my.cnf `，输入你的数据库配置:
```
[client]
host = 服务器地址
database = 所选数据库
user = 用户名
password = 密码
port = 端口
default-character-set = 字符集，这里推荐 utf8mb4
```
然后，在 `settings.py` 进行如下修改:
```python
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'OPTIONS': {
            'read_default_file': '<my.cnf 的地址>', 
        },
    }
}
```
如果填入的地址为相对路径，那么将会是相对运行 `manage.py` 时的工作目录。

#### 建立模型
模型对应于数据库中的表，可以用来设计和访问数据库的结构。我们为 polls 应用建立模型。编辑 `models.py` 输入以下内容：
```python
from django.db import models
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.FloatField('date published')

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
```
上面的代码建立了两个模型，对应于数据库中的两张表。模型是 models.Model 的子类，模型的字段是 models.Field 的实例。模型的每个字段对应于数据库中的一个字段。
在建立模型后我们需要让 Django 在数据库中建立这些模型，或对模型的修改做出对应数据库结构的调整。因此我们需要首先注册这一应用。在 `settings.py` 中，将我们的应用添加到 INSTALLED_APPS 中。

```python
INSTALLED_APPS = [
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
```
这时应用 polls 就被添加到了我们的 Django 项目中了。

我们运行:
```bash
python manage.py makemigrations polls
Migrations for 'polls':
  polls\migrations\0001_initial.py
    - Create model Question
    - Create model Choice
```
此时 Django 会检测我们对应用 polls 的模型做了哪些修改，在将这些修改操作汇总到一个 Python 文 件中。
我们可以看到在 `polls/migrations` 目录中出现了一个 `0001_initial.py` 文件。我们通常无需阅读 migrations 中的文件。

接下来我们需要将修改操作应用到数据库：
```bash
python manage.py migrate
```
此时你对模型的修改将会被执行到数据库中。注意到修改包含了大量其他模型的操作，这是因为我们在 INSTALLED_APPS 中配置了许多应用，而这些应用的模型尚未建立。

对于应用更改时具体执行的 SQL 语句，我们可以使用:
```bash
python manage.py sqlmigrate polls 0001
```
来查看 migration 0001 对应的 SQL 语句。
从这些语句中我们发现 Django 默认为我们建立主键，并添加了外键约束。

**总结起来，修改模型并应用修改分为 3 步: **
+ 编辑 `models.py` 文件，改变模型。
+ 运行 `python manage.py makemigrations` 为模型的改变生成迁移文件。 
+ 运行 `python manage.py migrate` 来应用数据库迁移。

#### 一些常见的模型定义：

以下面这段代码为例展示一些模型构建的常用内容：
```python
# 创建枚举选项：
class Role(models.TextChoices):
    MEMBER = "member"
    DEV = "dev"
    QA = "qa"
    SYS = "sys"
    SUPERMASTER = "supermaster"

class PendingModifyPasswordEmail(models.Model): 
    # 指定主键
    id = models.BigAutoField(primary_key=True) 
    # 唯一
    hash1 = models.CharField(max_length=100, unique=True) 
    # 枚举类型
    role = models.CharField(max_length=12, choices=Role.choices) 
    # 默认函数
    createdAt = models.FloatField(default=getTime.get_timestamp)
    class Meta: 
    # 索引
    indexes = [
        models.Index(fields=["hash1", "role"]),
        models.Index(fields=["createdAt"]),
    ]
    # 联合唯一
    unique_together = ["hash1", "createdAt"]
```

#### 模型 API
我们可以利用模型 API 完成对数据的操作。下面我们在 Django Shell 中演示一些常见模型 API 的使用方法。当然，我们通常会在视图函数中使用这些 API，使用交互式方式只是为了便于演示。

首先启动 Django Shell：
```bash
python manage.py shell
```

在 Django Shell 中:
```
/* Detailed source-code truncated for AI context efficiency. */
```

在这里我们发现对象的显示不太方便，我们可以配置相应模型的 `__str__` 方法来自定义模型的显示内容：
为 Question 和 Choice 分别定义以下方法即可：

```python
def __str__(self):
        return f"{self.question_text} @ {self.pub_date}"
```
```python
def __str__(self):
        return f"{self.choice_text} [{self.votes}]"
```

然后重启 Django Shell，再次尝试查询:
```django
>>> from polls.models import *

# 自定义显示:
>>> Choice.objects.all()
<QuerySet [<Choice: A [0]>, <Choice: B [0]>, <Choice: C [0]>]>
>>> Question.objects.all()
<QuerySet [<Question: Is it a question? @ 1658422997.1246326>,
           <Question: Is it a question? @ 1658423046.8407936>,
           <Question: Is it another question? @ 1658423054.8635635>]>
```

接下来我们看看如何修改对象。和创建类似地，有两种方法:
```django
# save object: 修改特定对象
>>> ch = Choice.objects.get(pk=2) >>> ch.votes = 114514
>>> ch.save()
# update: 修改整个 Query Set
>>> Choice.objects.filter(id=3).update(votes=255) 1
# 查看修改效果
>>> Choice.objects.all()
<QuerySet [<Choice: A [0]>, <Choice: B [114514]>, <Choice: C [255]>]>
```

然后是一些基本的查询方法（注意使用双下划线进行级联的写法）:
```
/* Detailed source-code truncated for AI context efficiency. */
```

我们可以使用 `.query` 来查看 QuerySet 对应的 SQL 语句:
```django
>>> print(
...     Choice.objects.filter(
...         Q(question__id=2) & (~Q(choice_text__in=["A", "B"]) | Q(id=1))
...     ).query
... )
SELECT `polls_choice`.`id`, `polls_choice`.`question_id`, `polls_choice`.`choice_text`, `polls_choice`.`votes` FROM `polls_choice` WHERE(`polls_choice`.`question_id` = 2 AND (NOT (`polls_choice`.`choice_text` IN (A, B)) OR `polls_choice`.`id` = 1))
```

在查询复杂(或者开发者对 ORM 接口不熟悉)的情况下也可以直接裸写 SQL。由于不同 SQL 实现的版 本的差异，这样的代码并不想 ORM 那样具有较为良好的迁移性。
```django
>>> Choice.objects.raw("SELECT * FROM ...")
```

当然，并不是说如果使用 ORM 就一定能保证代码在不同数据库之间无损转换。例如 Postgre SQL 的 DISTINCT ON 接口就会导致一部分代码迁移到 MySQL 后不能使用。而如果要把一部分数据从一种数据 库迁移到另一种数据库，这通常也十分令人头大。

> 这里介绍了创建应用程序的基本方法，如果想要体验创建一个完整应用程序的过程，请参看[文档](https://docs.djangoproject.com/zh-hans/4.0/intro/tutorial01/)

## 前后端分离的开发模式

对于 Web 应用来说，可以将其简单视为 2 部分：
+ 前端：用户可以看到并与之交互的部分。
+ 后端：用户看不到，但承担着一些如数据存储、计算等等功能的部分。
对于前后端的互动，也可以简单分成两种模式：
+ 服务端渲染：服务端将用户看到的界面计算好，然后整体以 HTML 的形式返回。
+ 用户端渲染：服务端先将不含数据，但包含交互逻辑的前端传给客户端。客户端需要时向服务端请求数据，利用请求的数据来完成页面的渲染。

对于当前日趋复杂的 Web 应用来说，前后端分离的是一种日趋流行的趋势
+ 前后端分离应用的页面在交互的过程中，只传递了数据，而不是渲染好的整个视图，更加高效、灵活。
+ 后端人员与前端人员的工作解耦，两者只需要通过约定的 API 进行协作，不需要代码的直接交互，不会出现后端开发里面嵌入了前端代码这种难以维护情形。

可能还需要说明的是，在学会前后端分离后，并不一定所有的任务都一定要上前后端分离，有些非常简单的任务用耦合的架构大概就能做的非常好了。

### Templates & Forms
Django 对前后端耦合的开发模式有深入的支持，但模板和表单在前后端分离的开发中使用较少，不是本节的重点，在这里附上文档链接，供有兴趣的同学查阅。
+ 模板：https://docs.djangoproject.com/zh-hans/4.0/intro/tutorial03/
+ 表单：Generic View:https://docs.djangoproject.com/zh-hans/4.0/intro/tutorial04/
以下介绍使用 Djaongo 搭建纯后端的基本操作。

### 使用 Django 收发请求
作为一个后端来说，最为常规的操作可能读取请求参数和收发各种 JSON。

#### GET
仍以上述投票程序为例，假设我们希望实现这样一个接口，请求 `/polls/questions/` 返回 id=2 的问题文本、创建时间和所有选项，此时我们可以写如下一个视图函数:
```python
from django.http import HttpRequest, JsonResponse
from .models import *
from django.forms.models import model_to_dict

def question_detail(req: HttpRequest, qid: int):
    res = Question.objects.filter(id=qid).first()
    if res:
        return JsonResponse({
            "code": 0,
            "data": {
                **model_to_dict(res),
                "choices": [
                    model_to_dict(ch, exclude=["question"])
                    for ch in res.choice_set.all()
                ]
            }
        })
    else:
        return JsonResponse({
            "code": -1
        }, status=404)
```
其接受一个 HttpRequest 对象和被查询问题的 id ，使用 model_to_dict 将问题对象转换为 dict ， 再将问题对应所有的 Choice 转化也都转化为 dict 。最后将这个 dict 与 list 的复合物封装成 JSON 返回。

然后我们在 `polls/urls.py` 中为其配置路由。
```python
from django.urls import path
from . import views

urlpatterns = [
    path('question/<int:qid>', views.question_detail),
]
```

这里我们遇到一种新的路由格式。其在匹配到这一项后相当于调用了:
```django
views.question_detail(request=<HttpRequest object>, qid=<int:qid>)
```
qid 被作为关键字参数传给了 views.question_detail。

更多 URL Pattern 写法详见官方文档。
这时我们可以使用 Postman 对该接口进行验证和调试。
此外，对于 GET 请求中附带的参数，可以使用 req.GET 获取，例如添加上 `print(req.GET)` 即可获取 GET 请求的参数。

#### POST
我们考虑另一种情形，就是给指定问题的指定选项投票，类似于以下场景：
```json
// 请求 
{
    "qid": 2,
    "cid": 0 
}
// 响应 
{
    "code": 0,
    "choices": [...]
}
```

这时我们可以撰写类似这样的一个视图函数:
```python
def vote(req: HttpRequest):
    info = json.loads(req.body)
    try:
        qid = info["qid"]
        cid = info["cid"]
        ch = Choice.objects.get(pk=cid)
        if ch.question.id != qid:
            raise ValueError("Mismatched question and choice pair")
        ch.votes += 1
        ch.save()
        return JsonResponse({
            "code": 0,
            "choices": [
                model_to_dict(ch, exclude=["question"])
                for ch in Choice.objects.filter(question__id=qid)
            ]
        }) 
    except:
        if settings.DEBUG:
            raise
        return JsonResponse({
            "code": -1
        }, status=400)
```

然后添加一条路由:
```
path('vote', views.vote)
```

这时在 Postman 中查询，发现响应为 HTTP 403，原因是缺少 CSRF token（出于安全性考虑，Djaongo 默认要求 POST 请求携带 CSRF token，已表明该请求来自被授权的表单）。
在这里我们不妨直接添加装饰器关闭 CSRF token 检查。

```python
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def vote(req: HttpRequest):
    ...
```

有时我们希望指定请求的方法，可以使用:
```python
from django.views.decorators.http import require_http_methods as method
@method(["GET"])
def leaderboard(req: HttpRequest):
...
```
此时若收到的请求不是 GET 请求，则会返回一个错误。

## 部署 Django
后端编写好后，我们希望将其部署在服务器上，这样我们就可以通过服务器对外网的端口访问页面。
在此使用一种典型部署：使用 uWSGI 来代理 Django，再用反向代理 Nginx 连接 uWSGI，将其代理到外网。

### uWSGI
现在我们准备将 Django 部署到服务器上了。 
先将文件转移到服务器的某个文件夹中（如果你使用 PyCharm，则可以使用其内置的“部署”工具来进行转移），这里以暑培服务器为例，选择 `/home/train/site`。
在前置准备中，我们已经安装了 conda 并配置好了虚拟环境，确认了 Nginx 可以正常启动。
进入网站目录，启动虚拟环境，用以下代码，我们可以将 uWSGI 代理到 10001 端口：

```bash
uwsgi --http :10001 --module mysite.wsgi
```
其中 module 参数指出相应的 Python 模块。 
现在我们就可以从外网通过端口来访问这个 Django 应用了。

如果提示无法连接到 MySQL 服务器，则可在 `mysite/__init__.py` 中加入以下代码：
```python
import pymysql

pymysql.install_as_MySQLdb()
```

我们也可以使用配置文件来进行操作:
```
[uwsgi]
socket = :9999
chdir = /home/train/site module = mysite.wsgi master = true
processes = 9
threads = 9
vacuum = true
```

然后
```bash
uwsgi --ini u.ini
```

其中，如果直接使用 uWSGI 应该指定 http，否则指定 socket。
关于 Django + uWSGI 的更多配置，详见[如何用 uWSGI 托管 Django](https://docs.djangoproject.com/zh-hans/4.0/howto/deployment/wsgi/uwsgi/)。

### Nginx

我们可以先来个极简配置，代理一波 uWSGI(更细致的配置可以参考其官方文档)。
在 `/etc/nginx/sites-enabled/default` 中加入以下内容:
（uWSGI 将 Django 代理到了 127.0.0.1 的 9999 端口，Nginx 又将其代理到了 10002 端口）

```
server{
listen 10002;
server_name 59.66.131.240;
location / {
        include uwsgi_params;
        uwsgi_pass 127.0.0.1:9999;
        uwsgi_read_timeout 15;
  }
}
```
此时在命令行中执行：
```bash
sudo service nginx start
```
此时就可以在外网中访问之前搭建的网页了。


另外也可以使用 Nginx 配置静态文件的代理。形如：
```
server {
listen 10001;
server_name 59.66.131.240;
location / {
        root /home/nana/build;
        index index.html;
}
```

有时我们会遇到 Nginx 没有权限读取内容的问题，表现为 HTTP 403，此时可以给相关文件加上权限， chown，甚至可以直接找到 `/etc/nginx/nginx.conf` ，将其首部的 user 改为 root。

#### 查找错误
在配置 Nginx 时，常用
```bash
sudo nginx -t
sudo cat /var/log/nginx/error.log
```
定位错误(前者检查配置文件中的错误，后者展示错误日志）。
例如配置文件编写有误，或端口被占用等问题，就可以被这两个命令发现。

## 扩展阅读
还有一些比较常用的主题，篇幅有限，以下是链接：
单元测试 UnitTest: https://docs.djangoproject.com/zh-hans/4.0/intro/tutorial05/
Middle Ware: https://docs.djangoproject.com/zh-hans/4.0/topics/http/middleware/ 
Command: https://docs.djangoproject.com/zh-hans/4.0/howto/custom-management-comm ands/
Django REST Framework：https://www.django-rest-framework.org

---

### 大一小学期 Week 3 Python Exam 2016 Docs Contents (`大一小学期/Week_3-Python/exam/2016/docs/contents.txt`)

=============================
Django documentation contents
=============================

.. toctree::
    :hidden:

    index

.. toctree::
    :maxdepth: 3

    intro/index
    topics/index
    howto/index
    faq/index
    ref/index
    misc/index
    glossary
    releases/index
    internals/index

Indices, glossary and tables
============================

* :ref:`genindex`
* :ref:`modindex`
* :doc:`glossary`

---

### 大一小学期 Week 3 Python Exam 2016 Docs Glossary (`大一小学期/Week_3-Python/exam/2016/docs/glossary.txt`)

========
Glossary
========

.. glossary::

    concrete model
        A non-abstract (:attr:`abstract=False
        <django.db.models.Options.abstract>`) model.

    field
        An attribute on a :term:`model`; a given field usually maps directly to
        a single database column.

        See :doc:`/topics/db/models`.

    generic view
        A higher-order :term:`view` function that provides an abstract/generic
        implementation of a common idiom or pattern found in view development.

        See :doc:`/topics/class-based-views/index`.

    model
        Models store your application's data.

        See :doc:`/topics/db/models`.

    MTV
        "Model-template-view"; a software pattern, similar in style to MVC, but
        a better description of the way Django does things.

        See :ref:`the FAQ entry <faq-mtv>`.

    MVC
        `Model-view-controller`__; a software pattern. Django :ref:`follows MVC
        to some extent <faq-mtv>`.

        __ https://en.wikipedia.org/wiki/Model-view-controller

    project
        A Python package -- i.e. a directory of code -- that contains all the
        settings for an instance of Django. This would include database
        configuration, Django-specific options and application-specific
        settings.

    property
        Also known as "managed attributes", and a feature of Python since
        version 2.2. This is a neat way to implement attributes whose usage
        resembles attribute access, but whose implementation uses method calls.

        See :class:`property`.

    queryset
        An object representing some set of rows to be fetched from the database.

        See :doc:`/topics/db/queries`.

    slug
        A short label for something, containing only letters, numbers,
        underscores or hyphens. They're generally used in URLs. For
        example, in a typical blog entry URL:

        .. parsed-literal::

            https://www.djangoproject.com/weblog/2008/apr/12/**spring**/

        the last bit (``spring``) is the slug.

    template
        A chunk of text that acts as formatting for representing data. A
        template helps to abstract the presentation of data from the data
        itself.

        See :doc:`/topics/templates`.

    view
        A function responsible for rendering a page.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Index (`大一小学期/Week_3-Python/exam/2016/docs/index.txt`)

====================
Django documentation
====================

.. rubric:: Everything you need to know about Django.

Getting help
============

Having trouble? We'd like to help!

* Try the :doc:`FAQ <faq/index>` -- it's got answers to many common questions.

* Looking for specific information? Try the :ref:`genindex`, :ref:`modindex` or
  the :doc:`detailed table of contents <contents>`.

* Search for information in the archives of the |django-users| mailing list, or
  `post a question`_.

* Ask a question in the `#django IRC channel`_, or search the `IRC logs`_ to see
  if it's been asked before.

* Report bugs with Django in our `ticket tracker`_.

.. _archives: https://groups.google.com/group/django-users/
.. _post a question: https://groups.google.com/d/forum/django-users
.. _#django IRC channel: irc://irc.freenode.net/django
.. _IRC logs: http://django-irc-logs.com/
.. _ticket tracker: https://code.djangoproject.com/

How the documentation is organized
==================================

Django has a lot of documentation. A high-level overview of how it's organized
will help you know where to look for certain things:

* :doc:`Tutorials </intro/index>` take you by the hand through a series of
  steps to create a Web application. Start here if you're new to Django or Web
  application development. Also look at the ":ref:`index-first-steps`" below.

* :doc:`Topic guides </topics/index>` discuss key topics and concepts at a
  fairly high level and provide useful background information and explanation.

* :doc:`Reference guides </ref/index>` contain technical reference for APIs and
  other aspects of Django's machinery. They describe how it works and how to
  use it but assume that you have a basic understanding of key concepts.

* :doc:`How-to guides </howto/index>` are recipes. They guide you through the
  steps involved in addressing key problems and use-cases. They are more
  advanced than tutorials and assume some knowledge of how Django works.

.. _index-first-steps:

First steps
===========

Are you new to Django or to programming? This is the place to start!

* **From scratch:**
  :doc:`Overview <intro/overview>` |
  :doc:`Installation <intro/install>`

* **Tutorial:**
  :doc:`Part 1: Requests and responses <intro/tutorial01>` |
  :doc:`Part 2: Models and the admin site <intro/tutorial02>` |
  :doc:`Part 3: Views and templates <intro/tutorial03>` |
  :doc:`Part 4: Forms and generic views <intro/tutorial04>` |
  :doc:`Part 5: Testing <intro/tutorial05>` |
  :doc:`Part 6: Static files <intro/tutorial06>` |
  :doc:`Part 7: Customizing the admin site <intro/tutorial07>`

* **Advanced Tutorials:**
  :doc:`How to write reusable apps <intro/reusable-apps>` |
  :doc:`Writing your first patch for Django <intro/contributing>`

The model layer
===============

Django provides an abstraction layer (the "models") for structuring and
manipulating the data of your Web application. Learn more about it below:

* **Models:**
  :doc:`Introduction to models <topics/db/models>` |
  :doc:`Field types <ref/models/fields>` |
  :doc:`Meta options <ref/models/options>` |
  :doc:`Model class <ref/models/class>`

* **QuerySets:**
  :doc:`Executing queries <topics/db/queries>` |
  :doc:`QuerySet method reference <ref/models/querysets>` |
  :doc:`Lookup expressions <ref/models/lookups>`

* **Model instances:**
  :doc:`Instance methods <ref/models/instances>` |
  :doc:`Accessing related objects <ref/models/relations>`

* **Migrations:**
  :doc:`Introduction to Migrations<topics/migrations>` |
  :doc:`Operations reference <ref/migration-operations>` |
  :doc:`SchemaEditor <ref/schema-editor>` |
  :doc:`Writing migrations <howto/writing-migrations>`

* **Advanced:**
  :doc:`Managers <topics/db/managers>` |
  :doc:`Raw SQL <topics/db/sql>` |
  :doc:`Transactions <topics/db/transactions>` |
  :doc:`Aggregation <topics/db/aggregation>` |
  :doc:`Search <topics/db/search>` |
  :doc:`Custom fields <howto/custom-model-fields>` |
  :doc:`Multiple databases <topics/db/multi-db>` |
  :doc:`Custom lookups <howto/custom-lookups>` |
  :doc:`Query Expressions <ref/models/expressions>` |
  :doc:`Conditional Expressions <ref/models/conditional-expressions>` |
  :doc:`Database Functions <ref/models/database-functions>`

* **Other:**
  :doc:`Supported databases <ref/databases>` |
  :doc:`Legacy databases <howto/legacy-databases>` |
  :doc:`Providing initial data <howto/initial-data>` |
  :doc:`Optimize database access <topics/db/optimization>` |
  :doc:`PostgreSQL specific features <ref/contrib/postgres/index>`

The view layer
==============

Django has the concept of "views" to encapsulate the logic responsible for
processing a user's request and for returning the response. Find all you need
to know about views via the links below:

* **The basics:**
  :doc:`URLconfs <topics/http/urls>` |
  :doc:`View functions <topics/http/views>` |
  :doc:`Shortcuts <topics/http/shortcuts>` |
  :doc:`Decorators <topics/http/decorators>`

* **Reference:**
  :doc:`Built-in Views <ref/views>` |
  :doc:`Request/response objects <ref/request-response>` |
  :doc:`TemplateResponse objects <ref/template-response>`

* **File uploads:**
  :doc:`Overview <topics/http/file-uploads>` |
  :doc:`File objects <ref/files/file>` |
  :doc:`Storage API <ref/files/storage>` |
  :doc:`Managing files <topics/files>` |
  :doc:`Custom storage <howto/custom-file-storage>`

* **Class-based views:**
  :doc:`Overview <topics/class-based-views/index>` |
  :doc:`Built-in display views <topics/class-based-views/generic-display>` |
  :doc:`Built-in editing views <topics/class-based-views/generic-editing>` |
  :doc:`Using mixins <topics/class-based-views/mixins>` |
  :doc:`API reference <ref/class-based-views/index>` |
  :doc:`Flattened index<ref/class-based-views/flattened-index>`

* **Advanced:**
  :doc:`Generating CSV <howto/outputting-csv>` |
  :doc:`Generating PDF <howto/outputting-pdf>`

* **Middleware:**
  :doc:`Overview <topics/http/middleware>` |
  :doc:`Built-in middleware classes <ref/middleware>`

The template layer
==================

The template layer provides a designer-friendly syntax for rendering the
information to be presented to the user. Learn how this syntax can be used by
designers and how it can be extended by programmers:

* **The basics:**
  :doc:`Overview <topics/templates>`

* **For designers:**
  :doc:`Language overview <ref/templates/language>` |
  :doc:`Built-in tags and filters <ref/templates/builtins>` |
  :doc:`Humanization <ref/contrib/humanize>`

* **For programmers:**
  :doc:`Template API <ref/templates/api>` |
  :doc:`Custom tags and filters <howto/custom-template-tags>`

Forms
=====

Django provides a rich framework to facilitate the creation of forms and the
manipulation of form data.

* **The basics:**
  :doc:`Overview <topics/forms/index>` |
  :doc:`Form API <ref/forms/api>` |
  :doc:`Built-in fields <ref/forms/fields>` |
  :doc:`Built-in widgets <ref/forms/widgets>`

* **Advanced:**
  :doc:`Forms for models <topics/forms/modelforms>` |
  :doc:`Integrating media <topics/forms/media>` |
  :doc:`Formsets <topics/forms/formsets>` |
  :doc:`Customizing validation <ref/forms/validation>`

The development process
=======================

Learn about the various components and tools to help you in the development and
testing of Django applications:

* **Settings:**
  :doc:`Overview <topics/settings>` |
  :doc:`Full list of settings <ref/settings>`

* **Applications:**
  :doc:`Overview <ref/applications>`

* **Exceptions:**
  :doc:`Overview <ref/exceptions>`

* **django-admin and manage.py:**
  :doc:`Overview <ref/django-admin>` |
  :doc:`Adding custom commands <howto/custom-management-commands>`

* **Testing:**
  :doc:`Introduction <topics/testing/index>` |
  :doc:`Writing and running tests <topics/testing/overview>` |
  :doc:`Included testing tools <topics/testing/tools>` |
  :doc:`Advanced topics <topics/testing/advanced>`

* **Deployment:**
  :doc:`Overview <howto/deployment/index>` |
  :doc:`WSGI servers <howto/deployment/wsgi/index>` |
  :doc:`Deploying static files <howto/static-files/deployment>` |
  :doc:`Tracking code errors by email <howto/error-reporting>`

The admin
=========

Find all you need to know about the automated admin interface, one of Django's
most popular features:

* :doc:`Admin site <ref/contrib/admin/index>`
* :doc:`Admin actions <ref/contrib/admin/actions>`
* :doc:`Admin documentation generator<ref/contrib/admin/admindocs>`

Security
========

Security is a topic of paramount importance in the development of Web
applications and Django provides multiple protection tools and mechanisms:

* :doc:`Security overview <topics/security>`
* :doc:`Disclosed security issues in Django <releases/security>`
* :doc:`Clickjacking protection <ref/clickjacking>`
* :doc:`Cross Site Request Forgery protection <ref/csrf>`
* :doc:`Cryptographic signing <topics/signing>`
* :ref:`Security Middleware <security-middleware>`

Internationalization and localization
=====================================

Django offers a robust internationalization and localization framework to
assist you in the development of applications for multiple languages and world
regions:

* :doc:`Overview <topics/i18n/index>` |
  :doc:`Internationalization <topics/i18n/translation>` |
  :ref:`Localization <how-to-create-language-files>` |
  :doc:`Localized Web UI formatting and form input <topics/i18n/formatting>`
* :doc:`Time zones </topics/i18n/timezones>`

Performance and optimization
============================

There are a variety of techniques and tools that can help get your code running
more efficiently - faster, and using fewer system resources.

* :doc:`Performance and optimization overview <topics/performance>`

Python compatibility
====================

Django aims to be compatible with multiple different flavors and versions of
Python:

* :doc:`Jython support <howto/jython>`
* :doc:`Python 3 compatibility <topics/python3>`

Geographic framework
====================

:doc:`GeoDjango <ref/contrib/gis/index>` intends to be a world-class geographic
Web framework. Its goal is to make it as easy as possible to build GIS Web
applications and harness the power of spatially enabled data.

Common Web application tools
============================

Django offers multiple tools commonly needed in the development of Web
applications:

* **Authentication:**
  :doc:`Overview <topics/auth/index>` |
  :doc:`Using the authentication system <topics/auth/default>` |
  :doc:`Password management <topics/auth/passwords>` |
  :doc:`Customizing authentication <topics/auth/customizing>` |
  :doc:`API Reference <ref/contrib/auth>`
* :doc:`Caching <topics/cache>`
* :doc:`Logging <topics/logging>`
* :doc:`Sending emails <topics/email>`
* :doc:`Syndication feeds (RSS/Atom) <ref/contrib/syndication>`
* :doc:`Pagination <topics/pagination>`
* :doc:`Messages framework <ref/contrib/messages>`
* :doc:`Serialization <topics/serialization>`
* :doc:`Sessions <topics/http/sessions>`
* :doc:`Sitemaps <ref/contrib/sitemaps>`
* :doc:`Static files management <ref/contrib/staticfiles>`
* :doc:`Data validation <ref/validators>`

Other core functionalities
==========================

Learn about some other core functionalities of the Django framework:

* :doc:`Conditional content processing <topics/conditional-view-processing>`
* :doc:`Content types and generic relations <ref/contrib/contenttypes>`
* :doc:`Flatpages <ref/contrib/flatpages>`
* :doc:`Redirects <ref/contrib/redirects>`
* :doc:`Signals <topics/signals>`
* :doc:`System check framework <topics/checks>`
* :doc:`The sites framework <ref/contrib/sites>`
* :doc:`Unicode in Django <ref/unicode>`

The Django open-source project
==============================

Learn about the development process for the Django project itself and about how
you can contribute:

* **Community:**
  :doc:`How to get involved <internals/contributing/index>` |
  :doc:`The release process <internals/release-process>` |
  :doc:`Team organization <internals/organization>` |
  :doc:`Meet the team <internals/team>` |
  :doc:`Current roles <internals/roles>` |
  :doc:`The Django source code repository <internals/git>` |
  :doc:`Security policies <internals/security>` |
  :doc:`Mailing lists <internals/mailing-lists>`

* **Design philosophies:**
  :doc:`Overview <misc/design-philosophies>`

* **Documentation:**
  :doc:`About this documentation <internals/contributing/writing-documentation>`

* **Third-party distributions:**
  :doc:`Overview <misc/distributions>`

* **Django over time:**
  :doc:`API stability <misc/api-stability>` |
  :doc:`Release notes and upgrading instructions <releases/index>` |
  :doc:`Deprecation Timeline <internals/deprecation>`

---

### 大一小学期 Week 3 Python Exam 2016 Docs Faq Admin (`大一小学期/Week_3-Python/exam/2016/docs/faq/admin.txt`)

==============
FAQ: The admin
==============

I can't log in. When I enter a valid username and password, it just brings up the login page again, with no error messages.
===========================================================================================================================

The login cookie isn't being set correctly, because the domain of the cookie
sent out by Django doesn't match the domain in your browser. Try setting the
:setting:`SESSION_COOKIE_DOMAIN` setting to match your domain. For example, if
you're going to "https://www.example.com/admin/" in your browser, set
``SESSION_COOKIE_DOMAIN = 'www.example.com'``.

I can't log in. When I enter a valid username and password, it brings up the login page again, with a "Please enter a correct username and password" error.
===========================================================================================================================================================

If you're sure your username and password are correct, make sure your user
account has :attr:`~django.contrib.auth.models.User.is_active` and
:attr:`~django.contrib.auth.models.User.is_staff` set to True. The admin site
only allows access to users with those two fields both set to True.

How do I automatically set a field's value to the user who last edited the object in the admin?
===============================================================================================

The :class:`~django.contrib.admin.ModelAdmin` class provides customization hooks
that allow you to transform an object as it saved, using details from the
request. By extracting the current user from the request, and customizing the
:meth:`~django.contrib.admin.ModelAdmin.save_model` hook, you can update an
object to reflect the user that edited it. See :ref:`the documentation on
ModelAdmin methods <model-admin-methods>` for an example.

How do I limit admin access so that objects can only be edited by the users who created them?
=============================================================================================

The :class:`~django.contrib.admin.ModelAdmin` class also provides customization
hooks that allow you to control the visibility and editability of objects in the
admin. Using the same trick of extracting the user from the request, the
:meth:`~django.contrib.admin.ModelAdmin.get_queryset` and
:meth:`~django.contrib.admin.ModelAdmin.has_change_permission` can be used to
control the visibility and editability of objects in the admin.

My admin-site CSS and images showed up fine using the development server, but they're not displaying when using mod_wsgi.
=========================================================================================================================

See :ref:`serving the admin files <serving-the-admin-files>`
in the "How to use Django with mod_wsgi" documentation.

My "list_filter" contains a ManyToManyField, but the filter doesn't display.
============================================================================

Django won't bother displaying the filter for a ``ManyToManyField`` if there
are fewer than two related objects.

For example, if your :attr:`~django.contrib.admin.ModelAdmin.list_filter`
includes :doc:`sites </ref/contrib/sites>`, and there's only one site in your
database, it won't display a "Site" filter. In that case, filtering by site
would be meaningless.

Some objects aren't appearing in the admin.
===========================================

Inconsistent row counts may be caused by missing foreign key values or a
foreign key field incorrectly set to :attr:`null=False
<django.db.models.Field.null>`. If you have a record with a
:class:`~django.db.models.ForeignKey` pointing to a non-existent object and
that foreign key is included is
:attr:`~django.contrib.admin.ModelAdmin.list_display`, the record will not be
shown in the admin changelist because the Django model is declaring an
integrity constraint that is not implemented at the database level.

How can I customize the functionality of the admin interface?
=============================================================

You've got several options. If you want to piggyback on top of an add/change
form that Django automatically generates, you can attach arbitrary JavaScript
modules to the page via the model's class Admin :ref:`js parameter
<modeladmin-asset-definitions>`. That parameter is a list of URLs, as strings,
pointing to JavaScript modules that will be included within the admin form via
a ``<script>`` tag.

If you want more flexibility than simply tweaking the auto-generated forms,
feel free to write custom views for the admin. The admin is powered by Django
itself, and you can write custom views that hook into the authentication
system, check permissions and do whatever else they need to do.

If you want to customize the look-and-feel of the admin interface, read the
next question.

The dynamically-generated admin site is ugly! How can I change it?
==================================================================

We like it, but if you don't agree, you can modify the admin site's
presentation by editing the CSS stylesheet and/or associated image files. The
site is built using semantic HTML and plenty of CSS hooks, so any changes you'd
like to make should be possible by editing the stylesheet.

What browsers are supported for using the admin?
================================================

The admin provides a fully-functional experience to `YUI's A-grade`_ browsers,
with the notable exception of IE6, which is not supported.

There *may* be minor stylistic differences between supported browsers—for
example, some browsers may not support rounded corners. These are considered
acceptable variations in rendering.

.. _YUI's A-grade: https://github.com/yui/yui3/wiki/Graded-Browser-Support

---

### 大一小学期 Week 3 Python Exam 2016 Docs Faq Contributing (`大一小学期/Week_3-Python/exam/2016/docs/faq/contributing.txt`)

======================
FAQ: Contributing code
======================

How can I get started contributing code to Django?
==================================================

Thanks for asking! We've written an entire document devoted to this question.
It's titled :doc:`Contributing to Django </internals/contributing/index>`.

I submitted a bug fix in the ticket system several weeks ago. Why are you ignoring my patch?
============================================================================================

Don't worry: We're not ignoring you!

It's important to understand there is a difference between "a ticket is being
ignored" and "a ticket has not been attended to yet." Django's ticket system
contains hundreds of open tickets, of various degrees of impact on end-user
functionality, and Django's developers have to review and prioritize.

On top of that: the people who work on Django are all volunteers. As a result,
the amount of time that we have to work on the framework is limited and will
vary from week to week depending on our spare time. If we're busy, we may not
be able to spend as much time on Django as we might want.

The best way to make sure tickets do not get hung up on the way to checkin is
to make it dead easy, even for someone who may not be intimately familiar with
that area of the code, to understand the problem and verify the fix:

* Are there clear instructions on how to reproduce the bug? If this
  touches a dependency (such as Pillow), a contrib module, or a specific
  database, are those instructions clear enough even for someone not
  familiar with it?

* If there are several patches attached to the ticket, is it clear what
  each one does, which ones can be ignored and which matter?

* Does the patch include a unit test? If not, is there a very clear
  explanation why not? A test expresses succinctly what the problem is,
  and shows that the patch actually fixes it.

If your patch stands no chance of inclusion in Django, we won't ignore it --
we'll just close the ticket. So if your ticket is still open, it doesn't mean
we're ignoring you; it just means we haven't had time to look at it yet.

When and how might I remind the core team of a patch I care about?
==================================================================

A polite, well-timed message to the mailing list is one way to get attention.
To determine the right time, you need to keep an eye on the schedule. If you
post your message when the core developers are trying to hit a feature
deadline or manage a planning phase, you're not going to get the sort of
attention you require. However, if you draw attention to a ticket when the
core developers are paying particular attention to bugs -- just before a bug
fixing sprint, or in the lead up to a beta release for example -- you're much
more likely to get a productive response.

Gentle IRC reminders can also work -- again, strategically timed if possible.
During a bug sprint would be a very good time, for example.

Another way to get traction is to pull several related tickets together. When
the core developers sit down to fix a bug in an area they haven't touched for
a while, it can take a few minutes to remember all the fine details of how
that area of code works. If you collect several minor bug fixes together into
a similarly themed group, you make an attractive target, as the cost of coming
up to speed on an area of code can be spread over multiple tickets.

Please refrain from emailing core developers personally, or repeatedly raising
the same issue over and over. This sort of behavior will not gain you any
additional attention -- certainly not the attention that you need in order to
get your pet bug addressed.

But I've reminded you several times and you keep ignoring my patch!
===================================================================

Seriously - we're not ignoring you. If your patch stands no chance of
inclusion in Django, we'll close the ticket. For all the other tickets, we
need to prioritize our efforts, which means that some tickets will be
addressed before others.

One of the criteria that is used to prioritize bug fixes is the number of
people that will likely be affected by a given bug. Bugs that have the
potential to affect many people will generally get priority over those that
are edge cases.

Another reason that bugs might be ignored for while is if the bug is a symptom
of a larger problem. While we can spend time writing, testing and applying
lots of little patches, sometimes the right solution is to rebuild. If a
rebuild or refactor of a particular component has been proposed or is
underway, you may find that bugs affecting that component will not get as much
attention. Again, this is just a matter of prioritizing scarce resources. By
concentrating on the rebuild, we can close all the little bugs at once, and
hopefully prevent other little bugs from appearing in the future.

Whatever the reason, please keep in mind that while you may hit a particular
bug regularly, it doesn't necessarily follow that every single Django user
will hit the same bug. Different users use Django in different ways, stressing
different parts of the code under different conditions. When we evaluate the
relative priorities, we are generally trying to consider the needs of the
entire community, not just the severity for one particular user. This doesn't
mean that we think your problem is unimportant -- just that in the limited
time we have available, we will always err on the side of making 10 people
happy rather than making 1 person happy.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Faq General (`大一小学期/Week_3-Python/exam/2016/docs/faq/general.txt`)

============
FAQ: General
============

Why does this project exist?
============================

Django grew from a very practical need: World Online, a newspaper Web
operation, is responsible for building intensive Web applications on journalism
deadlines. In the fast-paced newsroom, World Online often has only a matter of
hours to take a complicated Web application from concept to public launch.

At the same time, the World Online Web developers have consistently been
perfectionists when it comes to following best practices of Web development.

In fall 2003, the World Online developers (Adrian Holovaty and Simon Willison)
ditched PHP and began using Python to develop its websites. As they built
intensive, richly interactive sites such as Lawrence.com, they began to extract
a generic Web development framework that let them build Web applications more
and more quickly. They tweaked this framework constantly, adding improvements
over two years.

In summer 2005, World Online decided to open-source the resulting software,
Django. Django would not be possible without a whole host of open-source
projects -- `Apache`_, `Python`_, and `PostgreSQL`_ to name a few -- and we're
thrilled to be able to give something back to the open-source community.

.. _Apache: https://httpd.apache.org/
.. _Python: https://www.python.org/
.. _PostgreSQL: http://www.postgresql.org/

What does "Django" mean, and how do you pronounce it?
=====================================================

Django is named after `Django Reinhardt`_, a jazz manouche guitarist from the 1930s
to early 1950s. To this day, he's considered one of the best guitarists of all time.

Listen to his music. You'll like it.

Django is pronounced **JANG**-oh. Rhymes with FANG-oh. The "D" is silent.

We've also recorded an `audio clip of the pronunciation`_.

.. _Django Reinhardt: https://en.wikipedia.org/wiki/Django_Reinhardt
.. _audio clip of the pronunciation: http://red-bean.com/~adrian/django_pronunciation.mp3

Is Django stable?
=================

Yes, it's quite stable. Companies like Disqus, Instagram, Pinterest, and
Mozilla have been using Django for many years. Sites built on Django have
weathered traffic spikes of over 50 thousand hits per second.

Does Django scale?
==================

Yes. Compared to development time, hardware is cheap, and so Django is
designed to take advantage of as much hardware as you can throw at it.

Django uses a "shared-nothing" architecture, which means you can add hardware
at any level -- database servers, caching servers or Web/application servers.

The framework cleanly separates components such as its database layer and
application layer. And it ships with a simple-yet-powerful
:doc:`cache framework </topics/cache>`.

Who's behind this?
==================

Django was originally developed at World Online, the Web department of a
newspaper in Lawrence, Kansas, USA. Django's now run by an international
:doc:`team of volunteers </internals/team>`.

Which sites use Django?
=======================

`DjangoSites.org`_ features a constantly growing list of Django-powered sites.

.. _DjangoSites.org: https://djangosites.org

.. _faq-mtv:

Django appears to be a MVC framework, but you call the Controller the "view", and the View the "template". How come you don't use the standard names?
=====================================================================================================================================================

Well, the standard names are debatable.

In our interpretation of MVC, the "view" describes the data that gets presented
to the user. It's not necessarily *how* the data *looks*, but *which* data is
presented. The view describes *which data you see*, not *how you see it.* It's
a subtle distinction.

So, in our case, a "view" is the Python callback function for a particular URL,
because that callback function describes which data is presented.

Furthermore, it's sensible to separate content from presentation -- which is
where templates come in. In Django, a "view" describes which data is presented,
but a view normally delegates to a template, which describes *how* the data is
presented.

Where does the "controller" fit in, then? In Django's case, it's probably the
framework itself: the machinery that sends a request to the appropriate view,
according to the Django URL configuration.

If you're hungry for acronyms, you might say that Django is a "MTV" framework
-- that is, "model", "template", and "view." That breakdown makes much more
sense.

At the end of the day, of course, it comes down to getting stuff done. And,
regardless of how things are named, Django gets stuff done in a way that's most
logical to us.

<Framework X> does <feature Y> -- why doesn't Django?
=====================================================

We're well aware that there are other awesome Web frameworks out there, and
we're not averse to borrowing ideas where appropriate. However, Django was
developed precisely because we were unhappy with the status quo, so please be
aware that "because <Framework X> does it" is not going to be sufficient reason
to add a given feature to Django.

Why did you write all of Django from scratch, instead of using other Python libraries?
======================================================================================

When Django was originally written a couple of years ago, Adrian and Simon
spent quite a bit of time exploring the various Python Web frameworks
available.

In our opinion, none of them were completely up to snuff.

We're picky. You might even call us perfectionists. (With deadlines.)

Over time, we stumbled across open-source libraries that did things we'd
already implemented. It was reassuring to see other people solving similar
problems in similar ways, but it was too late to integrate outside code: We'd
already written, tested and implemented our own framework bits in several
production settings -- and our own code met our needs delightfully.

In most cases, however, we found that existing frameworks/tools inevitably had
some sort of fundamental, fatal flaw that made us squeamish. No tool fit our
philosophies 100%.

Like we said: We're picky.

We've documented our philosophies on the
:doc:`design philosophies page </misc/design-philosophies>`.

Is Django a content-management-system (CMS)?
============================================

No, Django is not a CMS, or any sort of "turnkey product" in and of itself.
It's a Web framework; it's a programming tool that lets you build websites.

For example, it doesn't make much sense to compare Django to something like
Drupal_, because Django is something you use to *create* things like Drupal.

Of course, Django's automatic admin site is fantastic and timesaving -- but
the admin site is one module of Django the framework. Furthermore, although
Django has special conveniences for building "CMS-y" apps, that doesn't mean
it's not just as appropriate for building "non-CMS-y" apps (whatever that
means!).

.. _Drupal: https://drupal.org/

How can I download the Django documentation to read it offline?
===============================================================

The Django docs are available in the ``docs`` directory of each Django tarball
release. These docs are in reST (reStructuredText) format, and each text file
corresponds to a Web page on the official Django site.

Because the documentation is `stored in revision control`_, you can browse
documentation changes just like you can browse code changes.

Technically, the docs on Django's site are generated from the latest development
versions of those reST documents, so the docs on the Django site may offer more
information than the docs that come with the latest Django release.

.. _stored in revision control: https://github.com/django/django/tree/master/docs/

Where can I find Django developers for hire?
============================================

Consult our `developers for hire page`_ for a list of Django developers who
would be happy to help you.

You might also be interested in posting a job to https://djangogigs.com/ .
If you want to find Django-capable people in your local area, try
https://people.djangoproject.com/ .

.. _developers for hire page: https://code.djangoproject.com/wiki/DevelopersForHire

How do I cite Django?
=====================

It's difficult to give an official citation format, for two reasons: citation
formats can vary wildly between publications, and citation standards for
software are still a matter of some debate.

For example, `APA style`_,  would dictate something like::

    Django (Version 1.5) [Computer Software]. (2013). Retrieved from https://djangoproject.com.

However, the only true guide is what your publisher will accept, so get a copy
of those guidelines and fill in the gaps as best you can.

If your referencing style guide requires a publisher name, use "Django Software
Foundation".

If you need a publishing location, use "Lawrence, Kansas".

If you need a web address, use https://djangoproject.com.

If you need a name, just use "Django", without any tagline.

If you need a publication date, use the year of release of the version you're
referencing (e.g., 2013 for v1.5)

.. _APA style: http://www.apastyle.org

---

### 大一小学期 Week 3 Python Exam 2016 Docs Faq Help (`大一小学期/Week_3-Python/exam/2016/docs/faq/help.txt`)

=================
FAQ: Getting Help
=================

How do I do X? Why doesn't Y work? Where can I go to get help?
==============================================================

If this FAQ doesn't contain an answer to your question, you might want to
try the |django-users| mailing list. Feel free to ask any question related
to installing, using, or debugging Django.

If you prefer IRC, the `#django IRC channel`_ on the Freenode IRC network is an
active community of helpful individuals who may be able to solve your problem.

.. _`#django IRC channel`: irc://irc.freenode.net/django

.. _message-does-not-appear-on-django-users:

Why hasn't my message appeared on django-users?
===============================================

|django-users| has a lot of subscribers. This is good for the community, as
it means many people are available to contribute answers to questions.
Unfortunately, it also means that |django-users| is an attractive target for
spammers.

In order to combat the spam problem, when you join the |django-users| mailing
list, we manually moderate the first message you send to the list. This means
that spammers get caught, but it also means that your first question to the
list might take a little longer to get answered. We apologize for any
inconvenience that this policy may cause.

Nobody on django-users answered my question! What should I do?
==============================================================

Try making your question more specific, or provide a better example of your
problem.

As with most open-source mailing lists, the folks on |django-users| are
volunteers. If nobody has answered your question, it may be because nobody
knows the answer, it may be because nobody can understand the question, or it
may be that everybody that can help is busy. One thing you might try is to ask
the question on IRC -- visit the `#django IRC channel`_ on the Freenode IRC
network.

You might notice we have a second mailing list, called |django-developers| --
but please don't email support questions to this mailing list. This list is
for discussion of the development of Django itself. Asking a tech support
question there is considered quite impolite.

I think I've found a bug! What should I do?
===========================================

Detailed instructions on how to handle a potential bug can be found in our
:ref:`Guide to contributing to Django <reporting-bugs>`.

I think I've found a security problem! What should I do?
========================================================

If you think you've found a security problem with Django, please send a message
to security@djangoproject.com. This is a private list only open to long-time,
highly trusted Django developers, and its archives are not publicly readable.

Due to the sensitive nature of security issues, we ask that if you think you
have found a security problem, *please* don't send a message to one of the
public mailing lists. Django has a
:ref:`policy for handling security issues <reporting-security-issues>`;
while a defect is outstanding, we would like to minimize any damage that
could be inflicted through public knowledge of that defect.

.. _`policy for handling security issues`: ../contributing/#reporting-security-issues

---

### 大一小学期 Week 3 Python Exam 2016 Docs Faq Index (`大一小学期/Week_3-Python/exam/2016/docs/faq/index.txt`)

==========
Django FAQ
==========

.. toctree::
   :maxdepth: 2

   general
   install
   usage
   help
   models
   admin
   contributing
   troubleshooting

---

### 大一小学期 Week 3 Python Exam 2016 Docs Faq Install (`大一小学期/Week_3-Python/exam/2016/docs/faq/install.txt`)

=================
FAQ: Installation
=================

How do I get started?
=====================

#. `Download the code`_.
#. Install Django (read the :doc:`installation guide </intro/install>`).
#. Walk through the :doc:`tutorial </intro/tutorial01>`.
#. Check out the rest of the :doc:`documentation </index>`, and `ask questions`_ if you
   run into trouble.

.. _`Download the code`: https://www.djangoproject.com/download/
.. _ask questions: https://www.djangoproject.com/community/

What are Django's prerequisites?
================================

Django requires Python. See the table in the next question for the versions of
Python that work with each version of Django. Other Python libraries may be
required for some uses, but you'll receive an error about it as they're needed.

For a development environment -- if you just want to experiment with Django --
you don't need to have a separate Web server installed; Django comes with its
own lightweight development server. For a production environment, Django follows
the WSGI spec, :pep:`3333`, which means it can run on a variety of server
platforms. See :doc:`Deploying Django </howto/deployment/index>` for some
popular alternatives.

If you want to use Django with a database, which is probably the case, you'll
also need a database engine. PostgreSQL_ is recommended, because we're
PostgreSQL fans, and MySQL_, `SQLite 3`_, and Oracle_ are also supported.

.. _Python: https://www.python.org/
.. _PostgreSQL: http://www.postgresql.org/
.. _MySQL: https://www.mysql.com/
.. _`SQLite 3`: https://www.sqlite.org/
.. _Oracle: http://www.oracle.com/

.. _faq-python-version-support:

What Python version can I use with Django?
==========================================

============== ===============
Django version Python versions
============== ===============
1.8            2.7, 3.2 (until the end of 2016), 3.3, 3.4, 3.5
1.9, 1.10      2.7, 3.4, 3.5
1.11           2.7, 3.4, 3.5, 3.6
2.0            3.5+
============== ===============

For each version of Python, only the latest micro release (A.B.C) is officially
supported. You can find the latest micro version for each series on the `Python
download page <https://www.python.org/downloads/>`_.

Typically, we will support a Python version up to and including the first
Django LTS release whose security support ends after security support for that
version of Python ends. For example, Python 3.3 security support ends September
2017 and Django 1.8 LTS security support ends April 2018. Therefore Django 1.8
is the last version to support Python 3.3.

What Python version should I use with Django?
=============================================

As of Django 1.6, Python 3 support is considered stable and you can safely use
it in production. See also :doc:`/topics/python3`. However, the community is
still in the process of migrating third-party packages and applications to
Python 3.

If you're starting a new project, and the dependencies you plan to use work on
Python 3, you should use Python 3. If they don't, consider contributing to the
porting efforts, or stick to Python 2.

Since newer versions of Python are often faster, have more features, and are
better supported, all else being equal, we recommend that you use the latest
2.x.y or 3.x.y release.

You don't lose anything in Django by using an older release, but you don't take
advantage of the improvements and optimizations in newer Python releases.
Third-party applications for use with Django are, of course, free to set their
own version requirements.

Should I use the stable version or development version?
=======================================================

Generally, if you're using code in production, you should be using a
stable release. The Django project publishes a full stable release
every nine months or so, with bugfix updates in between. These stable
releases contain the API that is covered by our backwards
compatibility guarantees; if you write code against stable releases,
you shouldn't have any problems upgrading when the next official
version is released.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Faq Models (`大一小学期/Week_3-Python/exam/2016/docs/faq/models.txt`)

=========================
FAQ: Databases and models
=========================

.. _faq-see-raw-sql-queries:

How can I see the raw SQL queries Django is running?
====================================================

Make sure your Django :setting:`DEBUG` setting is set to ``True``.
Then, just do this::

    >>> from django.db import connection
    >>> connection.queries
    [{'sql': 'SELECT polls_polls.id, polls_polls.question, polls_polls.pub_date FROM polls_polls',
    'time': '0.002'}]

``connection.queries`` is only available if :setting:`DEBUG` is ``True``.
It's a list of dictionaries in order of query execution. Each dictionary has
the following::

    ``sql`` -- The raw SQL statement
    ``time`` -- How long the statement took to execute, in seconds.

``connection.queries`` includes all SQL statements -- INSERTs, UPDATES,
SELECTs, etc. Each time your app hits the database, the query will be recorded.

If you are using :doc:`multiple databases</topics/db/multi-db>`, you can use the
same interface on each member of the ``connections`` dictionary::

    >>> from django.db import connections
    >>> connections['my_db_alias'].queries

If you need to clear the query list manually at any point in your functions,
just call ``reset_queries()``, like this::

    from django.db import reset_queries
    reset_queries()

Can I use Django with a pre-existing database?
==============================================

Yes. See :doc:`Integrating with a legacy database </howto/legacy-databases>`.

If I make changes to a model, how do I update the database?
===========================================================

Take a look at Django's support for :mod:`schema migrations
<django.db.migrations>`.

If you don't mind clearing data, your project's ``manage.py`` utility has a
:djadmin:`flush` option to reset the database to the state it was in
immediately after :djadmin:`migrate` was executed.

Do Django models support multiple-column primary keys?
======================================================

No. Only single-column primary keys are supported.

But this isn't an issue in practice, because there's nothing stopping you from
adding other constraints (using the ``unique_together`` model option or
creating the constraint directly in your database), and enforcing the
uniqueness at that level. Single-column primary keys are needed for things such
as the admin interface to work; e.g., you need a simple way of being able to
specify an object to edit or delete.

Does Django support NoSQL databases?
====================================

NoSQL databases are not officially supported by Django itself. There are,
however, a number of side project and forks which allow NoSQL functionality in
Django, like `Django non-rel`_.

You can also take a look on `the wiki page`_ which discusses some alternatives.

.. _`Django non-rel`: http://django-nonrel.org/
.. _`the wiki page`: https://code.djangoproject.com/wiki/NoSqlSupport

How do I add database-specific options to my CREATE TABLE statements, such as specifying MyISAM as the table type?
==================================================================================================================

We try to avoid adding special cases in the Django code to accommodate all the
database-specific options such as table type, etc. If you'd like to use any of
these options, create a migration with a
:class:`~django.db.migrations.operations.RunSQL` operation that contains
``ALTER TABLE`` statements that do what you want to do.

For example, if you're using MySQL and want your tables to use the MyISAM table
type, use the following SQL::

    ALTER TABLE myapp_mytable ENGINE=MyISAM;

---

### 大一小学期 Week 3 Python Exam 2016 Docs Faq Troubleshooting (`大一小学期/Week_3-Python/exam/2016/docs/faq/troubleshooting.txt`)

===============
Troubleshooting
===============

This page contains some advice about errors and problems commonly encountered
during the development of Django applications.

.. _troubleshooting-django-admin:

Problems running django-admin
=============================

"command not found: django-admin"
------------------------------------

:doc:`django-admin </ref/django-admin>` should be on your system path if you
installed Django via ``python setup.py``. If it's not on your path, you can
find it in ``site-packages/django/bin``, where ``site-packages`` is a directory
within your Python installation. Consider symlinking to :doc:`django-admin
</ref/django-admin>` from some place on your path, such as
:file:`/usr/local/bin`.

If ``django-admin`` doesn't work but ``django-admin.py`` does, you're probably
using a version of Django that doesn't match the version of this documentation.
``django-admin`` is new in Django 1.7.

Mac OS X permissions
--------------------

If you're using Mac OS X, you may see the message "permission denied" when
you try to run ``django-admin``. This is because, on Unix-based systems like
OS X, a file must be marked as "executable" before it can be run as a program.
To do this, open Terminal.app and navigate (using the ``cd`` command) to the
directory where :doc:`django-admin </ref/django-admin>` is installed, then
run the command ``sudo chmod +x django-admin``.

Miscellaneous
=============

I'm getting a ``UnicodeDecodeError``. What am I doing wrong?
------------------------------------------------------------

This class of errors happen when a bytestring containing non-ASCII sequences is
transformed into a Unicode string and the specified encoding is incorrect. The
output generally looks like this::

    UnicodeDecodeError: 'ascii' codec can't decode byte 0x?? in position ?:
    ordinal not in range(128)

The resolution mostly depends on the context, however here are two common
pitfalls producing this error:

* Your system locale may be a default ASCII locale, like the "C" locale on
  UNIX-like systems (can be checked by the ``locale`` command). If it's the
  case, please refer to your system documentation to learn how you can change
  this to a UTF-8 locale.

* You created raw bytestrings, which is easy to do on Python 2::

      my_string = 'café'

  Either use the ``u''`` prefix or even better, add the
  ``from __future__ import unicode_literals`` line at the top of your file
  so that your code will be compatible with Python 3.2 which doesn't support
  the ``u''`` prefix.

Related resources:

* :doc:`Unicode in Django </ref/unicode>`
* https://wiki.python.org/moin/UnicodeDecodeError

---

### 大一小学期 Week 3 Python Exam 2016 Docs Faq Usage (`大一小学期/Week_3-Python/exam/2016/docs/faq/usage.txt`)

=================
FAQ: Using Django
=================

Why do I get an error about importing DJANGO_SETTINGS_MODULE?
=============================================================

Make sure that:

* The environment variable DJANGO_SETTINGS_MODULE is set to a
  fully-qualified Python module (i.e. "mysite.settings").

* Said module is on ``sys.path`` (``import mysite.settings`` should work).

* The module doesn't contain syntax errors (of course).

I can't stand your template language. Do I have to use it?
==========================================================

We happen to think our template engine is the best thing since chunky bacon,
but we recognize that choosing a template language runs close to religion.
There's nothing about Django that requires using the template language, so
if you're attached to Jinja2, Mako, or whatever, feel free to use those.

Do I have to use your model/database layer?
===========================================

Nope. Just like the template system, the model/database layer is decoupled from
the rest of the framework.

The one exception is: If you use a different database library, you won't get to
use Django's automatically-generated admin site. That app is coupled to the
Django database layer.

How do I use image and file fields?
===================================

Using a :class:`~django.db.models.FileField` or an
:class:`~django.db.models.ImageField` in a model takes a few steps:

#. In your settings file, you'll need to define :setting:`MEDIA_ROOT` as
   the full path to a directory where you'd like Django to store uploaded
   files. (For performance, these files are not stored in the database.)
   Define :setting:`MEDIA_URL` as the base public URL of that directory.
   Make sure that this directory is writable by the Web server's user
   account.

#. Add the :class:`~django.db.models.FileField` or
   :class:`~django.db.models.ImageField` to your model, defining the
   :attr:`~django.db.models.FileField.upload_to` option to specify a
   subdirectory of :setting:`MEDIA_ROOT` to use for uploaded files.

#. All that will be stored in your database is a path to the file
   (relative to :setting:`MEDIA_ROOT`). You'll most likely want to use the
   convenience :attr:`~django.db.models.fields.files.FieldFile.url` attribute
   provided by Django. For example, if your
   :class:`~django.db.models.ImageField` is called ``mug_shot``, you can get
   the absolute path to your image in a template with
   ``{{ object.mug_shot.url }}``.

How do I make a variable available to all my templates?
=======================================================

Sometimes your templates just all need the same thing. A common example would
be dynamically-generated menus. At first glance, it seems logical to simply
add a common dictionary to the template context.

The correct solution is to use a ``RequestContext``. Details on how to do this
are here: :ref:`subclassing-context-requestcontext`.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Auth Remote User (`大一小学期/Week_3-Python/exam/2016/docs/howto/auth-remote-user.txt`)

====================================
Authentication using ``REMOTE_USER``
====================================

This document describes how to make use of external authentication sources
(where the Web server sets the ``REMOTE_USER`` environment variable) in your
Django applications.  This type of authentication solution is typically seen on
intranet sites, with single sign-on solutions such as IIS and Integrated
Windows Authentication or Apache and `mod_authnz_ldap`_, `CAS`_, `Cosign`_,
`WebAuth`_, `mod_auth_sspi`_, etc.

.. _mod_authnz_ldap: https://httpd.apache.org/docs/2.2/mod/mod_authnz_ldap.html
.. _CAS: https://www.apereo.org/projects/cas
.. _Cosign: http://weblogin.org
.. _WebAuth: https://www.stanford.edu/services/webauth/
.. _mod_auth_sspi: http://sourceforge.net/projects/mod-auth-sspi

When the Web server takes care of authentication it typically sets the
``REMOTE_USER`` environment variable for use in the underlying application.  In
Django, ``REMOTE_USER`` is made available in the :attr:`request.META
<django.http.HttpRequest.META>` attribute.  Django can be configured to make
use of the ``REMOTE_USER`` value using the ``RemoteUserMiddleware``
or ``PersistentRemoteUserMiddleware``, and
:class:`~django.contrib.auth.backends.RemoteUserBackend` classes found in
:mod:`django.contrib.auth`.

Configuration
=============

First, you must add the
:class:`django.contrib.auth.middleware.RemoteUserMiddleware` to the
:setting:`MIDDLEWARE` setting **after** the
:class:`django.contrib.auth.middleware.AuthenticationMiddleware`::

    MIDDLEWARE = [
        '...',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.RemoteUserMiddleware',
        '...',
    ]

Next, you must replace the :class:`~django.contrib.auth.backends.ModelBackend`
with :class:`~django.contrib.auth.backends.RemoteUserBackend` in the
:setting:`AUTHENTICATION_BACKENDS` setting::

    AUTHENTICATION_BACKENDS = [
        'django.contrib.auth.backends.RemoteUserBackend',
    ]

With this setup, ``RemoteUserMiddleware`` will detect the username in
``request.META['REMOTE_USER']`` and will authenticate and auto-login that user
using the :class:`~django.contrib.auth.backends.RemoteUserBackend`.

Be aware that this particular setup disables authentication with the default
``ModelBackend``. This means that if the ``REMOTE_USER`` value is not set
then the user is unable to log in, even using Django's admin interface.
Adding ``'django.contrib.auth.backends.ModelBackend'`` to the
``AUTHENTICATION_BACKENDS`` list will use ``ModelBackend`` as a fallback
if ``REMOTE_USER`` is absent, which will solve these issues.

Django's user management, such as the views in ``contrib.admin`` and
the :djadmin:`createsuperuser` management command, doesn't integrate with
remote users. These interfaces work with users stored in the database
regardless of ``AUTHENTICATION_BACKENDS``.

.. note::

    Since the ``RemoteUserBackend`` inherits from ``ModelBackend``, you will
    still have all of the same permissions checking that is implemented in
    ``ModelBackend``.

    Users with :attr:`is_active=False
    <django.contrib.auth.models.User.is_active>` won't be allowed to
    authenticate. Use
    :class:`~django.contrib.auth.backends.AllowAllUsersRemoteUserBackend` if
    you want to allow them to.

    .. versionchanged:: 1.10

        In older versions, inactive users weren't rejected as described above.

If your authentication mechanism uses a custom HTTP header and not
``REMOTE_USER``, you can subclass ``RemoteUserMiddleware`` and set the
``header`` attribute to the desired ``request.META`` key.  For example::

    from django.contrib.auth.middleware import RemoteUserMiddleware

    class CustomHeaderMiddleware(RemoteUserMiddleware):
        header = 'HTTP_AUTHUSER'

.. warning::

    Be very careful if using a ``RemoteUserMiddleware`` subclass with a custom
    HTTP header. You must be sure that your front-end web server always sets or
    strips that header based on the appropriate authentication checks, never
    permitting an end-user to submit a fake (or "spoofed") header value. Since
    the HTTP headers ``X-Auth-User`` and ``X-Auth_User`` (for example) both
    normalize to the ``HTTP_X_AUTH_USER`` key in ``request.META``, you must
    also check that your web server doesn't allow a spoofed header using
    underscores in place of dashes.

    This warning doesn't apply to ``RemoteUserMiddleware`` in its default
    configuration with ``header = 'REMOTE_USER'``, since a key that doesn't
    start with ``HTTP_`` in ``request.META`` can only be set by your WSGI
    server, not directly from an HTTP request header.

If you need more control, you can create your own authentication backend
that inherits from :class:`~django.contrib.auth.backends.RemoteUserBackend` and
override one or more of its attributes and methods.

.. _persistent-remote-user-middleware-howto:

Using ``REMOTE_USER`` on login pages only
=========================================

.. versionadded:: 1.9

The ``RemoteUserMiddleware`` authentication middleware assumes that the HTTP
request header ``REMOTE_USER`` is present with all authenticated requests. That
might be expected and practical when Basic HTTP Auth with ``htpasswd`` or other
simple mechanisms are used, but with Negotiate (GSSAPI/Kerberos) or other
resource intensive authentication methods, the authentication in the front-end
HTTP server is usually only set up for one or a few login URLs, and after
successful authentication, the application is supposed to maintain the
authenticated session itself.

:class:`~django.contrib.auth.middleware.PersistentRemoteUserMiddleware`
provides support for this use case. It will maintain the authenticated session
until explicit logout by the user. The class can be used as a drop-in
replacement of :class:`~django.contrib.auth.middleware.RemoteUserMiddleware`
in the documentation above.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Custom File Storage (`大一小学期/Week_3-Python/exam/2016/docs/howto/custom-file-storage.txt`)

===============================
Writing a custom storage system
===============================

.. currentmodule:: django.core.files.storage

If you need to provide custom file storage -- a common example is storing files
on some remote system -- you can do so by defining a custom storage class.
You'll need to follow these steps:

#. Your custom storage system must be a subclass of
   ``django.core.files.storage.Storage``::

        from django.core.files.storage import Storage

        class MyStorage(Storage):
            ...

#. Django must be able to instantiate your storage system without any arguments.
   This means that any settings should be taken from ``django.conf.settings``::

        from django.conf import settings
        from django.core.files.storage import Storage

        class MyStorage(Storage):
            def __init__(self, option=None):
                if not option:
                    option = settings.CUSTOM_STORAGE_OPTIONS
                ...

#. Your storage class must implement the :meth:`_open()` and :meth:`_save()`
   methods, along with any other methods appropriate to your storage class. See
   below for more on these methods.

   In addition, if your class provides local file storage, it must override
   the ``path()`` method.

#. Your storage class must be :ref:`deconstructible <custom-deconstruct-method>`
   so it can be serialized when it's used on a field in a migration. As long
   as your field has arguments that are themselves
   :ref:`serializable <migration-serializing>`, you can use the
   ``django.utils.deconstruct.deconstructible`` class decorator for this
   (that's what Django uses on FileSystemStorage).

By default, the following methods raise `NotImplementedError` and will
typically have to be overridden:

* :meth:`Storage.delete`
* :meth:`Storage.exists`
* :meth:`Storage.listdir`
* :meth:`Storage.size`
* :meth:`Storage.url`

Note however that not all these methods are required and may be deliberately
omitted. As it happens, it is possible to leave each method unimplemented and
still have a working Storage.

By way of example, if listing the contents of certain storage backends turns
out to be expensive, you might decide not to implement `Storage.listdir`.

Another example would be a backend that only handles writing to files. In this
case, you would not need to implement any of the above methods.

Ultimately, which of these methods are implemented is up to you. Leaving some
methods unimplemented will result in a partial (possibly broken) interface.

You'll also usually want to use hooks specifically designed for custom storage
objects. These are:

.. method:: _open(name, mode='rb')

**Required**.

Called by ``Storage.open()``, this is the actual mechanism the storage class
uses to open the file. This must return a ``File`` object, though in most cases,
you'll want to return some subclass here that implements logic specific to the
backend storage system.

.. method:: _save(name, content)

Called by ``Storage.save()``. The ``name`` will already have gone through
``get_valid_name()`` and ``get_available_name()``, and the ``content`` will be a
``File`` object itself.

Should return the actual name of name of the file saved (usually the ``name``
passed in, but if the storage needs to change the file name return the new name
instead).

.. method:: get_valid_name(name)

Returns a filename suitable for use with the underlying storage system. The
``name`` argument passed to this method is either the original filename sent to
the server or, if ``upload_to`` is a callable, the filename returned by that
method after any path information is removed. Override this to customize how
non-standard characters are converted to safe filenames.

.. versionchanged:: 1.9

    In older versions, this method was not called when ``upload_to`` was a
    callable.

The code provided on ``Storage`` retains only alpha-numeric characters, periods
and underscores from the original filename, removing everything else.

.. method:: get_available_name(name, max_length=None)

Returns a filename that is available in the storage mechanism, possibly taking
the provided filename into account. The ``name`` argument passed to this method
will have already cleaned to a filename valid for the storage system, according
to the ``get_valid_name()`` method described above.

The length of the filename will not exceed ``max_length``, if provided. If a
free unique filename cannot be found, a :exc:`SuspiciousFileOperation
<django.core.exceptions.SuspiciousOperation>` exception is raised.

If a file with ``name`` already exists, an underscore plus a random 7 character
alphanumeric string is appended to the filename before the extension.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Custom Lookups (`大一小学期/Week_3-Python/exam/2016/docs/howto/custom-lookups.txt`)

==============
Custom Lookups
==============

.. currentmodule:: django.db.models

Django offers a wide variety of :ref:`built-in lookups <field-lookups>` for
filtering (for example, ``exact`` and ``icontains``). This documentation
explains how to write custom lookups and how to alter the working of existing
lookups. For the API references of lookups, see the :doc:`/ref/models/lookups`.

A simple lookup example
=======================

Let's start with a simple custom lookup. We will write a custom lookup ``ne``
which works opposite to ``exact``. ``Author.objects.filter(name__ne='Jack')``
will translate to the SQL::

  "author"."name" <> 'Jack'

This SQL is backend independent, so we don't need to worry about different
databases.

There are two steps to making this work. Firstly we need to implement the
lookup, then we need to tell Django about it. The implementation is quite
straightforward::

  from django.db.models import Lookup

  class NotEqual(Lookup):
      lookup_name = 'ne'

      def as_sql(self, compiler, connection):
          lhs, lhs_params = self.process_lhs(compiler, connection)
          rhs, rhs_params = self.process_rhs(compiler, connection)
          params = lhs_params + rhs_params
          return '%s <> %s' % (lhs, rhs), params

To register the ``NotEqual`` lookup we will just need to call
``register_lookup`` on the field class we want the lookup to be available. In
this case, the lookup makes sense on all ``Field`` subclasses, so we register
it with ``Field`` directly::

  from django.db.models.fields import Field
  Field.register_lookup(NotEqual)

Lookup registration can also be done using a decorator pattern::

    from django.db.models.fields import Field

    @Field.register_lookup
    class NotEqualLookup(Lookup):
        # ...

We can now use ``foo__ne`` for any field ``foo``. You will need to ensure that
this registration happens before you try to create any querysets using it. You
could place the implementation in a ``models.py`` file, or register the lookup
in the ``ready()`` method of an ``AppConfig``.

Taking a closer look at the implementation, the first required attribute is
``lookup_name``. This allows the ORM to understand how to interpret ``name__ne``
and use ``NotEqual`` to generate the SQL. By convention, these names are always
lowercase strings containing only letters, but the only hard requirement is
that it must not contain the string ``__``.

We then need to define the ``as_sql`` method. This takes a ``SQLCompiler``
object, called ``compiler``,  and the active database connection.
``SQLCompiler`` objects are not documented, but the only thing we need to know
about them is that they have a ``compile()`` method which returns a tuple
containing an SQL string, and the parameters to be interpolated into that
string. In most cases, you don't need to use it directly and can pass it on to
``process_lhs()`` and ``process_rhs()``.

A ``Lookup`` works against two values, ``lhs`` and ``rhs``, standing for
left-hand side and right-hand side. The left-hand side is usually a field
reference, but it can be anything implementing the :ref:`query expression API
<query-expression>`. The right-hand is the value given by the user. In the
example ``Author.objects.filter(name__ne='Jack')``, the left-hand side is a
reference to the ``name`` field of the ``Author`` model, and ``'Jack'`` is the
right-hand side.

We call ``process_lhs`` and ``process_rhs`` to convert them into the values we
need for SQL using the ``compiler`` object described before. These methods
return tuples containing some SQL and the parameters to be interpolated into
that SQL, just as we need to return from our ``as_sql`` method. In the above
example, ``process_lhs`` returns ``('"author"."name"', [])`` and
``process_rhs`` returns ``('"%s"', ['Jack'])``. In this example there were no
parameters for the left hand side, but this would depend on the object we have,
so we still need to include them in the parameters we return.

Finally we combine the parts into an SQL expression with ``<>``, and supply all
the parameters for the query. We then return a tuple containing the generated
SQL string and the parameters.

A simple transformer example
============================

The custom lookup above is great, but in some cases you may want to be able to
chain lookups together. For example, let's suppose we are building an
application where we want to make use of the ``abs()`` operator.
We have an ``Experiment`` model which records a start value, end value, and the
change (start - end). We would like to find all experiments where the change
was equal to a certain amount (``Experiment.objects.filter(change__abs=27)``),
or where it did not exceed a certain amount
(``Experiment.objects.filter(change__abs__lt=27)``).

.. note::
    This example is somewhat contrived, but it nicely demonstrates the range of
    functionality which is possible in a database backend independent manner,
    and without duplicating functionality already in Django.

We will start by writing a ``AbsoluteValue`` transformer. This will use the SQL
function ``ABS()`` to transform the value before comparison::

  from django.db.models import Transform

  class AbsoluteValue(Transform):
      lookup_name = 'abs'
      function = 'ABS'

Next, let's register it for ``IntegerField``::

  from django.db.models import IntegerField
  IntegerField.register_lookup(AbsoluteValue)

We can now run the queries we had before.
``Experiment.objects.filter(change__abs=27)`` will generate the following SQL::

    SELECT ... WHERE ABS("experiments"."change") = 27

By using ``Transform`` instead of ``Lookup`` it means we are able to chain
further lookups afterwards. So
``Experiment.objects.filter(change__abs__lt=27)`` will generate the following
SQL::

    SELECT ... WHERE ABS("experiments"."change") < 27

Note that in case there is no other lookup specified, Django interprets
``change__abs=27`` as ``change__abs__exact=27``.

When looking for which lookups are allowable after the ``Transform`` has been
applied, Django uses the ``output_field`` attribute. We didn't need to specify
this here as it didn't change, but supposing we were applying ``AbsoluteValue``
to some field which represents a more complex type (for example a point
relative to an origin, or a complex number) then we may have wanted to specify
that the transform returns a ``FloatField`` type for further lookups. This can
be done by adding an ``output_field`` attribute to the transform::

    from django.db.models import FloatField, Transform

    class AbsoluteValue(Transform):
        lookup_name = 'abs'
        function = 'ABS'

        @property
        def output_field(self):
            return FloatField()

This ensures that further lookups like ``abs__lte`` behave as they would for
a ``FloatField``.

Writing an efficient ``abs__lt`` lookup
=======================================

When using the above written ``abs`` lookup, the SQL produced will not use
indexes efficiently in some cases. In particular, when we use
``change__abs__lt=27``, this is equivalent to ``change__gt=-27`` AND
``change__lt=27``. (For the ``lte`` case we could use the SQL ``BETWEEN``).

So we would like ``Experiment.objects.filter(change__abs__lt=27)`` to generate
the following SQL::

    SELECT .. WHERE "experiments"."change" < 27 AND "experiments"."change" > -27

The implementation is::

  from django.db.models import Lookup

  class AbsoluteValueLessThan(Lookup):
      lookup_name = 'lt'

      def as_sql(self, compiler, connection):
          lhs, lhs_params = compiler.compile(self.lhs.lhs)
          rhs, rhs_params = self.process_rhs(compiler, connection)
          params = lhs_params + rhs_params + lhs_params + rhs_params
          return '%s < %s AND %s > -%s' % (lhs, rhs, lhs, rhs), params

  AbsoluteValue.register_lookup(AbsoluteValueLessThan)

There are a couple of notable things going on. First, ``AbsoluteValueLessThan``
isn't calling ``process_lhs()``. Instead it skips the transformation of the
``lhs`` done by ``AbsoluteValue`` and uses the original ``lhs``. That is, we
want to get ``"experiments"."change"`` not ``ABS("experiments"."change")``.
Referring directly to ``self.lhs.lhs`` is safe as ``AbsoluteValueLessThan``
can be accessed only from the ``AbsoluteValue`` lookup, that is the ``lhs``
is always an instance of ``AbsoluteValue``.

Notice also that  as both sides are used multiple times in the query the params
need to contain ``lhs_params`` and ``rhs_params`` multiple times.

The final query does the inversion (``27`` to ``-27``) directly in the
database. The reason for doing this is that if the ``self.rhs`` is something else
than a plain integer value (for example an ``F()`` reference) we can't do the
transformations in Python.

.. note::
    In fact, most lookups with ``__abs`` could be implemented as range queries
    like this, and on most database backends it is likely to be more sensible to
    do so as you can make use of the indexes. However with PostgreSQL you may
    want to add an index on ``abs(change)`` which would allow these queries to
    be very efficient.

A bilateral transformer example
===============================

The ``AbsoluteValue`` example we discussed previously is a transformation which
applies to the left-hand side of the lookup. There may be some cases where you
want the transformation to be applied to both the left-hand side and the
right-hand side. For instance, if you want to filter a queryset based on the
equality of the left and right-hand side insensitively to some SQL function.

Let's examine the simple example of case-insensitive transformation here. This
transformation isn't very useful in practice as Django already comes with a bunch
of built-in case-insensitive lookups, but it will be a nice demonstration of
bilateral transformations in a database-agnostic way.

We define an ``UpperCase`` transformer which uses the SQL function ``UPPER()`` to
transform the values before comparison. We define
:attr:`bilateral = True <django.db.models.Transform.bilateral>` to indicate that
this transformation should apply to both ``lhs`` and ``rhs``::

  from django.db.models import Transform

  class UpperCase(Transform):
      lookup_name = 'upper'
      function = 'UPPER'
      bilateral = True

Next, let's register it::

  from django.db.models import CharField, TextField
  CharField.register_lookup(UpperCase)
  TextField.register_lookup(UpperCase)

Now, the queryset ``Author.objects.filter(name__upper="doe")`` will generate a case
insensitive query like this::

    SELECT ... WHERE UPPER("author"."name") = UPPER('doe')

Writing alternative implementations for existing lookups
========================================================

Sometimes different database vendors require different SQL for the same
operation. For this example we will rewrite a custom implementation for
MySQL for the NotEqual operator. Instead of ``<>`` we will be using ``!=``
operator. (Note that in reality almost all databases support both, including
all the official databases supported by Django).

We can change the behavior on a specific backend by creating a subclass of
``NotEqual`` with a ``as_mysql`` method::

  class MySQLNotEqual(NotEqual):
      def as_mysql(self, compiler, connection):
          lhs, lhs_params = self.process_lhs(compiler, connection)
          rhs, rhs_params = self.process_rhs(compiler, connection)
          params = lhs_params + rhs_params
          return '%s != %s' % (lhs, rhs), params

  Field.register_lookup(MySQLNotEqual)

We can then register it with ``Field``. It takes the place of the original
``NotEqual`` class as it has the same ``lookup_name``.

When compiling a query, Django first looks for ``as_%s % connection.vendor``
methods, and then falls back to ``as_sql``. The vendor names for the in-built
backends are ``sqlite``, ``postgresql``, ``oracle`` and ``mysql``.

How Django determines the lookups and transforms which are used
===============================================================

In some cases you may wish to dynamically change which ``Transform`` or
``Lookup`` is returned based on the name passed in, rather than fixing it. As
an example, you could have a field which stores coordinates or an arbitrary
dimension, and wish to allow a syntax like ``.filter(coords__x7=4)`` to return
the objects where the 7th coordinate has value 4. In order to do this, you
would override ``get_lookup`` with something like::

    class CoordinatesField(Field):
        def get_lookup(self, lookup_name):
            if lookup_name.startswith('x'):
                try:
                    dimension = int(lookup_name[1:])
                except ValueError:
                    pass
                else:
                    return get_coordinate_lookup(dimension)
            return super(CoordinatesField, self).get_lookup(lookup_name)

You would then define ``get_coordinate_lookup`` appropriately to return a
``Lookup`` subclass which handles the relevant value of ``dimension``.

There is a similarly named method called ``get_transform()``. ``get_lookup()``
should always return a ``Lookup`` subclass, and ``get_transform()`` a
``Transform`` subclass. It is important to remember that ``Transform``
objects can be further filtered on, and ``Lookup`` objects cannot.

When filtering, if there is only one lookup name remaining to be resolved, we
will look for a ``Lookup``. If there are multiple names, it will look for a
``Transform``. In the situation where there is only one name and a ``Lookup``
is not found, we look for a ``Transform`` and then the ``exact`` lookup on that
``Transform``. All call sequences always end with a ``Lookup``. To clarify:

- ``.filter(myfield__mylookup)`` will call ``myfield.get_lookup('mylookup')``.
- ``.filter(myfield__mytransform__mylookup)`` will call
  ``myfield.get_transform('mytransform')``, and then
  ``mytransform.get_lookup('mylookup')``.
- ``.filter(myfield__mytransform)`` will first call
  ``myfield.get_lookup('mytransform')``, which will fail, so it will fall back
  to calling ``myfield.get_transform('mytransform')`` and then
  ``mytransform.get_lookup('exact')``.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Custom Management Commands (`大一小学期/Week_3-Python/exam/2016/docs/howto/custom-management-commands.txt`)

========================================
Writing custom ``django-admin`` commands
========================================

.. module:: django.core.management

Applications can register their own actions with ``manage.py``. For example,
you might want to add a ``manage.py`` action for a Django app that you're
distributing. In this document, we will be building a custom ``closepoll``
command for the ``polls`` application from the
:doc:`tutorial</intro/tutorial01>`.

To do this, just add a ``management/commands`` directory to the application.
Django will register a ``manage.py`` command for each Python module in that
directory whose name doesn't begin with an underscore. For example::

    polls/
        __init__.py
        models.py
        management/
            __init__.py
            commands/
                __init__.py
                _private.py
                closepoll.py
        tests.py
        views.py

On Python 2, be sure to include ``__init__.py`` files in both the
``management`` and ``management/commands`` directories as done above or your
command will not be detected.

In this example, the ``closepoll`` command will be made available to any project
that includes the ``polls`` application in :setting:`INSTALLED_APPS`.

The ``_private.py`` module will not be available as a management command.

The ``closepoll.py`` module has only one requirement -- it must define a class
``Command`` that extends :class:`BaseCommand` or one of its
:ref:`subclasses<ref-basecommand-subclasses>`.

.. admonition:: Standalone scripts

    Custom management commands are especially useful for running standalone
    scripts or for scripts that are periodically executed from the UNIX crontab
    or from Windows scheduled tasks control panel.

To implement the command, edit ``polls/management/commands/closepoll.py`` to
look like this::

    from django.core.management.base import BaseCommand, CommandError
    from polls.models import Question as Poll

    class Command(BaseCommand):
        help = 'Closes the specified poll for voting'

        def add_arguments(self, parser):
            parser.add_argument('poll_id', nargs='+', type=int)

        def handle(self, *args, **options):
            for poll_id in options['poll_id']:
                try:
                    poll = Poll.objects.get(pk=poll_id)
                except Poll.DoesNotExist:
                    raise CommandError('Poll "%s" does not exist' % poll_id)

                poll.opened = False
                poll.save()

                self.stdout.write(self.style.SUCCESS('Successfully closed poll "%s"' % poll_id))

.. _management-commands-output:

.. note::
    When you are using management commands and wish to provide console
    output, you should write to ``self.stdout`` and ``self.stderr``,
    instead of printing to ``stdout`` and ``stderr`` directly. By
    using these proxies, it becomes much easier to test your custom
    command. Note also that you don't need to end messages with a newline
    character, it will be added automatically, unless you specify the ``ending``
    parameter::

        self.stdout.write("Unterminated line", ending='')

The new custom command can be called using ``python manage.py closepoll
<poll_id>``.

The ``handle()`` method takes one or more ``poll_ids`` and sets ``poll.opened``
to ``False`` for each one. If the user referenced any nonexistent polls, a
:exc:`CommandError` is raised. The ``poll.opened`` attribute does not exist in
the :doc:`tutorial</intro/tutorial01>` and was added to
``polls.models.Question`` for this example.

.. _custom-commands-options:

Accepting optional arguments
============================

The same ``closepoll`` could be easily modified to delete a given poll instead
of closing it by accepting additional command line options. These custom
options can be added in the :meth:`~BaseCommand.add_arguments` method like this::

    class Command(BaseCommand):
        def add_arguments(self, parser):
            # Positional arguments
            parser.add_argument('poll_id', nargs='+', type=int)

            # Named (optional) arguments
            parser.add_argument(
                '--delete',
                action='store_true',
                dest='delete',
                default=False,
                help='Delete poll instead of closing it',
            )

        def handle(self, *args, **options):
            # ...
            if options['delete']:
                poll.delete()
            # ...

The option (``delete`` in our example) is available in the options dict
parameter of the handle method. See the :py:mod:`argparse` Python documentation
for more about ``add_argument`` usage.

In addition to being able to add custom command line options, all
:doc:`management commands</ref/django-admin>` can accept some default options
such as :option:`--verbosity` and :option:`--traceback`.

.. _management-commands-and-locales:

Management commands and locales
===============================

By default, the :meth:`BaseCommand.execute` method deactivates translations
because some commands shipped with Django perform several tasks (for example,
user-facing content rendering and database population) that require a
project-neutral string language.

If, for some reason, your custom management command needs to use a fixed locale,
you should manually activate and deactivate it in your
:meth:`~BaseCommand.handle` method using the functions provided by the I18N
support code::

    from django.core.management.base import BaseCommand, CommandError
    from django.utils import translation

    class Command(BaseCommand):
        ...
        can_import_settings = True

        def handle(self, *args, **options):

            # Activate a fixed locale, e.g. Russian
            translation.activate('ru')

            # Or you can activate the LANGUAGE_CODE # chosen in the settings:
            from django.conf import settings
            translation.activate(settings.LANGUAGE_CODE)

            # Your command logic here
            ...

            translation.deactivate()

Another need might be that your command simply should use the locale set in
settings and Django should be kept from deactivating it. You can achieve
it by using the :data:`BaseCommand.leave_locale_alone` option.

When working on the scenarios described above though, take into account that
system management commands typically have to be very careful about running in
non-uniform locales, so you might need to:

* Make sure the :setting:`USE_I18N` setting is always ``True`` when running
  the command (this is a good example of the potential problems stemming
  from a dynamic runtime environment that Django commands avoid offhand by
  deactivating translations).

* Review the code of your command and the code it calls for behavioral
  differences when locales are changed and evaluate its impact on
  predictable behavior of your command.

Testing
=======

Information on how to test custom management commands can be found in the
:ref:`testing docs <topics-testing-management-commands>`.

Command objects
===============

.. class:: BaseCommand

The base class from which all management commands ultimately derive.

Use this class if you want access to all of the mechanisms which
parse the command-line arguments and work out what code to call in
response; if you don't need to change any of that behavior,
consider using one of its :ref:`subclasses<ref-basecommand-subclasses>`.

Subclassing the :class:`BaseCommand` class requires that you implement the
:meth:`~BaseCommand.handle` method.

Attributes
----------

All attributes can be set in your derived class and can be used in
:class:`BaseCommand`’s :ref:`subclasses<ref-basecommand-subclasses>`.

.. attribute:: BaseCommand.can_import_settings

    A boolean indicating whether the command needs to be able to
    import Django settings; if ``True``, ``execute()`` will verify
    that this is possible before proceeding. Default value is
    ``True``.

.. attribute:: BaseCommand.help

    A short description of the command, which will be printed in the
    help message when the user runs the command
    ``python manage.py help <command>``.

.. attribute:: BaseCommand.missing_args_message

    If your command defines mandatory positional arguments, you can customize
    the message error returned in the case of missing arguments. The default is
    output by :py:mod:`argparse` ("too few arguments").

.. attribute:: BaseCommand.output_transaction

    A boolean indicating whether the command outputs SQL statements; if
    ``True``, the output will automatically be wrapped with ``BEGIN;`` and
    ``COMMIT;``. Default value is ``False``.

.. attribute:: BaseCommand.requires_migrations_checks

    .. versionadded:: 1.10

    A boolean; if ``True``, the command prints a warning if the set of
    migrations on disk don't match the migrations in the database. A warning
    doesn't prevent the command from executing. Default value is ``False``.

.. attribute:: BaseCommand.requires_system_checks

    A boolean; if ``True``, the entire Django project will be checked for
    potential problems prior to executing the command. Default value is ``True``.

.. attribute:: BaseCommand.leave_locale_alone

    A boolean indicating whether the locale set in settings should be preserved
    during the execution of the command instead of being forcibly set to 'en-us'.

    Default value is ``False``.

    Make sure you know what you are doing if you decide to change the value of
    this option in your custom command if it creates database content that
    is locale-sensitive and such content shouldn't contain any translations
    (like it happens e.g. with django.contrib.auth permissions) as making the
    locale differ from the de facto default 'en-us' might cause unintended
    effects. Seethe `Management commands and locales`_ section above for
    further details.

    This option can't be ``False`` when the
    :data:`~BaseCommand.can_import_settings` option is set to ``False`` too
    because attempting to set the locale needs access to settings. This
    condition will generate a :exc:`CommandError`.

.. attribute:: BaseCommand.style

    An instance attribute that helps create colored output when writing to
    ``stdout`` or ``stderr``. For example::

        self.stdout.write(self.style.SUCCESS('...'))

    See :ref:`syntax-coloring` to learn how to modify the color palette and to
    see the available styles (use uppercased versions of the "roles" described
    in that section).

    If you pass the :option:`--no-color` option when running your command, all
    ``self.style()`` calls will return the original string uncolored.

Methods
-------

:class:`BaseCommand` has a few methods that can be overridden but only
the :meth:`~BaseCommand.handle` method must be implemented.

.. admonition:: Implementing a constructor in a subclass

    If you implement ``__init__`` in your subclass of :class:`BaseCommand`,
    you must call :class:`BaseCommand`’s ``__init__``::

        class Command(BaseCommand):
            def __init__(self, *args, **kwargs):
                super(Command, self).__init__(*args, **kwargs)
                # ...

.. method:: BaseCommand.add_arguments(parser)

    Entry point to add parser arguments to handle command line arguments passed
    to the command. Custom commands should override this method to add both
    positional and optional arguments accepted by the command. Calling
    ``super()`` is not needed when directly subclassing ``BaseCommand``.

.. method:: BaseCommand.get_version()

    Returns the Django version, which should be correct for all built-in Django
    commands. User-supplied commands can override this method to return their
    own version.

.. method:: BaseCommand.execute(*args, **options)

    Tries to execute this command, performing system checks if needed (as
    controlled by the :attr:`requires_system_checks` attribute). If the command
    raises a :exc:`CommandError`, it's intercepted and printed to stderr.

.. admonition:: Calling a management command in your code

    ``execute()`` should not be called directly from your code to execute a
    command. Use :func:`~django.core.management.call_command` instead.

.. method:: BaseCommand.handle(*args, **options)

    The actual logic of the command. Subclasses must implement this method.

    It may return a Unicode string which will be printed to ``stdout`` (wrapped
    by ``BEGIN;`` and ``COMMIT;`` if :attr:`output_transaction` is ``True``).

.. method:: BaseCommand.check(app_configs=None, tags=None, display_num_errors=False)

    Uses the system check framework to inspect the entire Django project for
    potential problems. Serious problems are raised as a :exc:`CommandError`;
    warnings are output to stderr; minor notifications are output to stdout.

    If ``app_configs`` and ``tags`` are both ``None``, all system checks are
    performed. ``tags`` can be a list of check tags, like ``compatibility`` or
    ``models``.

.. _ref-basecommand-subclasses:

``BaseCommand`` subclasses
--------------------------

.. class:: AppCommand

A management command which takes one or more installed application labels as
arguments, and does something with each of them.

Rather than implementing :meth:`~BaseCommand.handle`, subclasses must
implement :meth:`~AppCommand.handle_app_config`, which will be called once for
each application.

.. method:: AppCommand.handle_app_config(app_config, **options)

    Perform the command's actions for ``app_config``, which will be an
    :class:`~django.apps.AppConfig` instance corresponding to an application
    label given on the command line.

.. class:: LabelCommand

A management command which takes one or more arbitrary arguments (labels) on
the command line, and does something with each of them.

Rather than implementing :meth:`~BaseCommand.handle`, subclasses must implement
:meth:`~LabelCommand.handle_label`, which will be called once for each label.

.. method:: LabelCommand.handle_label(label, **options)

    Perform the command's actions for ``label``, which will be the string as
    given on the command line.

Command exceptions
------------------

.. exception:: CommandError

Exception class indicating a problem while executing a management command.

If this exception is raised during the execution of a management command from a
command line console, it will be caught and turned into a nicely-printed error
message to the appropriate output stream (i.e., stderr); as a result, raising
this exception (with a sensible description of the error) is the preferred way
to indicate that something has gone wrong in the execution of a command.

If a management command is called from code through
:func:`~django.core.management.call_command`, it's up to you to catch the
exception when needed.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Custom Model Fields (`大一小学期/Week_3-Python/exam/2016/docs/howto/custom-model-fields.txt`)

===========================
Writing custom model fields
===========================

.. currentmodule:: django.db.models

Introduction
============

The :doc:`model reference </topics/db/models>` documentation explains how to use
Django's standard field classes -- :class:`~django.db.models.CharField`,
:class:`~django.db.models.DateField`, etc. For many purposes, those classes are
all you'll need. Sometimes, though, the Django version won't meet your precise
requirements, or you'll want to use a field that is entirely different from
those shipped with Django.

Django's built-in field types don't cover every possible database column type --
only the common types, such as ``VARCHAR`` and ``INTEGER``. For more obscure
column types, such as geographic polygons or even user-created types such as
`PostgreSQL custom types`_, you can define your own Django ``Field`` subclasses.

.. _PostgreSQL custom types: http://www.postgresql.org/docs/current/interactive/sql-createtype.html

Alternatively, you may have a complex Python object that can somehow be
serialized to fit into a standard database column type. This is another case
where a ``Field`` subclass will help you use your object with your models.

Our example object
------------------

Creating custom fields requires a bit of attention to detail. To make things
easier to follow, we'll use a consistent example throughout this document:
wrapping a Python object representing the deal of cards in a hand of Bridge_.
Don't worry, you don't have to know how to play Bridge to follow this example.
You only need to know that 52 cards are dealt out equally to four players, who
are traditionally called *north*, *east*, *south* and *west*.  Our class looks
something like this::

    class Hand(object):
        """A hand of cards (bridge style)"""

        def __init__(self, north, east, south, west):
            # Input parameters are lists of cards ('Ah', '9s', etc.)
            self.north = north
            self.east = east
            self.south = south
            self.west = west

        # ... (other possibly useful methods omitted) ...

.. _Bridge: https://en.wikipedia.org/wiki/Contract_bridge

This is just an ordinary Python class, with nothing Django-specific about it.
We'd like to be able to do things like this in our models (we assume the
``hand`` attribute on the model is an instance of ``Hand``)::

    example = MyModel.objects.get(pk=1)
    print(example.hand.north)

    new_hand = Hand(north, east, south, west)
    example.hand = new_hand
    example.save()

We assign to and retrieve from the ``hand`` attribute in our model just like
any other Python class. The trick is to tell Django how to handle saving and
loading such an object.

In order to use the ``Hand`` class in our models, we **do not** have to change
this class at all. This is ideal, because it means you can easily write
model support for existing classes where you cannot change the source code.

.. note::
    You might only be wanting to take advantage of custom database column
    types and deal with the data as standard Python types in your models;
    strings, or floats, for example. This case is similar to our ``Hand``
    example and we'll note any differences as we go along.

Background theory
=================

Database storage
----------------

The simplest way to think of a model field is that it provides a way to take a
normal Python object -- string, boolean, ``datetime``, or something more
complex like ``Hand`` -- and convert it to and from a format that is useful
when dealing with the database (and serialization, but, as we'll see later,
that falls out fairly naturally once you have the database side under control).

Fields in a model must somehow be converted to fit into an existing database
column type. Different databases provide different sets of valid column types,
but the rule is still the same: those are the only types you have to work
with. Anything you want to store in the database must fit into one of
those types.

Normally, you're either writing a Django field to match a particular database
column type, or there's a fairly straightforward way to convert your data to,
say, a string.

For our ``Hand`` example, we could convert the card data to a string of 104
characters by concatenating all the cards together in a pre-determined order --
say, all the *north* cards first, then the *east*, *south* and *west* cards. So
``Hand`` objects can be saved to text or character columns in the database.

What does a field class do?
---------------------------

All of Django's fields (and when we say *fields* in this document, we always
mean model fields and not :doc:`form fields </ref/forms/fields>`) are subclasses
of :class:`django.db.models.Field`. Most of the information that Django records
about a field is common to all fields -- name, help text, uniqueness and so
forth. Storing all that information is handled by ``Field``. We'll get into the
precise details of what ``Field`` can do later on; for now, suffice it to say
that everything descends from ``Field`` and then customizes key pieces of the
class behavior.

It's important to realize that a Django field class is not what is stored in
your model attributes. The model attributes contain normal Python objects. The
field classes you define in a model are actually stored in the ``Meta`` class
when the model class is created (the precise details of how this is done are
unimportant here). This is because the field classes aren't necessary when
you're just creating and modifying attributes. Instead, they provide the
machinery for converting between the attribute value and what is stored in the
database or sent to the :doc:`serializer </topics/serialization>`.

Keep this in mind when creating your own custom fields. The Django ``Field``
subclass you write provides the machinery for converting between your Python
instances and the database/serializer values in various ways (there are
differences between storing a value and using a value for lookups, for
example). If this sounds a bit tricky, don't worry -- it will become clearer in
the examples below. Just remember that you will often end up creating two
classes when you want a custom field:

* The first class is the Python object that your users will manipulate.
  They will assign it to the model attribute, they will read from it for
  displaying purposes, things like that. This is the ``Hand`` class in our
  example.

* The second class is the ``Field`` subclass. This is the class that knows
  how to convert your first class back and forth between its permanent
  storage form and the Python form.

Writing a field subclass
========================

When planning your :class:`~django.db.models.Field` subclass, first give some
thought to which existing :class:`~django.db.models.Field` class your new field
is most similar to. Can you subclass an existing Django field and save yourself
some work? If not, you should subclass the :class:`~django.db.models.Field`
class, from which everything is descended.

Initializing your new field is a matter of separating out any arguments that are
specific to your case from the common arguments and passing the latter to the
``__init__()`` method of :class:`~django.db.models.Field` (or your parent
class).

In our example, we'll call our field ``HandField``. (It's a good idea to call
your :class:`~django.db.models.Field` subclass ``<Something>Field``, so it's
easily identifiable as a :class:`~django.db.models.Field` subclass.) It doesn't
behave like any existing field, so we'll subclass directly from
:class:`~django.db.models.Field`::

    from django.db import models

    class HandField(models.Field):

        description = "A hand of cards (bridge style)"

        def __init__(self, *args, **kwargs):
            kwargs['max_length'] = 104
            super(HandField, self).__init__(*args, **kwargs)

Our ``HandField`` accepts most of the standard field options (see the list
below), but we ensure it has a fixed length, since it only needs to hold 52
card values plus their suits; 104 characters in total.

.. note::

    Many of Django's model fields accept options that they don't do anything
    with. For example, you can pass both
    :attr:`~django.db.models.Field.editable` and
    :attr:`~django.db.models.DateField.auto_now` to a
    :class:`django.db.models.DateField` and it will simply ignore the
    :attr:`~django.db.models.Field.editable` parameter
    (:attr:`~django.db.models.DateField.auto_now` being set implies
    ``editable=False``). No error is raised in this case.

    This behavior simplifies the field classes, because they don't need to
    check for options that aren't necessary. They just pass all the options to
    the parent class and then don't use them later on. It's up to you whether
    you want your fields to be more strict about the options they select, or to
    use the simpler, more permissive behavior of the current fields.

The ``Field.__init__()`` method takes the following parameters:

* :attr:`~django.db.models.Field.verbose_name`
* ``name``
* :attr:`~django.db.models.Field.primary_key`
* :attr:`~django.db.models.CharField.max_length`
* :attr:`~django.db.models.Field.unique`
* :attr:`~django.db.models.Field.blank`
* :attr:`~django.db.models.Field.null`
* :attr:`~django.db.models.Field.db_index`
* ``rel``: Used for related fields (like :class:`ForeignKey`). For advanced
  use only.
* :attr:`~django.db.models.Field.default`
* :attr:`~django.db.models.Field.editable`
* ``serialize``: If ``False``, the field will not be serialized when the model
  is passed to Django's :doc:`serializers </topics/serialization>`. Defaults to
  ``True``.
* :attr:`~django.db.models.Field.unique_for_date`
* :attr:`~django.db.models.Field.unique_for_month`
* :attr:`~django.db.models.Field.unique_for_year`
* :attr:`~django.db.models.Field.choices`
* :attr:`~django.db.models.Field.help_text`
* :attr:`~django.db.models.Field.db_column`
* :attr:`~django.db.models.Field.db_tablespace`: Only for index creation, if the
  backend supports :doc:`tablespaces </topics/db/tablespaces>`. You can usually
  ignore this option.
* :attr:`~django.db.models.Field.auto_created`: ``True`` if the field was
  automatically created, as for the :class:`~django.db.models.OneToOneField`
  used by model inheritance. For advanced use only.

All of the options without an explanation in the above list have the same
meaning they do for normal Django fields. See the :doc:`field documentation
</ref/models/fields>` for examples and details.

.. _custom-field-deconstruct-method:

Field deconstruction
--------------------

The counterpoint to writing your ``__init__()`` method is writing the
``deconstruct()`` method. This method tells Django how to take an instance
of your new field and reduce it to a serialized form - in particular, what
arguments to pass to ``__init__()`` to re-create it.

If you haven't added any extra options on top of the field you inherited from,
then there's no need to write a new ``deconstruct()`` method. If, however,
you're changing the arguments passed in ``__init__()`` (like we are in
``HandField``), you'll need to supplement the values being passed.

The contract of ``deconstruct()`` is simple; it returns a tuple of four items:
the field's attribute name, the full import path of the field class, the
positional arguments (as a list), and the keyword arguments (as a dict). Note
this is different from the ``deconstruct()`` method :ref:`for custom classes
<custom-deconstruct-method>` which returns a tuple of three things.

As a custom field author, you don't need to care about the first two values;
the base ``Field`` class has all the code to work out the field's attribute
name and import path. You do, however, have to care about the positional
and keyword arguments, as these are likely the things you are changing.

For example, in our ``HandField`` class we're always forcibly setting
max_length in ``__init__()``. The ``deconstruct()`` method on the base ``Field``
class will see this and try to return it in the keyword arguments; thus,
we can drop it from the keyword arguments for readability::

    from django.db import models

    class HandField(models.Field):

        def __init__(self, *args, **kwargs):
            kwargs['max_length'] = 104
            super(HandField, self).__init__(*args, **kwargs)

        def deconstruct(self):
            name, path, args, kwargs = super(HandField, self).deconstruct()
            del kwargs["max_length"]
            return name, path, args, kwargs

If you add a new keyword argument, you need to write code to put its value
into ``kwargs`` yourself::

    from django.db import models

    class CommaSepField(models.Field):
        "Implements comma-separated storage of lists"

        def __init__(self, separator=",", *args, **kwargs):
            self.separator = separator
            super(CommaSepField, self).__init__(*args, **kwargs)

        def deconstruct(self):
            name, path, args, kwargs = super(CommaSepField, self).deconstruct()
            # Only include kwarg if it's not the default
            if self.separator != ",":
                kwargs['separator'] = self.separator
            return name, path, args, kwargs

More complex examples are beyond the scope of this document, but remember -
for any configuration of your Field instance, ``deconstruct()`` must return
arguments that you can pass to ``__init__`` to reconstruct that state.

Pay extra attention if you set new default values for arguments in the
``Field`` superclass; you want to make sure they're always included, rather
than disappearing if they take on the old default value.

In addition, try to avoid returning values as positional arguments; where
possible, return values as keyword arguments for maximum future compatibility.
Of course, if you change the names of things more often than their position
in the constructor's argument list, you might prefer positional, but bear in
mind that people will be reconstructing your field from the serialized version
for quite a while (possibly years), depending how long your migrations live for.

You can see the results of deconstruction by looking in migrations that include
the field, and you can test deconstruction in unit tests by just deconstructing
and reconstructing the field::

    name, path, args, kwargs = my_field_instance.deconstruct()
    new_instance = MyField(*args, **kwargs)
    self.assertEqual(my_field_instance.some_attribute, new_instance.some_attribute)

Changing a custom field's base class
------------------------------------

You can't change the base class of a custom field because Django won't detect
the change and make a migration for it. For example, if you start with::

    class CustomCharField(models.CharField):
        ...

and then decide that you want to use ``TextField`` instead, you can't change
the subclass like this::

    class CustomCharField(models.TextField):
        ...

Instead, you must create a new custom field class and update your models to
reference it::

    class CustomCharField(models.CharField):
        ...

    class CustomTextField(models.TextField):
        ...

As discussed in :ref:`removing fields <migrations-removing-model-fields>`, you
must retain the original ``CustomCharField`` class as long as you have
migrations that reference it.

Documenting your custom field
-----------------------------

As always, you should document your field type, so users will know what it is.
In addition to providing a docstring for it, which is useful for developers,
you can also allow users of the admin app to see a short description of the
field type via the :doc:`django.contrib.admindocs
</ref/contrib/admin/admindocs>` application. To do this simply provide
descriptive text in a :attr:`~Field.description` class attribute of your custom
field. In the above example, the description displayed by the ``admindocs``
application for a ``HandField`` will be 'A hand of cards (bridge style)'.

In the :mod:`django.contrib.admindocs` display, the field description is
interpolated with ``field.__dict__`` which allows the description to
incorporate arguments of the field. For example, the description for
:class:`~django.db.models.CharField` is::

    description = _("String (up to %(max_length)s)")

Useful methods
--------------

Once you've created your :class:`~django.db.models.Field` subclass, you might
consider overriding a few standard methods, depending on your field's behavior.
The list of methods below is in approximately decreasing order of importance,
so start from the top.

.. _custom-database-types:

Custom database types
~~~~~~~~~~~~~~~~~~~~~

Say you've created a PostgreSQL custom type called ``mytype``. You can
subclass ``Field`` and implement the :meth:`~Field.db_type` method, like so::

    from django.db import models

    class MytypeField(models.Field):
        def db_type(self, connection):
            return 'mytype'

Once you have ``MytypeField``, you can use it in any model, just like any other
``Field`` type::

    class Person(models.Model):
        name = models.CharField(max_length=80)
        something_else = MytypeField()

If you aim to build a database-agnostic application, you should account for
differences in database column types. For example, the date/time column type
in PostgreSQL is called ``timestamp``, while the same column in MySQL is called
``datetime``. The simplest way to handle this in a :meth:`~Field.db_type`
method is to check the ``connection.settings_dict['ENGINE']`` attribute.

For example::

    class MyDateField(models.Field):
        def db_type(self, connection):
            if connection.settings_dict['ENGINE'] == 'django.db.backends.mysql':
                return 'datetime'
            else:
                return 'timestamp'

The :meth:`~Field.db_type` and :meth:`~Field.rel_db_type` methods are called by
Django when the framework constructs the ``CREATE TABLE`` statements for your
application -- that is, when you first create your tables. The methods are also
called when constructing a ``WHERE`` clause that includes the model field --
that is, when you retrieve data using QuerySet methods like ``get()``,
``filter()``, and ``exclude()`` and have the model field as an argument. They
are not called at any other time, so it can afford to execute slightly complex
code, such as the ``connection.settings_dict`` check in the above example.

Some database column types accept parameters, such as ``CHAR(25)``, where the
parameter ``25`` represents the maximum column length. In cases like these,
it's more flexible if the parameter is specified in the model rather than being
hard-coded in the ``db_type()`` method. For example, it wouldn't make much
sense to have a ``CharMaxlength25Field``, shown here::

    # This is a silly example of hard-coded parameters.
    class CharMaxlength25Field(models.Field):
        def db_type(self, connection):
            return 'char(25)'

    # In the model:
    class MyModel(models.Model):
        # ...
        my_field = CharMaxlength25Field()

The better way of doing this would be to make the parameter specifiable at run
time -- i.e., when the class is instantiated. To do that, just implement
``Field.__init__()``, like so::

    # This is a much more flexible example.
    class BetterCharField(models.Field):
        def __init__(self, max_length, *args, **kwargs):
            self.max_length = max_length
            super(BetterCharField, self).__init__(*args, **kwargs)

        def db_type(self, connection):
            return 'char(%s)' % self.max_length

    # In the model:
    class MyModel(models.Model):
        # ...
        my_field = BetterCharField(25)

Finally, if your column requires truly complex SQL setup, return ``None`` from
:meth:`.db_type`. This will cause Django's SQL creation code to skip
over this field. You are then responsible for creating the column in the right
table in some other way, of course, but this gives you a way to tell Django to
get out of the way.

The :meth:`~Field.rel_db_type` method is called by fields such as ``ForeignKey``
and ``OneToOneField`` that point to another field to determine their database
column data types. For example, if you have an ``UnsignedAutoField``, you also
need the foreign keys that point to that field to use the same data type::

    # MySQL unsigned integer (range 0 to 4294967295).
    class UnsignedAutoField(models.AutoField):
        def db_type(self, connection):
            return 'integer UNSIGNED AUTO_INCREMENT'

        def rel_db_type(self, connection):
            return 'integer UNSIGNED'

.. versionadded:: 1.10

    The :meth:`~Field.rel_db_type` method was added.

.. _converting-values-to-python-objects:

Converting values to Python objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If your custom :class:`~Field` class deals with data structures that are more
complex than strings, dates, integers, or floats, then you may need to override
:meth:`~Field.from_db_value` and :meth:`~Field.to_python`.

If present for the field subclass, ``from_db_value()`` will be called in all
circumstances when the data is loaded from the database, including in
aggregates and :meth:`~django.db.models.query.QuerySet.values` calls.

``to_python()`` is called by deserialization and during the
:meth:`~django.db.models.Model.clean` method used from forms.

As a general rule, ``to_python()`` should deal gracefully with any of the
following arguments:

* An instance of the correct type (e.g., ``Hand`` in our ongoing example).

* A string

* ``None`` (if the field allows ``null=True``)

In our ``HandField`` class, we're storing the data as a VARCHAR field in the
database, so we need to be able to process strings and ``None`` in the
``from_db_value()``. In ``to_python()``, we need to also handle ``Hand``
instances::

    import re

    from django.core.exceptions import ValidationError
    from django.db import models
    from django.utils.translation import ugettext_lazy as _

    def parse_hand(hand_string):
        """Takes a string of cards and splits into a full hand."""
        p1 = re.compile('.{26}')
        p2 = re.compile('..')
        args = [p2.findall(x) for x in p1.findall(hand_string)]
        if len(args) != 4:
            raise ValidationError(_("Invalid input for a Hand instance"))
        return Hand(*args)

    class HandField(models.Field):
        # ...

        def from_db_value(self, value, expression, connection, context):
            if value is None:
                return value
            return parse_hand(value)

        def to_python(self, value):
            if isinstance(value, Hand):
                return value

            if value is None:
                return value

            return parse_hand(value)

Notice that we always return a ``Hand`` instance from these methods. That's the
Python object type we want to store in the model's attribute.

For ``to_python()``, if anything goes wrong during value conversion, you should
raise a :exc:`~django.core.exceptions.ValidationError` exception.

.. _converting-python-objects-to-query-values:

Converting Python objects to query values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Since using a database requires conversion in both ways, if you override
:meth:`~Field.to_python` you also have to override :meth:`~Field.get_prep_value`
to convert Python objects back to query values.

For example::

    class HandField(models.Field):
        # ...

        def get_prep_value(self, value):
            return ''.join([''.join(l) for l in (value.north,
                    value.east, value.south, value.west)])

.. warning::

    If your custom field uses the ``CHAR``, ``VARCHAR`` or ``TEXT``
    types for MySQL, you must make sure that :meth:`.get_prep_value`
    always returns a string type. MySQL performs flexible and unexpected
    matching when a query is performed on these types and the provided
    value is an integer, which can cause queries to include unexpected
    objects in their results. This problem cannot occur if you always
    return a string type from :meth:`.get_prep_value`.

.. _converting-query-values-to-database-values:

Converting query values to database values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Some data types (for example, dates) need to be in a specific format
before they can be used by a database backend.
:meth:`~Field.get_db_prep_value` is the method where those conversions should
be made. The specific connection that will be used for the query is
passed as the ``connection`` parameter. This allows you to use
backend-specific conversion logic if it is required.

For example, Django uses the following method for its
:class:`BinaryField`::

    def get_db_prep_value(self, value, connection, prepared=False):
        value = super(BinaryField, self).get_db_prep_value(value, connection, prepared)
        if value is not None:
            return connection.Database.Binary(value)
        return value

In case your custom field needs a special conversion when being saved that is
not the same as the conversion used for normal query parameters, you can
override :meth:`~Field.get_db_prep_save`.

.. _preprocessing-values-before-saving:

Preprocessing values before saving
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you want to preprocess the value just before saving, you can use
:meth:`~Field.pre_save`. For example, Django's
:class:`~django.db.models.DateTimeField` uses this method to set the attribute
correctly in the case of :attr:`~django.db.models.DateField.auto_now` or
:attr:`~django.db.models.DateField.auto_now_add`.

If you do override this method, you must return the value of the attribute at
the end. You should also update the model's attribute if you make any changes
to the value so that code holding references to the model will always see the
correct value.

.. _specifying-form-field-for-model-field:

Specifying the form field for a model field
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To customize the form field used by :class:`~django.forms.ModelForm`, you can
override :meth:`~Field.formfield`.

The form field class can be specified via the ``form_class`` and
``choices_form_class`` arguments; the latter is used if the field has choices
specified, the former otherwise. If these arguments are not provided,
:class:`~django.forms.CharField` or :class:`~django.forms.TypedChoiceField`
will be used.

All of the ``kwargs`` dictionary is passed directly to the form field's
``__init__()`` method. Normally, all you need to do is set up a good default
for the ``form_class`` (and maybe ``choices_form_class``) argument and then
delegate further handling to the parent class. This might require you to write
a custom form field (and even a form widget). See the :doc:`forms documentation
</topics/forms/index>` for information about this.

Continuing our ongoing example, we can write the :meth:`~Field.formfield` method
as::

    class HandField(models.Field):
        # ...

        def formfield(self, **kwargs):
            # This is a fairly standard way to set up some defaults
            # while letting the caller override them.
            defaults = {'form_class': MyFormField}
            defaults.update(kwargs)
            return super(HandField, self).formfield(**defaults)

This assumes we've imported a ``MyFormField`` field class (which has its own
default widget). This document doesn't cover the details of writing custom form
fields.

.. _helper functions: ../forms/#generating-forms-for-models
.. _forms documentation: ../forms/

.. _emulating-built-in-field-types:

Emulating built-in field types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you have created a :meth:`.db_type` method, you don't need to worry about
:meth:`.get_internal_type` -- it won't be used much. Sometimes, though, your
database storage is similar in type to some other field, so you can use that
other field's logic to create the right column.

For example::

    class HandField(models.Field):
        # ...

        def get_internal_type(self):
            return 'CharField'

No matter which database backend we are using, this will mean that
:djadmin:`migrate` and other SQL commands create the right column type for
storing a string.

If :meth:`.get_internal_type` returns a string that is not known to Django for
the database backend you are using -- that is, it doesn't appear in
``django.db.backends.<db_name>.base.DatabaseWrapper.data_types`` -- the string
will still be used by the serializer, but the default :meth:`~Field.db_type`
method will return ``None``. See the documentation of :meth:`~Field.db_type`
for reasons why this might be useful. Putting a descriptive string in as the
type of the field for the serializer is a useful idea if you're ever going to
be using the serializer output in some other place, outside of Django.

.. _converting-model-field-to-serialization:

Converting field data for serialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To customize how the values are serialized by a serializer, you can override
:meth:`~Field.value_to_string`. Using ``value_from_object()`` is the best way
to get the field's value prior to serialization. For example, since our
``HandField`` uses strings for its data storage anyway, we can reuse some
existing conversion code::

    class HandField(models.Field):
        # ...

        def value_to_string(self, obj):
            value = self.value_from_object(obj)
            return self.get_prep_value(value)

Some general advice
--------------------

Writing a custom field can be a tricky process, particularly if you're doing
complex conversions between your Python types and your database and
serialization formats. Here are a couple of tips to make things go more
smoothly:

1. Look at the existing Django fields (in
   :file:`django/db/models/fields/__init__.py`) for inspiration. Try to find
   a field that's similar to what you want and extend it a little bit,
   instead of creating an entirely new field from scratch.

2. Put a ``__str__()`` (``__unicode__()`` on Python 2) method on the class you're
   wrapping up as a field. There are a lot of places where the default
   behavior of the field code is to call
   :func:`~django.utils.encoding.force_text` on the value. (In our
   examples in this document, ``value`` would be a ``Hand`` instance, not a
   ``HandField``). So if your ``__str__()`` method (``__unicode__()`` on
   Python 2) automatically converts to the string form of your Python object,
   you can save yourself a lot of work.

Writing a ``FileField`` subclass
================================

In addition to the above methods, fields that deal with files have a few other
special requirements which must be taken into account. The majority of the
mechanics provided by ``FileField``, such as controlling database storage and
retrieval, can remain unchanged, leaving subclasses to deal with the challenge
of supporting a particular type of file.

Django provides a ``File`` class, which is used as a proxy to the file's
contents and operations. This can be subclassed to customize how the file is
accessed, and what methods are available. It lives at
``django.db.models.fields.files``, and its default behavior is explained in the
:doc:`file documentation </ref/files/file>`.

Once a subclass of ``File`` is created, the new ``FileField`` subclass must be
told to use it. To do so, simply assign the new ``File`` subclass to the special
``attr_class`` attribute of the ``FileField`` subclass.

A few suggestions
------------------

In addition to the above details, there are a few guidelines which can greatly
improve the efficiency and readability of the field's code.

1. The source for Django's own ``ImageField`` (in
   ``django/db/models/fields/files.py``) is a great example of how to
   subclass ``FileField`` to support a particular type of file, as it
   incorporates all of the techniques described above.

2. Cache file attributes wherever possible. Since files may be stored in
   remote storage systems, retrieving them may cost extra time, or even
   money, that isn't always necessary. Once a file is retrieved to obtain
   some data about its content, cache as much of that data as possible to
   reduce the number of times the file must be retrieved on subsequent
   calls for that information.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Custom Template Tags (`大一小学期/Week_3-Python/exam/2016/docs/howto/custom-template-tags.txt`)

================================
Custom template tags and filters
================================

Django's template language comes with a wide variety of :doc:`built-in
tags and filters </ref/templates/builtins>` designed to address the
presentation logic needs of your application. Nevertheless, you may
find yourself needing functionality that is not covered by the core
set of template primitives. You can extend the template engine by
defining custom tags and filters using Python, and then make them
available to your templates using the :ttag:`{% load %}<load>` tag.

Code layout
===========

The most common place to specify custom template tags and filters is inside
a Django app. If they relate to an existing app, it makes sense to bundle them
there; otherwise, they can be added to a new app. When a Django app is added
to :setting:`INSTALLED_APPS`, any tags it defines in the conventional location
described below are automatically made available to load within templates.

The app should contain a ``templatetags`` directory, at the same level as
``models.py``, ``views.py``, etc. If this doesn't already exist, create it -
don't forget the ``__init__.py`` file to ensure the directory is treated as a
Python package.

.. admonition:: Development server won't automatically restart

    After adding the ``templatetags``  module, you will need to restart your
    server before you can use the tags or filters in templates.

Your custom tags and filters will live in a module inside the ``templatetags``
directory. The name of the module file is the name you'll use to load the tags
later, so be careful to pick a name that won't clash with custom tags and
filters in another app.

For example, if your custom tags/filters are in a file called
``poll_extras.py``, your app layout might look like this::

    polls/
        __init__.py
        models.py
        templatetags/
            __init__.py
            poll_extras.py
        views.py

And in your template you would use the following:

.. code-block:: html+django

    {% load poll_extras %}

The app that contains the custom tags must be in :setting:`INSTALLED_APPS` in
order for the :ttag:`{% load %}<load>` tag to work. This is a security feature:
It allows you to host Python code for many template libraries on a single host
machine without enabling access to all of them for every Django installation.

There's no limit on how many modules you put in the ``templatetags`` package.
Just keep in mind that a :ttag:`{% load %}<load>` statement will load
tags/filters for the given Python module name, not the name of the app.

To be a valid tag library, the module must contain a module-level variable
named ``register`` that is a ``template.Library`` instance, in which all the
tags and filters are registered. So, near the top of your module, put the
following::

    from django import template

    register = template.Library()

.. versionadded:: 1.9

Alternatively, template tag modules can be registered through the
``'libraries'`` argument to
:class:`~django.template.backends.django.DjangoTemplates`. This is useful if
you want to use a different label from the template tag module name when
loading template tags. It also enables you to register tags without installing
an application.

.. admonition:: Behind the scenes

    For a ton of examples, read the source code for Django's default filters
    and tags. They're in ``django/template/defaultfilters.py`` and
    ``django/template/defaulttags.py``, respectively.

    For more information on the :ttag:`load` tag, read its documentation.

.. _howto-writing-custom-template-filters:

Writing custom template filters
===============================

Custom filters are just Python functions that take one or two arguments:

* The value of the variable (input) -- not necessarily a string.
* The value of the argument -- this can have a default value, or be left
  out altogether.

For example, in the filter ``{{ var|foo:"bar" }}``, the filter ``foo`` would be
passed the variable ``var`` and the argument ``"bar"``.

Since the template language doesn't provide exception handling, any exception
raised from a template filter will be exposed as a server error. Thus, filter
functions should avoid raising exceptions if there is a reasonable fallback
value to return. In case of input that represents a clear bug in a template,
raising an exception may still be better than silent failure which hides the
bug.

Here's an example filter definition::

    def cut(value, arg):
        """Removes all values of arg from the given string"""
        return value.replace(arg, '')

And here's an example of how that filter would be used:

.. code-block:: html+django

    {{ somevariable|cut:"0" }}

Most filters don't take arguments. In this case, just leave the argument out of
your function. Example::

    def lower(value): # Only one argument.
        """Converts a string into all lowercase"""
        return value.lower()

Registering custom filters
--------------------------

.. method:: django.template.Library.filter()

Once you've written your filter definition, you need to register it with
your ``Library`` instance, to make it available to Django's template language::

    register.filter('cut', cut)
    register.filter('lower', lower)

The ``Library.filter()`` method takes two arguments:

1. The name of the filter -- a string.
2. The compilation function -- a Python function (not the name of the
   function as a string).

You can use ``register.filter()`` as a decorator instead::

    @register.filter(name='cut')
    def cut(value, arg):
        return value.replace(arg, '')

    @register.filter
    def lower(value):
        return value.lower()

If you leave off the ``name`` argument, as in the second example above, Django
will use the function's name as the filter name.

Finally, ``register.filter()`` also accepts three keyword arguments,
``is_safe``, ``needs_autoescape``, and ``expects_localtime``. These arguments
are described in :ref:`filters and auto-escaping <filters-auto-escaping>` and
:ref:`filters and time zones <filters-timezones>` below.

Template filters that expect strings
------------------------------------

.. method:: django.template.defaultfilters.stringfilter()

If you're writing a template filter that only expects a string as the first
argument, you should use the decorator ``stringfilter``. This will
convert an object to its string value before being passed to your function::

    from django import template
    from django.template.defaultfilters import stringfilter

    register = template.Library()

    @register.filter
    @stringfilter
    def lower(value):
        return value.lower()

This way, you'll be able to pass, say, an integer to this filter, and it
won't cause an ``AttributeError`` (because integers don't have ``lower()``
methods).

.. _filters-auto-escaping:

Filters and auto-escaping
-------------------------

When writing a custom filter, give some thought to how the filter will interact
with Django's auto-escaping behavior. Note that three types of strings can be
passed around inside the template code:

* **Raw strings** are the native Python ``str`` or ``unicode`` types. On
  output, they're escaped if auto-escaping is in effect and presented
  unchanged, otherwise.

* **Safe strings** are strings that have been marked safe from further
  escaping at output time. Any necessary escaping has already been done.
  They're commonly used for output that contains raw HTML that is intended
  to be interpreted as-is on the client side.

  Internally, these strings are of type ``SafeBytes`` or ``SafeText``.
  They share a common base class of ``SafeData``, so you can test
  for them using code like::

      if isinstance(value, SafeData):
          # Do something with the "safe" string.
          ...

Template filter code falls into one of two situations:

1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
   ``'``, ``"`` or ``&``) into the result that were not already present. In
   this case, you can let Django take care of all the auto-escaping
   handling for you. All you need to do is set the ``is_safe`` flag to ``True``
   when you register your filter function, like so::

       @register.filter(is_safe=True)
       def myfilter(value):
           return value

   This flag tells Django that if a "safe" string is passed into your
   filter, the result will still be "safe" and if a non-safe string is
   passed in, Django will automatically escape it, if necessary.

   You can think of this as meaning "this filter is safe -- it doesn't
   introduce any possibility of unsafe HTML."

   The reason ``is_safe`` is necessary is because there are plenty of
   normal string operations that will turn a ``SafeData`` object back into
   a normal ``str`` or ``unicode`` object and, rather than try to catch
   them all, which would be very difficult, Django repairs the damage after
   the filter has completed.

   For example, suppose you have a filter that adds the string ``xx`` to
   the end of any input. Since this introduces no dangerous HTML characters
   to the result (aside from any that were already present), you should
   mark your filter with ``is_safe``::

       @register.filter(is_safe=True)
       def add_xx(value):
           return '%sxx' % value

   When this filter is used in a template where auto-escaping is enabled,
   Django will escape the output whenever the input is not already marked
   as "safe".

   By default, ``is_safe`` is ``False``, and you can omit it from any filters
   where it isn't required.

   Be careful when deciding if your filter really does leave safe strings
   as safe. If you're *removing* characters, you might inadvertently leave
   unbalanced HTML tags or entities in the result. For example, removing a
   ``>`` from the input might turn ``<a>`` into ``<a``, which would need to
   be escaped on output to avoid causing problems. Similarly, removing a
   semicolon (``;``) can turn ``&amp;`` into ``&amp``, which is no longer a
   valid entity and thus needs further escaping. Most cases won't be nearly
   this tricky, but keep an eye out for any problems like that when
   reviewing your code.

   Marking a filter ``is_safe`` will coerce the filter's return value to
   a string.  If your filter should return a boolean or other non-string
   value, marking it ``is_safe`` will probably have unintended
   consequences (such as converting a boolean False to the string
   'False').

2. Alternatively, your filter code can manually take care of any necessary
   escaping. This is necessary when you're introducing new HTML markup into
   the result. You want to mark the output as safe from further
   escaping so that your HTML markup isn't escaped further, so you'll need
   to handle the input yourself.

   To mark the output as a safe string, use
   :func:`django.utils.safestring.mark_safe`.

   Be careful, though. You need to do more than just mark the output as
   safe. You need to ensure it really *is* safe, and what you do depends on
   whether auto-escaping is in effect. The idea is to write filters that
   can operate in templates where auto-escaping is either on or off in
   order to make things easier for your template authors.

   In order for your filter to know the current auto-escaping state, set the
   ``needs_autoescape`` flag to ``True`` when you register your filter function.
   (If you don't specify this flag, it defaults to ``False``). This flag tells
   Django that your filter function wants to be passed an extra keyword
   argument, called ``autoescape``, that is ``True`` if auto-escaping is in
   effect and ``False`` otherwise. It is recommended to set the default of the
   ``autoescape`` parameter to ``True``, so that if you call the function
   from Python code it will have escaping enabled by default.

   For example, let's write a filter that emphasizes the first character of
   a string::

      from django import template
      from django.utils.html import conditional_escape
      from django.utils.safestring import mark_safe

      register = template.Library()

      @register.filter(needs_autoescape=True)
      def initial_letter_filter(text, autoescape=True):
          first, other = text[0], text[1:]
          if autoescape:
              esc = conditional_escape
          else:
              esc = lambda x: x
          result = '<strong>%s</strong>%s' % (esc(first), esc(other))
          return mark_safe(result)

   The ``needs_autoescape`` flag and the ``autoescape`` keyword argument mean
   that our function will know whether automatic escaping is in effect when the
   filter is called. We use ``autoescape`` to decide whether the input data
   needs to be passed through ``django.utils.html.conditional_escape`` or not.
   (In the latter case, we just use the identity function as the "escape"
   function.) The ``conditional_escape()`` function is like ``escape()`` except
   it only escapes input that is **not** a ``SafeData`` instance. If a
   ``SafeData`` instance is passed to ``conditional_escape()``, the data is
   returned unchanged.

   Finally, in the above example, we remember to mark the result as safe
   so that our HTML is inserted directly into the template without further
   escaping.

   There's no need to worry about the ``is_safe`` flag in this case
   (although including it wouldn't hurt anything). Whenever you manually
   handle the auto-escaping issues and return a safe string, the
   ``is_safe`` flag won't change anything either way.

.. warning:: Avoiding XSS vulnerabilities when reusing built-in filters

    Django's built-in filters have ``autoescape=True`` by default in order to
    get the proper autoescaping behavior and avoid a cross-site script
    vulnerability.

    In older versions of Django, be careful when reusing Django's built-in
    filters as ``autoescape`` defaults to ``None``. You'll need to pass
    ``autoescape=True`` to get autoescaping.

    For example, if you wanted to write a custom filter called
    ``urlize_and_linebreaks`` that combined the :tfilter:`urlize` and
    :tfilter:`linebreaksbr` filters, the filter would look like::

        from django.template.defaultfilters import linebreaksbr, urlize

        @register.filter(needs_autoescape=True)
        def urlize_and_linebreaks(text, autoescape=True):
            return linebreaksbr(
                urlize(text, autoescape=autoescape),
                autoescape=autoescape
            )

    Then:

    .. code-block:: html+django

        {{ comment|urlize_and_linebreaks }}

    would be equivalent to:

    .. code-block:: html+django

        {{ comment|urlize|linebreaksbr }}

.. _filters-timezones:

Filters and time zones
----------------------

If you write a custom filter that operates on :class:`~datetime.datetime`
objects, you'll usually register it with the ``expects_localtime`` flag set to
``True``::

    @register.filter(expects_localtime=True)
    def businesshours(value):
        try:
            return 9 <= value.hour < 17
        except AttributeError:
            return ''

When this flag is set, if the first argument to your filter is a time zone
aware datetime, Django will convert it to the current time zone before passing
it to your filter when appropriate, according to :ref:`rules for time zones
conversions in templates <time-zones-in-templates>`.

.. _howto-writing-custom-template-tags:

Writing custom template tags
============================

Tags are more complex than filters, because tags can do anything. Django
provides a number of shortcuts that make writing most types of tags easier.
First we'll explore those shortcuts, then explain how to write a tag from
scratch for those cases when the shortcuts aren't powerful enough.

.. _howto-custom-template-tags-simple-tags:

Simple tags
-----------

.. method:: django.template.Library.simple_tag()

Many template tags take a number of arguments -- strings or template variables
-- and return a result after doing some processing based solely on
the input arguments and some external information. For example, a
``current_time`` tag might accept a format string and return the time as a
string formatted accordingly.

To ease the creation of these types of tags, Django provides a helper function,
``simple_tag``. This function, which is a method of
``django.template.Library``, takes a function that accepts any number of
arguments, wraps it in a ``render`` function and the other necessary bits
mentioned above and registers it with the template system.

Our ``current_time`` function could thus be written like this::

    import datetime
    from django import template

    register = template.Library()

    @register.simple_tag
    def current_time(format_string):
        return datetime.datetime.now().strftime(format_string)

A few things to note about the ``simple_tag`` helper function:

* Checking for the required number of arguments, etc., has already been
  done by the time our function is called, so we don't need to do that.
* The quotes around the argument (if any) have already been stripped away,
  so we just receive a plain string.
* If the argument was a template variable, our function is passed the
  current value of the variable, not the variable itself.

Unlike other tag utilities, ``simple_tag`` passes its output through
:func:`~django.utils.html.conditional_escape` if the template context is in
autoescape mode, to ensure correct HTML and protect you from XSS
vulnerabilities.

If additional escaping is not desired, you will need to use
:func:`~django.utils.safestring.mark_safe` if you are absolutely sure that your
code does not contain XSS vulnerabilities. For building small HTML snippets,
use of :func:`~django.utils.html.format_html` instead of ``mark_safe()`` is
strongly recommended.

.. versionchanged:: 1.9

   Auto-escaping for ``simple_tag`` as described in the previous two paragraphs
   was added.

If your template tag needs to access the current context, you can use the
``takes_context`` argument when registering your tag::

    @register.simple_tag(takes_context=True)
    def current_time(context, format_string):
        timezone = context['timezone']
        return your_get_current_time_method(timezone, format_string)

Note that the first argument *must* be called ``context``.

For more information on how the ``takes_context`` option works, see the section
on :ref:`inclusion tags<howto-custom-template-tags-inclusion-tags>`.

If you need to rename your tag, you can provide a custom name for it::

    register.simple_tag(lambda x: x - 1, name='minusone')

    @register.simple_tag(name='minustwo')
    def some_function(value):
        return value - 2

``simple_tag`` functions may accept any number of positional or keyword
arguments. For example::

    @register.simple_tag
    def my_tag(a, b, *args, **kwargs):
        warning = kwargs['warning']
        profile = kwargs['profile']
        ...
        return ...

Then in the template any number of arguments, separated by spaces, may be
passed to the template tag. Like in Python, the values for keyword arguments
are set using the equal sign ("``=``") and must be provided after the
positional arguments. For example:

.. code-block:: html+django

    {% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}

.. versionadded:: 1.9

It's possible to store the tag results in a template variable rather than
directly outputting it. This is done by using the ``as`` argument followed by
the variable name. Doing so enables you to output the content yourself where
you see fit:

.. code-block:: html+django

    {% get_current_time "%Y-%m-%d %I:%M %p" as the_time %}
    <p>The time is {{ the_time }}.</p>

.. _howto-custom-template-tags-inclusion-tags:

Inclusion tags
--------------

.. method:: django.template.Library.inclusion_tag()

Another common type of template tag is the type that displays some data by
rendering *another* template. For example, Django's admin interface uses custom
template tags to display the buttons along the bottom of the "add/change" form
pages. Those buttons always look the same, but the link targets change
depending on the object being edited -- so they're a perfect case for using a
small template that is filled with details from the current object. (In the
admin's case, this is the ``submit_row`` tag.)

These sorts of tags are called "inclusion tags".

Writing inclusion tags is probably best demonstrated by example. Let's write a
tag that outputs a list of choices for a given ``Poll`` object, such as was
created in the :ref:`tutorials <creating-models>`. We'll use the tag like this:

.. code-block:: html+django

    {% show_results poll %}

...and the output will be something like this:

.. code-block:: html

    <ul>
      <li>First choice</li>
      <li>Second choice</li>
      <li>Third choice</li>
    </ul>

First, define the function that takes the argument and produces a dictionary of
data for the result. The important point here is we only need to return a
dictionary, not anything more complex. This will be used as a template context
for the template fragment. Example::

    def show_results(poll):
        choices = poll.choice_set.all()
        return {'choices': choices}

Next, create the template used to render the tag's output. This template is a
fixed feature of the tag: the tag writer specifies it, not the template
designer. Following our example, the template is very simple:

.. code-block:: html+django

    <ul>
    {% for choice in choices %}
        <li> {{ choice }} </li>
    {% endfor %}
    </ul>

Now, create and register the inclusion tag by calling the ``inclusion_tag()``
method on a ``Library`` object. Following our example, if the above template is
in a file called ``results.html`` in a directory that's searched by the
template loader, we'd register the tag like this::

    # Here, register is a django.template.Library instance, as before
    @register.inclusion_tag('results.html')
    def show_results(poll):
        ...

Alternatively it is possible to register the inclusion tag using a
:class:`django.template.Template` instance::

    from django.template.loader import get_template
    t = get_template('results.html')
    register.inclusion_tag(t)(show_results)

...when first creating the function.

Sometimes, your inclusion tags might require a large number of arguments,
making it a pain for template authors to pass in all the arguments and remember
their order. To solve this, Django provides a ``takes_context`` option for
inclusion tags. If you specify ``takes_context`` in creating a template tag,
the tag will have no required arguments, and the underlying Python function
will have one argument -- the template context as of when the tag was called.

For example, say you're writing an inclusion tag that will always be used in a
context that contains ``home_link`` and ``home_title`` variables that point
back to the main page. Here's what the Python function would look like::

    @register.inclusion_tag('link.html', takes_context=True)
    def jump_link(context):
        return {
            'link': context['home_link'],
            'title': context['home_title'],
        }

Note that the first parameter to the function *must* be called ``context``.

In that ``register.inclusion_tag()`` line, we specified ``takes_context=True``
and the name of the template. Here's what the template ``link.html`` might look
like:

.. code-block:: html+django

    Jump directly to <a href="{{ link }}">{{ title }}</a>.

Then, any time you want to use that custom tag, load its library and call it
without any arguments, like so:

.. code-block:: html+django

    {% jump_link %}

Note that when you're using ``takes_context=True``, there's no need to pass
arguments to the template tag. It automatically gets access to the context.

The ``takes_context`` parameter defaults to ``False``. When it's set to
``True``, the tag is passed the context object, as in this example. That's the
only difference between this case and the previous ``inclusion_tag`` example.

``inclusion_tag`` functions may accept any number of positional or keyword
arguments. For example::

    @register.inclusion_tag('my_template.html')
    def my_tag(a, b, *args, **kwargs):
        warning = kwargs['warning']
        profile = kwargs['profile']
        ...
        return ...

Then in the template any number of arguments, separated by spaces, may be
passed to the template tag. Like in Python, the values for keyword arguments
are set using the equal sign ("``=``") and must be provided after the
positional arguments. For example:

.. code-block:: html+django

    {% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}

Assignment tags
---------------

.. method:: django.template.Library.assignment_tag()

.. deprecated:: 1.9

    ``simple_tag`` can now store results in a template variable and should
    be used instead.

To ease the creation of tags setting a variable in the context, Django provides
a helper function, ``assignment_tag``. This function works the same way as
:meth:`~django.template.Library.simple_tag` except that it stores the tag's
result in a specified context variable instead of directly outputting it.

Our earlier ``current_time`` function could thus be written like this::

    @register.assignment_tag
    def get_current_time(format_string):
        return datetime.datetime.now().strftime(format_string)

You may then store the result in a template variable using the ``as`` argument
followed by the variable name, and output it yourself where you see fit:

.. code-block:: html+django

    {% get_current_time "%Y-%m-%d %I:%M %p" as the_time %}
    <p>The time is {{ the_time }}.</p>

Advanced custom template tags
-----------------------------

Sometimes the basic features for custom template tag creation aren't enough.
Don't worry, Django gives you complete access to the internals required to build
a template tag from the ground up.

A quick overview
----------------

The template system works in a two-step process: compiling and rendering. To
define a custom template tag, you specify how the compilation works and how
the rendering works.

When Django compiles a template, it splits the raw template text into
''nodes''. Each node is an instance of ``django.template.Node`` and has
a ``render()`` method. A compiled template is, simply, a list of ``Node``
objects. When you call ``render()`` on a compiled template object, the template
calls ``render()`` on each ``Node`` in its node list, with the given context.
The results are all concatenated together to form the output of the template.

Thus, to define a custom template tag, you specify how the raw template tag is
converted into a ``Node`` (the compilation function), and what the node's
``render()`` method does.

Writing the compilation function
--------------------------------

For each template tag the template parser encounters, it calls a Python
function with the tag contents and the parser object itself. This function is
responsible for returning a ``Node`` instance based on the contents of the tag.

For example, let's write a full implementation of our simple template tag,
``{% current_time %}``, that displays the current date/time, formatted according
to a parameter given in the tag, in :func:`~time.strftime` syntax. It's a good
idea to decide the tag syntax before anything else. In our case, let's say the
tag should be used like this:

.. code-block:: html+django

    <p>The time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p>

The parser for this function should grab the parameter and create a ``Node``
object::

    from django import template

    def do_current_time(parser, token):
        try:
            # split_contents() knows not to split quoted strings.
            tag_name, format_string = token.split_contents()
        except ValueError:
            raise template.TemplateSyntaxError(
                "%r tag requires a single argument" % token.contents.split()[0]
            )
        if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
            raise template.TemplateSyntaxError(
                "%r tag's argument should be in quotes" % tag_name
            )
        return CurrentTimeNode(format_string[1:-1])

Notes:

* ``parser`` is the template parser object. We don't need it in this
  example.

* ``token.contents`` is a string of the raw contents of the tag. In our
  example, it's ``'current_time "%Y-%m-%d %I:%M %p"'``.

* The ``token.split_contents()`` method separates the arguments on spaces
  while keeping quoted strings together. The more straightforward
  ``token.contents.split()`` wouldn't be as robust, as it would naively
  split on *all* spaces, including those within quoted strings. It's a good
  idea to always use ``token.split_contents()``.

* This function is responsible for raising
  ``django.template.TemplateSyntaxError``, with helpful messages, for
  any syntax error.

* The ``TemplateSyntaxError`` exceptions use the ``tag_name`` variable.
  Don't hard-code the tag's name in your error messages, because that
  couples the tag's name to your function. ``token.contents.split()[0]``
  will ''always'' be the name of your tag -- even when the tag has no
  arguments.

* The function returns a ``CurrentTimeNode`` with everything the node needs
  to know about this tag. In this case, it just passes the argument --
  ``"%Y-%m-%d %I:%M %p"``. The leading and trailing quotes from the
  template tag are removed in ``format_string[1:-1]``.

* The parsing is very low-level. The Django developers have experimented
  with writing small frameworks on top of this parsing system, using
  techniques such as EBNF grammars, but those experiments made the template
  engine too slow. It's low-level because that's fastest.

Writing the renderer
--------------------

The second step in writing custom tags is to define a ``Node`` subclass that
has a ``render()`` method.

Continuing the above example, we need to define ``CurrentTimeNode``::

    import datetime
    from django import template

    class CurrentTimeNode(template.Node):
        def __init__(self, format_string):
            self.format_string = format_string

        def render(self, context):
            return datetime.datetime.now().strftime(self.format_string)

Notes:

* ``__init__()`` gets the ``format_string`` from ``do_current_time()``.
  Always pass any options/parameters/arguments to a ``Node`` via its
  ``__init__()``.

* The ``render()`` method is where the work actually happens.

* ``render()`` should generally fail silently, particularly in a production
  environment. In some cases however, particularly if
  ``context.template.engine.debug`` is ``True``, this method may raise an
  exception to make debugging easier. For example, several core tags raise
  ``django.template.TemplateSyntaxError`` if they receive the wrong number or
  type of arguments.

Ultimately, this decoupling of compilation and rendering results in an
efficient template system, because a template can render multiple contexts
without having to be parsed multiple times.

.. _tags-auto-escaping:

Auto-escaping considerations
----------------------------

The output from template tags is **not** automatically run through the
auto-escaping filters (with the exception of
:meth:`~django.template.Library.simple_tag` as described above). However, there
are still a couple of things you should keep in mind when writing a template
tag.

If the ``render()`` function of your template stores the result in a context
variable (rather than returning the result in a string), it should take care
to call ``mark_safe()`` if appropriate. When the variable is ultimately
rendered, it will be affected by the auto-escape setting in effect at the
time, so content that should be safe from further escaping needs to be marked
as such.

Also, if your template tag creates a new context for performing some
sub-rendering, set the auto-escape attribute to the current context's value.
The ``__init__`` method for the ``Context`` class takes a parameter called
``autoescape`` that you can use for this purpose. For example::

    from django.template import Context

    def render(self, context):
        # ...
        new_context = Context({'var': obj}, autoescape=context.autoescape)
        # ... Do something with new_context ...

This is not a very common situation, but it's useful if you're rendering a
template yourself. For example::

    def render(self, context):
        t = context.template.engine.get_template('small_fragment.html')
        return t.render(Context({'var': obj}, autoescape=context.autoescape))

If we had neglected to pass in the current ``context.autoescape`` value to our
new ``Context`` in this example, the results would have *always* been
automatically escaped, which may not be the desired behavior if the template
tag is used inside a :ttag:`{% autoescape off %}<autoescape>` block.

.. _template_tag_thread_safety:

Thread-safety considerations
----------------------------

Once a node is parsed, its ``render`` method may be called any number of times.
Since Django is sometimes run in multi-threaded environments, a single node may
be simultaneously rendering with different contexts in response to two separate
requests. Therefore, it's important to make sure your template tags are thread
safe.

To make sure your template tags are thread safe, you should never store state
information on the node itself. For example, Django provides a builtin
:ttag:`cycle` template tag that cycles among a list of given strings each time
it's rendered:

.. code-block:: html+django

    {% for o in some_list %}
        <tr class="{% cycle 'row1' 'row2' %}">
            ...
        </tr>
    {% endfor %}

A naive implementation of ``CycleNode`` might look something like this::

    import itertools
    from django import template

    class CycleNode(template.Node):
        def __init__(self, cyclevars):
            self.cycle_iter = itertools.cycle(cyclevars)

        def render(self, context):
            return next(self.cycle_iter)

But, suppose we have two templates rendering the template snippet from above at
the same time:

1. Thread 1 performs its first loop iteration, ``CycleNode.render()``
   returns 'row1'
2. Thread 2 performs its first loop iteration, ``CycleNode.render()``
   returns 'row2'
3. Thread 1 performs its second loop iteration, ``CycleNode.render()``
   returns 'row1'
4. Thread 2 performs its second loop iteration, ``CycleNode.render()``
   returns 'row2'

The CycleNode is iterating, but it's iterating globally. As far as Thread 1
and Thread 2 are concerned, it's always returning the same value. This is
obviously not what we want!

To address this problem, Django provides a ``render_context`` that's associated
with the ``context`` of the template that is currently being rendered. The
``render_context`` behaves like a Python dictionary, and should be used to
store ``Node`` state between invocations of the ``render`` method.

Let's refactor our ``CycleNode`` implementation to use the ``render_context``::

    class CycleNode(template.Node):
        def __init__(self, cyclevars):
            self.cyclevars = cyclevars

        def render(self, context):
            if self not in context.render_context:
                context.render_context[self] = itertools.cycle(self.cyclevars)
            cycle_iter = context.render_context[self]
            return next(cycle_iter)

Note that it's perfectly safe to store global information that will not change
throughout the life of the ``Node`` as an attribute. In the case of
``CycleNode``, the ``cyclevars`` argument doesn't change after the ``Node`` is
instantiated, so we don't need to put it in the ``render_context``. But state
information that is specific to the template that is currently being rendered,
like the current iteration of the ``CycleNode``, should be stored in the
``render_context``.

.. note::
    Notice how we used ``self`` to scope the ``CycleNode`` specific information
    within the ``render_context``. There may be multiple ``CycleNodes`` in a
    given template, so we need to be careful not to clobber another node's
    state information. The easiest way to do this is to always use ``self`` as
    the key into ``render_context``. If you're keeping track of several state
    variables, make ``render_context[self]`` a dictionary.

Registering the tag
-------------------

Finally, register the tag with your module's ``Library`` instance, as explained
in :ref:`writing custom template filters<howto-writing-custom-template-tags>`
above. Example::

    register.tag('current_time', do_current_time)

The ``tag()`` method takes two arguments:

1. The name of the template tag -- a string. If this is left out, the
   name of the compilation function will be used.
2. The compilation function -- a Python function (not the name of the
   function as a string).

As with filter registration, it is also possible to use this as a decorator::

    @register.tag(name="current_time")
    def do_current_time(parser, token):
        ...

    @register.tag
    def shout(parser, token):
        ...

If you leave off the ``name`` argument, as in the second example above, Django
will use the function's name as the tag name.

Passing template variables to the tag
-------------------------------------

Although you can pass any number of arguments to a template tag using
``token.split_contents()``, the arguments are all unpacked as
string literals. A little more work is required in order to pass dynamic
content (a template variable) to a template tag as an argument.

While the previous examples have formatted the current time into a string and
returned the string, suppose you wanted to pass in a
:class:`~django.db.models.DateTimeField` from an object and have the template
tag format that date-time:

.. code-block:: html+django

    <p>This post was last updated at {% format_time blog_entry.date_updated "%Y-%m-%d %I:%M %p" %}.</p>

Initially, ``token.split_contents()`` will return three values:

1. The tag name ``format_time``.
2. The string ``'blog_entry.date_updated'`` (without the surrounding
   quotes).
3. The formatting string ``'"%Y-%m-%d %I:%M %p"'``. The return value from
   ``split_contents()`` will include the leading and trailing quotes for
   string literals like this.

Now your tag should begin to look like this::

    from django import template

    def do_format_time(parser, token):
        try:
            # split_contents() knows not to split quoted strings.
            tag_name, date_to_be_formatted, format_string = token.split_contents()
        except ValueError:
            raise template.TemplateSyntaxError(
                "%r tag requires exactly two arguments" % token.contents.split()[0]
            )
        if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
            raise template.TemplateSyntaxError(
                "%r tag's argument should be in quotes" % tag_name
            )
        return FormatTimeNode(date_to_be_formatted, format_string[1:-1])

You also have to change the renderer to retrieve the actual contents of the
``date_updated`` property of the ``blog_entry`` object.  This can be
accomplished by using the ``Variable()`` class in ``django.template``.

To use the ``Variable`` class, simply instantiate it with the name of the
variable to be resolved, and then call ``variable.resolve(context)``. So,
for example::

    class FormatTimeNode(template.Node):
        def __init__(self, date_to_be_formatted, format_string):
            self.date_to_be_formatted = template.Variable(date_to_be_formatted)
            self.format_string = format_string

        def render(self, context):
            try:
                actual_date = self.date_to_be_formatted.resolve(context)
                return actual_date.strftime(self.format_string)
            except template.VariableDoesNotExist:
                return ''

Variable resolution will throw a ``VariableDoesNotExist`` exception if it
cannot resolve the string passed to it in the current context of the page.

Setting a variable in the context
---------------------------------

The above examples simply output a value. Generally, it's more flexible if your
template tags set template variables instead of outputting values. That way,
template authors can reuse the values that your template tags create.

To set a variable in the context, just use dictionary assignment on the context
object in the ``render()`` method. Here's an updated version of
``CurrentTimeNode`` that sets a template variable ``current_time`` instead of
outputting it::

    import datetime
    from django import template

    class CurrentTimeNode2(template.Node):
        def __init__(self, format_string):
            self.format_string = format_string
        def render(self, context):
            context['current_time'] = datetime.datetime.now().strftime(self.format_string)
            return ''

Note that ``render()`` returns the empty string. ``render()`` should always
return string output. If all the template tag does is set a variable,
``render()`` should return the empty string.

Here's how you'd use this new version of the tag:

.. code-block:: html+django

    {% current_time "%Y-%M-%d %I:%M %p" %}<p>The time is {{ current_time }}.</p>

.. admonition:: Variable scope in context

    Any variable set in the context will only be available in the same
    ``block`` of the template in which it was assigned. This behavior is
    intentional; it provides a scope for variables so that they don't conflict
    with context in other blocks.

But, there's a problem with ``CurrentTimeNode2``: The variable name
``current_time`` is hard-coded. This means you'll need to make sure your
template doesn't use ``{{ current_time }}`` anywhere else, because the
``{% current_time %}`` will blindly overwrite that variable's value. A cleaner
solution is to make the template tag specify the name of the output variable,
like so:

.. code-block:: html+django

    {% current_time "%Y-%M-%d %I:%M %p" as my_current_time %}
    <p>The current time is {{ my_current_time }}.</p>

To do that, you'll need to refactor both the compilation function and ``Node``
class, like so::

    import re

    class CurrentTimeNode3(template.Node):
        def __init__(self, format_string, var_name):
            self.format_string = format_string
            self.var_name = var_name
        def render(self, context):
            context[self.var_name] = datetime.datetime.now().strftime(self.format_string)
            return ''

    def do_current_time(parser, token):
        # This version uses a regular expression to parse tag contents.
        try:
            # Splitting by None == splitting by spaces.
            tag_name, arg = token.contents.split(None, 1)
        except ValueError:
            raise template.TemplateSyntaxError(
                "%r tag requires arguments" % token.contents.split()[0]
            )
        m = re.search(r'(.*?) as (\w+)', arg)
        if not m:
            raise template.TemplateSyntaxError("%r tag had invalid arguments" % tag_name)
        format_string, var_name = m.groups()
        if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
            raise template.TemplateSyntaxError(
                "%r tag's argument should be in quotes" % tag_name
            )
        return CurrentTimeNode3(format_string[1:-1], var_name)

The difference here is that ``do_current_time()`` grabs the format string and
the variable name, passing both to ``CurrentTimeNode3``.

Finally, if you only need to have a simple syntax for your custom
context-updating template tag, consider using the
:meth:`~django.template.Library.simple_tag` shortcut, which supports assigning
the tag results to a template variable.

Parsing until another block tag
-------------------------------

Template tags can work in tandem. For instance, the standard
:ttag:`{% comment %}<comment>` tag hides everything until ``{% endcomment %}``.
To create a template tag such as this, use ``parser.parse()`` in your
compilation function.

Here's how a simplified ``{% comment %}`` tag might be implemented::

    def do_comment(parser, token):
        nodelist = parser.parse(('endcomment',))
        parser.delete_first_token()
        return CommentNode()

    class CommentNode(template.Node):
        def render(self, context):
            return ''

.. note::
    The actual implementation of :ttag:`{% comment %}<comment>` is slightly
    different in that it allows broken template tags to appear between
    ``{% comment %}`` and ``{% endcomment %}``. It does so by calling
    ``parser.skip_past('endcomment')`` instead of ``parser.parse(('endcomment',))``
    followed by ``parser.delete_first_token()``, thus avoiding the generation of a
    node list.

``parser.parse()`` takes a tuple of names of block tags ''to parse until''. It
returns an instance of ``django.template.NodeList``, which is a list of
all ``Node`` objects that the parser encountered ''before'' it encountered
any of the tags named in the tuple.

In ``"nodelist = parser.parse(('endcomment',))"`` in the above example,
``nodelist`` is a list of all nodes between the ``{% comment %}`` and
``{% endcomment %}``, not counting ``{% comment %}`` and ``{% endcomment %}``
themselves.

After ``parser.parse()`` is called, the parser hasn't yet "consumed" the
``{% endcomment %}`` tag, so the code needs to explicitly call
``parser.delete_first_token()``.

``CommentNode.render()`` simply returns an empty string. Anything between
``{% comment %}`` and ``{% endcomment %}`` is ignored.

Parsing until another block tag, and saving contents
----------------------------------------------------

In the previous example, ``do_comment()`` discarded everything between
``{% comment %}`` and ``{% endcomment %}``. Instead of doing that, it's
possible to do something with the code between block tags.

For example, here's a custom template tag, ``{% upper %}``, that capitalizes
everything between itself and ``{% endupper %}``.

Usage:

.. code-block:: html+django

    {% upper %}This will appear in uppercase, {{ your_name }}.{% endupper %}

As in the previous example, we'll use ``parser.parse()``. But this time, we
pass the resulting ``nodelist`` to the ``Node``::

    def do_upper(parser, token):
        nodelist = parser.parse(('endupper',))
        parser.delete_first_token()
        return UpperNode(nodelist)

    class UpperNode(template.Node):
        def __init__(self, nodelist):
            self.nodelist = nodelist
        def render(self, context):
            output = self.nodelist.render(context)
            return output.upper()

The only new concept here is the ``self.nodelist.render(context)`` in
``UpperNode.render()``.

For more examples of complex rendering, see the source code of
:ttag:`{% for %}<for>` in ``django/template/defaulttags.py`` and
:ttag:`{% if %}<if>` in ``django/template/smartif.py``.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Error Reporting (`大一小学期/Week_3-Python/exam/2016/docs/howto/error-reporting.txt`)

===============
Error reporting
===============

When you're running a public site you should always turn off the
:setting:`DEBUG` setting. That will make your server run much faster, and will
also prevent malicious users from seeing details of your application that can be
revealed by the error pages.

However, running with :setting:`DEBUG` set to ``False`` means you'll never see
errors generated by your site -- everyone will just see your public error pages.
You need to keep track of errors that occur in deployed sites, so Django can be
configured to create reports with details about those errors.

Email reports
=============

Server errors
-------------

When :setting:`DEBUG` is ``False``, Django will email the users listed in the
:setting:`ADMINS` setting whenever your code raises an unhandled exception and
results in an internal server error (HTTP status code 500). This gives the
administrators immediate notification of any errors. The :setting:`ADMINS` will
get a description of the error, a complete Python traceback, and details about
the HTTP request that caused the error.

.. note::

   In order to send email, Django requires a few settings telling it
   how to connect to your mail server. At the very least, you'll need
   to specify :setting:`EMAIL_HOST` and possibly
   :setting:`EMAIL_HOST_USER` and :setting:`EMAIL_HOST_PASSWORD`,
   though other settings may be also required depending on your mail
   server's configuration. Consult :doc:`the Django settings
   documentation </ref/settings>` for a full list of email-related
   settings.

By default, Django will send email from root@localhost. However, some mail
providers reject all email from this address. To use a different sender
address, modify the :setting:`SERVER_EMAIL` setting.

To activate this behavior, put the email addresses of the recipients in the
:setting:`ADMINS` setting.

.. seealso::

    Server error emails are sent using the logging framework, so you can
    customize this behavior by :doc:`customizing your logging configuration
    </topics/logging>`.

404 errors
----------

Django can also be configured to email errors about broken links (404 "page
not found" errors). Django sends emails about 404 errors when:

* :setting:`DEBUG` is ``False``;

* Your :setting:`MIDDLEWARE` setting includes
  :class:`django.middleware.common.BrokenLinkEmailsMiddleware`.

If those conditions are met, Django will email the users listed in the
:setting:`MANAGERS` setting whenever your code raises a 404 and the request has
a referer. It doesn't bother to email for 404s that don't have a referer --
those are usually just people typing in broken URLs or broken Web bots. It also
ignores 404s when the referer is equal to the requested URL, since this
behavior is from broken Web bots too.

.. versionchanged:: 1.9

    In older versions, 404s were not ignored when the referer was equal to the
    requested URL.

.. note::

    :class:`~django.middleware.common.BrokenLinkEmailsMiddleware` must appear
    before other middleware that intercepts 404 errors, such as
    :class:`~django.middleware.locale.LocaleMiddleware` or
    :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware`.
    Put it towards the top of your :setting:`MIDDLEWARE` setting.

You can tell Django to stop reporting particular 404s by tweaking the
:setting:`IGNORABLE_404_URLS` setting. It should be a list of compiled
regular expression objects. For example::

    import re
    IGNORABLE_404_URLS = [
        re.compile(r'\.(php|cgi)$'),
        re.compile(r'^/phpmyadmin/'),
    ]

In this example, a 404 to any URL ending with ``.php`` or ``.cgi`` will *not* be
reported. Neither will any URL starting with ``/phpmyadmin/``.

The following example shows how to exclude some conventional URLs that browsers and
crawlers often request::

    import re
    IGNORABLE_404_URLS = [
        re.compile(r'^/apple-touch-icon.*\.png$'),
        re.compile(r'^/favicon\.ico$'),
        re.compile(r'^/robots\.txt$'),
    ]

(Note that these are regular expressions, so we put a backslash in front of
periods to escape them.)

If you'd like to customize the behavior of
:class:`django.middleware.common.BrokenLinkEmailsMiddleware` further (for
example to ignore requests coming from web crawlers), you should subclass it
and override its methods.

.. seealso::

    404 errors are logged using the logging framework. By default, these log
    records are ignored, but you can use them for error reporting by writing a
    handler and :doc:`configuring logging </topics/logging>` appropriately.

.. _filtering-error-reports:

Filtering error reports
=======================

.. warning::

    Filtering sensitive data is a hard problem, and it's nearly impossible to
    guarantee that sensitive won't leak into an error report. Therefore, error
    reports should only be available to trusted team members and you should
    avoid transmitting error reports unencrypted over the Internet (such as
    through email).

Filtering sensitive information
-------------------------------

.. currentmodule:: django.views.decorators.debug

Error reports are really helpful for debugging errors, so it is generally
useful to record as much relevant information about those errors as possible.
For example, by default Django records the `full traceback`_ for the
exception raised, each `traceback frame`_’s local variables, and the
:class:`~django.http.HttpRequest`’s :ref:`attributes<httprequest-attributes>`.

However, sometimes certain types of information may be too sensitive and thus
may not be appropriate to be kept track of, for example a user's password or
credit card number. So in addition to filtering out settings that appear to be
sensitive as described in the :setting:`DEBUG` documentation, Django offers a
set of function decorators to help you control which information should be
filtered out of error reports in a production environment (that is, where
:setting:`DEBUG` is set to ``False``): :func:`sensitive_variables` and
:func:`sensitive_post_parameters`.

.. _`full traceback`: https://en.wikipedia.org/wiki/Stack_trace
.. _`traceback frame`: https://en.wikipedia.org/wiki/Stack_frame

.. function:: sensitive_variables(*variables)

    If a function (either a view or any regular callback) in your code uses
    local variables susceptible to contain sensitive information, you may
    prevent the values of those variables from being included in error reports
    using the ``sensitive_variables`` decorator::

        from django.views.decorators.debug import sensitive_variables

        @sensitive_variables('user', 'pw', 'cc')
        def process_info(user):
            pw = user.pass_word
            cc = user.credit_card_number
            name = user.name
            ...

    In the above example, the values for the ``user``, ``pw`` and ``cc``
    variables will be hidden and replaced with stars (`**********`) in the
    error reports, whereas the value of the ``name`` variable will be
    disclosed.

    To systematically hide all local variables of a function from error logs,
    do not provide any argument to the ``sensitive_variables`` decorator::

        @sensitive_variables()
        def my_function():
            ...

    .. admonition:: When using multiple decorators

        If the variable you want to hide is also a function argument (e.g.
        '``user``’ in the following example), and if the decorated function has
        multiple decorators, then make sure to place ``@sensitive_variables``
        at the top of the decorator chain. This way it will also hide the
        function argument as it gets passed through the other decorators::

            @sensitive_variables('user', 'pw', 'cc')
            @some_decorator
            @another_decorator
            def process_info(user):
                ...

.. function:: sensitive_post_parameters(*parameters)

    If one of your views receives an :class:`~django.http.HttpRequest` object
    with :attr:`POST parameters<django.http.HttpRequest.POST>` susceptible to
    contain sensitive information, you may prevent the values of those
    parameters from being included in the error reports using the
    ``sensitive_post_parameters`` decorator::

        from django.views.decorators.debug import sensitive_post_parameters

        @sensitive_post_parameters('pass_word', 'credit_card_number')
        def record_user_profile(request):
            UserProfile.create(
                user=request.user,
                password=request.POST['pass_word'],
                credit_card=request.POST['credit_card_number'],
                name=request.POST['name'],
            )
            ...

    In the above example, the values for the ``pass_word`` and
    ``credit_card_number`` POST parameters will be hidden and replaced with
    stars (`**********`) in the request's representation inside the error
    reports, whereas the value of the ``name`` parameter will be disclosed.

    To systematically hide all POST parameters of a request in error reports,
    do not provide any argument to the ``sensitive_post_parameters`` decorator::

        @sensitive_post_parameters()
        def my_view(request):
            ...

    All POST parameters are systematically filtered out of error reports for
    certain :mod:`django.contrib.auth.views` views (``login``,
    ``password_reset_confirm``, ``password_change``, and ``add_view`` and
    ``user_change_password`` in the ``auth`` admin) to prevent the leaking of
    sensitive information such as user passwords.

.. _custom-error-reports:

Custom error reports
--------------------

All :func:`sensitive_variables` and :func:`sensitive_post_parameters` do is,
respectively, annotate the decorated function with the names of sensitive
variables and annotate the ``HttpRequest`` object with the names of sensitive
POST parameters, so that this sensitive information can later be filtered out
of reports when an error occurs. The actual filtering is done by Django's
default error reporter filter:
:class:`django.views.debug.SafeExceptionReporterFilter`. This filter uses the
decorators' annotations to replace the corresponding values with stars
(`**********`) when the error reports are produced. If you wish to override or
customize this default behavior for your entire site, you need to define your
own filter class and tell Django to use it via the
:setting:`DEFAULT_EXCEPTION_REPORTER_FILTER` setting::

    DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'

You may also control in a more granular way which filter to use within any
given view by setting the ``HttpRequest``’s ``exception_reporter_filter``
attribute::

    def my_view(request):
        if request.user.is_authenticated:
            request.exception_reporter_filter = CustomExceptionReporterFilter()
        ...

.. currentmodule:: django.views.debug

Your custom filter class needs to inherit from
:class:`django.views.debug.SafeExceptionReporterFilter` and may override the
following methods:

.. class:: SafeExceptionReporterFilter

.. method:: SafeExceptionReporterFilter.is_active(request)

    Returns ``True`` to activate the filtering operated in the other methods.
    By default the filter is active if :setting:`DEBUG` is ``False``.

.. method:: SafeExceptionReporterFilter.get_post_parameters(request)

    Returns the filtered dictionary of POST parameters. By default it replaces
    the values of sensitive parameters with stars (`**********`).

.. method:: SafeExceptionReporterFilter.get_traceback_frame_variables(request, tb_frame)

    Returns the filtered dictionary of local variables for the given traceback
    frame. By default it replaces the values of sensitive variables with stars
    (`**********`).

.. seealso::

    You can also set up custom error reporting by writing a custom piece of
    :ref:`exception middleware <exception-middleware>`. If you do write custom
    error handling, it's a good idea to emulate Django's built-in error handling
    and only report/log errors if :setting:`DEBUG` is ``False``.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Index (`大一小学期/Week_3-Python/exam/2016/docs/howto/index.txt`)

===============
"How-to" guides
===============

Here you'll find short answers to "How do I....?" types of questions. These
how-to guides don't cover topics in depth -- you'll find that material in the
:doc:`/topics/index` and the :doc:`/ref/index`. However, these guides will help
you quickly accomplish common tasks.

.. toctree::
   :maxdepth: 1

   auth-remote-user
   custom-management-commands
   custom-model-fields
   custom-lookups
   custom-template-tags
   custom-file-storage
   deployment/index
   upgrade-version
   error-reporting
   initial-data
   jython
   legacy-databases
   outputting-csv
   outputting-pdf
   static-files/index
   static-files/deployment
   windows
   writing-migrations

.. seealso::

    The `Django community aggregator`_, where we aggregate content from the
    global Django community. Many writers in the aggregator write this sort of
    how-to material.

    .. _django community aggregator: https://www.djangoproject.com/community/

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Initial Data (`大一小学期/Week_3-Python/exam/2016/docs/howto/initial-data.txt`)

=================================
Providing initial data for models
=================================

It's sometimes useful to pre-populate your database with hard-coded data when
you're first setting up an app. You can provide initial data via fixtures.

.. _initial-data-via-fixtures:

Providing initial data with fixtures
====================================

A fixture is a collection of data that Django knows how to import into a
database. The most straightforward way of creating a fixture if you've already
got some data is to use the :djadmin:`manage.py dumpdata <dumpdata>` command.
Or, you can write fixtures by hand; fixtures can be written as JSON, XML or YAML
(with PyYAML_ installed) documents. The :doc:`serialization documentation
</topics/serialization>` has more details about each of these supported
:ref:`serialization formats <serialization-formats>`.

.. _PyYAML: http://www.pyyaml.org/

As an example, though, here's what a fixture for a simple ``Person`` model might
look like in JSON:

.. code-block:: js

    [
      {
        "model": "myapp.person",
        "pk": 1,
        "fields": {
          "first_name": "John",
          "last_name": "Lennon"
        }
      },
      {
        "model": "myapp.person",
        "pk": 2,
        "fields": {
          "first_name": "Paul",
          "last_name": "McCartney"
        }
      }
    ]

And here's that same fixture as YAML:

.. code-block:: none

    - model: myapp.person
      pk: 1
      fields:
        first_name: John
        last_name: Lennon
    - model: myapp.person
      pk: 2
      fields:
        first_name: Paul
        last_name: McCartney

You'll store this data in a ``fixtures`` directory inside your app.

Loading data is easy: just call :djadmin:`manage.py loaddata <loaddata>`
``<fixturename>``, where ``<fixturename>`` is the name of the fixture file
you've created. Each time you run :djadmin:`loaddata`, the data will be read
from the fixture and re-loaded into the database. Note this means that if you
change one of the rows created by a fixture and then run :djadmin:`loaddata`
again, you'll wipe out any changes you've made.

Where Django finds fixture files
--------------------------------

By default, Django looks in the ``fixtures`` directory inside each app for
fixtures. You can set the :setting:`FIXTURE_DIRS` setting to a list of
additional directories where Django should look.

When running :djadmin:`manage.py loaddata <loaddata>`, you can also
specify a path to a fixture file, which overrides searching the usual
directories.

.. seealso::

    Fixtures are also used by the :ref:`testing framework
    <topics-testing-fixtures>` to help set up a consistent test environment.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Jython (`大一小学期/Week_3-Python/exam/2016/docs/howto/jython.txt`)

========================
Running Django on Jython
========================

.. index:: Jython, Java, JVM

Jython_ is an implementation of Python that runs on the Java platform (JVM).
This document will get you up and running with Django on top of Jython.

Installing Jython
=================

Django works with Jython versions 2.7b2 and higher. See the Jython_ website for
download and installation instructions.

.. _jython: http://www.jython.org/

Creating a servlet container
============================

If you just want to experiment with Django, skip ahead to the next section;
Django includes a lightweight Web server you can use for testing, so you won't
need to set up anything else until you're ready to deploy Django in production.

If you want to use Django on a production site, use a Java servlet container,
such as `Apache Tomcat`_. Full JavaEE applications servers such as `GlassFish`_
or `JBoss`_ are also OK, if you need the extra features they include.

.. _`Apache Tomcat`: https://tomcat.apache.org/
.. _GlassFish: https://glassfish.java.net/
.. _JBoss: https://www.jboss.org/

Installing Django
=================

The next step is to install Django itself. This is exactly the same as
installing Django on standard Python, so see
:ref:`removing-old-versions-of-django` and :ref:`install-django-code` for
instructions.

Installing Jython platform support libraries
============================================

The `django-jython`_ project contains database backends and management commands
for Django/Jython development. Note that the builtin Django backends won't work
on top of Jython.

.. _`django-jython`: https://github.com/beachmachine/django-jython

To install it, follow the `installation instructions`_ detailed on the project
website. Also, read the `database backends`_ documentation there.

.. _`installation instructions`: https://pythonhosted.org/django-jython/quickstart.html#install
.. _`database backends`: https://pythonhosted.org/django-jython/database-backends.html

Differences with Django on Jython
=================================

.. index:: JYTHONPATH

At this point, Django on Jython should behave nearly identically to Django
running on standard Python. However, are a few differences to keep in mind:

* Remember to use the ``jython`` command instead of ``python``. The
  documentation uses ``python`` for consistency, but if you're using Jython
  you'll want to mentally replace ``python`` with ``jython`` every time it
  occurs.

* Similarly, you'll need to use the ``JYTHONPATH`` environment variable
  instead of ``PYTHONPATH``.

* Any part of Django that requires `Pillow`_ will not work.

.. _Pillow: https://pillow.readthedocs.io/en/latest/

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Legacy Databases (`大一小学期/Week_3-Python/exam/2016/docs/howto/legacy-databases.txt`)

=========================================
Integrating Django with a legacy database
=========================================

While Django is best suited for developing new applications, it's quite
possible to integrate it into legacy databases. Django includes a couple of
utilities to automate as much of this process as possible.

This document assumes you know the Django basics, as covered in the
:doc:`tutorial </intro/tutorial01>`.

Once you've got Django set up, you'll follow this general process to integrate
with an existing database.

Give Django your database parameters
====================================

You'll need to tell Django what your database connection parameters are, and
what the name of the database is. Do that by editing the :setting:`DATABASES`
setting and assigning values to the following keys for the ``'default'``
connection:

* :setting:`NAME`
* :setting:`ENGINE <DATABASE-ENGINE>`
* :setting:`USER`
* :setting:`PASSWORD`
* :setting:`HOST`
* :setting:`PORT`

Auto-generate the models
========================

.. highlight:: bash

Django comes with a utility called :djadmin:`inspectdb` that can create models
by introspecting an existing database. You can view the output by running this
command::

    $ python manage.py inspectdb

Save this as a file by using standard Unix output redirection::

    $ python manage.py inspectdb > models.py

This feature is meant as a shortcut, not as definitive model generation. See the
:djadmin:`documentation of inspectdb <inspectdb>` for more information.

Once you've cleaned up your models, name the file ``models.py`` and put it in
the Python package that holds your app. Then add the app to your
:setting:`INSTALLED_APPS` setting.

By default, :djadmin:`inspectdb` creates unmanaged models. That is,
``managed = False`` in the model's ``Meta`` class tells Django not to manage
each table's creation, modification, and deletion::

    class Person(models.Model):
        id = models.IntegerField(primary_key=True)
        first_name = models.CharField(max_length=70)
        class Meta:
           managed = False
           db_table = 'CENSUS_PERSONS'

If you do want to allow Django to manage the table's lifecycle, you'll need to
change the :attr:`~django.db.models.Options.managed` option above to ``True``
(or simply remove it because ``True`` is its default value).

Install the core Django tables
==============================

Next, run the :djadmin:`migrate` command to install any extra needed database
records such as admin permissions and content types::

    $ python manage.py migrate

Test and tweak
==============

Those are the basic steps -- from here you'll want to tweak the models Django
generated until they work the way you'd like. Try accessing your data via the
Django database API, and try editing objects via Django's admin site, and edit
the models file accordingly.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Outputting Csv (`大一小学期/Week_3-Python/exam/2016/docs/howto/outputting-csv.txt`)

==========================
Outputting CSV with Django
==========================

This document explains how to output CSV (Comma Separated Values) dynamically
using Django views. To do this, you can either use the Python CSV library or the
Django template system.

Using the Python CSV library
============================

Python comes with a CSV library, :mod:`csv`. The key to using it with Django is
that the :mod:`csv` module's CSV-creation capability acts on file-like objects,
and Django's :class:`~django.http.HttpResponse` objects are file-like objects.

Here's an example::

    import csv
    from django.http import HttpResponse

    def some_view(request):
        # Create the HttpResponse object with the appropriate CSV header.
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'

        writer = csv.writer(response)
        writer.writerow(['First row', 'Foo', 'Bar', 'Baz'])
        writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"])

        return response

The code and comments should be self-explanatory, but a few things deserve a
mention:

* The response gets a special MIME type, :mimetype:`text/csv`. This tells
  browsers that the document is a CSV file, rather than an HTML file. If
  you leave this off, browsers will probably interpret the output as HTML,
  which will result in ugly, scary gobbledygook in the browser window.

* The response gets an additional ``Content-Disposition`` header, which
  contains the name of the CSV file. This filename is arbitrary; call it
  whatever you want. It'll be used by browsers in the "Save as..." dialog, etc.

* Hooking into the CSV-generation API is easy: Just pass ``response`` as the
  first argument to ``csv.writer``. The ``csv.writer`` function expects a
  file-like object, and :class:`~django.http.HttpResponse` objects fit the
  bill.

* For each row in your CSV file, call ``writer.writerow``, passing it an
  iterable object such as a list or tuple.

* The CSV module takes care of quoting for you, so you don't have to worry
  about escaping strings with quotes or commas in them. Just pass
  ``writerow()`` your raw strings, and it'll do the right thing.

.. admonition:: Handling Unicode on Python 2

    Python 2's :mod:`csv` module does not support Unicode input. Since Django
    uses Unicode internally this means strings read from sources such as
    :class:`~django.http.HttpRequest` are potentially problematic. There are a
    few options for handling this:

    * Manually encode all Unicode objects to a compatible encoding.

    * Use the ``UnicodeWriter`` class provided in the `csv module's examples
      section`_.

    * Use the `python-unicodecsv module`_, which aims to be a drop-in
      replacement for :mod:`csv` that gracefully handles Unicode.

    For more information, see the Python documentation of the :mod:`csv` module.

    .. _`csv module's examples section`: https://docs.python.org/2/library/csv.html#examples
    .. _`python-unicodecsv module`: https://github.com/jdunck/python-unicodecsv

.. _streaming-csv-files:

Streaming large CSV files
-------------------------

When dealing with views that generate very large responses, you might want to
consider using Django's :class:`~django.http.StreamingHttpResponse` instead.
For example, by streaming a file that takes a long time to generate you can
avoid a load balancer dropping a connection that might have otherwise timed out
while the server was generating the response.

In this example, we make full use of Python generators to efficiently handle
the assembly and transmission of a large CSV file::

    import csv

    from django.utils.six.moves import range
    from django.http import StreamingHttpResponse

    class Echo(object):
        """An object that implements just the write method of the file-like
        interface.
        """
        def write(self, value):
            """Write the value by returning it, instead of storing in a buffer."""
            return value

    def some_streaming_csv_view(request):
        """A view that streams a large CSV file."""
        # Generate a sequence of rows. The range is based on the maximum number of
        # rows that can be handled by a single sheet in most spreadsheet
        # applications.
        rows = (["Row {}".format(idx), str(idx)] for idx in range(65536))
        pseudo_buffer = Echo()
        writer = csv.writer(pseudo_buffer)
        response = StreamingHttpResponse((writer.writerow(row) for row in rows),
                                         content_type="text/csv")
        response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'
        return response

Using the template system
=========================

Alternatively, you can use the :doc:`Django template system </topics/templates>`
to generate CSV. This is lower-level than using the convenient Python :mod:`csv`
module, but the solution is presented here for completeness.

The idea here is to pass a list of items to your template, and have the
template output the commas in a :ttag:`for` loop.

Here's an example, which generates the same CSV file as above::

    from django.http import HttpResponse
    from django.template import loader, Context

    def some_view(request):
        # Create the HttpResponse object with the appropriate CSV header.
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'

        # The data is hard-coded here, but you could load it from a database or
        # some other source.
        csv_data = (
            ('First row', 'Foo', 'Bar', 'Baz'),
            ('Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"),
        )

        t = loader.get_template('my_template_name.txt')
        c = Context({
            'data': csv_data,
        })
        response.write(t.render(c))
        return response

The only difference between this example and the previous example is that this
one uses template loading instead of the CSV module. The rest of the code --
such as the ``content_type='text/csv'`` -- is the same.

Then, create the template ``my_template_name.txt``, with this template code:

.. code-block:: html+django

    {% for row in data %}"{{ row.0|addslashes }}", "{{ row.1|addslashes }}", "{{ row.2|addslashes }}", "{{ row.3|addslashes }}", "{{ row.4|addslashes }}"
    {% endfor %}

This template is quite basic. It just iterates over the given data and displays
a line of CSV for each row. It uses the :tfilter:`addslashes` template filter to
ensure there aren't any problems with quotes.

Other text-based formats
========================

Notice that there isn't very much specific to CSV here -- just the specific
output format. You can use either of these techniques to output any text-based
format you can dream of. You can also use a similar technique to generate
arbitrary binary data; see :doc:`/howto/outputting-pdf` for an example.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Outputting Pdf (`大一小学期/Week_3-Python/exam/2016/docs/howto/outputting-pdf.txt`)

===========================
Outputting PDFs with Django
===========================

This document explains how to output PDF files dynamically using Django views.
This is made possible by the excellent, open-source ReportLab_ Python PDF
library.

The advantage of generating PDF files dynamically is that you can create
customized PDFs for different purposes -- say, for different users or different
pieces of content.

For example, Django was used at kusports.com_ to generate customized,
printer-friendly NCAA tournament brackets, as PDF files, for people
participating in a March Madness contest.

.. _ReportLab: http://www.reportlab.com/opensource/
.. _kusports.com: http://www.kusports.com/

Install ReportLab
=================

The ReportLab library is `available on PyPI`_. A `user guide`_ (not
coincidentally, a PDF file) is also available for download.
You can install ReportLab with ``pip``:

.. code-block:: console

    $ pip install reportlab

Test your installation by importing it in the Python interactive interpreter::

    >>> import reportlab

If that command doesn't raise any errors, the installation worked.

.. _available on PyPI: https://pypi.python.org/pypi/reportlab
.. _user guide: http://www.reportlab.com/docs/reportlab-userguide.pdf

Write your view
===============

The key to generating PDFs dynamically with Django is that the ReportLab API
acts on file-like objects, and Django's :class:`~django.http.HttpResponse`
objects are file-like objects.

Here's a "Hello World" example::

    from reportlab.pdfgen import canvas
    from django.http import HttpResponse

    def some_view(request):
        # Create the HttpResponse object with the appropriate PDF headers.
        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename="somefilename.pdf"'

        # Create the PDF object, using the response object as its "file."
        p = canvas.Canvas(response)

        # Draw things on the PDF. Here's where the PDF generation happens.
        # See the ReportLab documentation for the full list of functionality.
        p.drawString(100, 100, "Hello world.")

        # Close the PDF object cleanly, and we're done.
        p.showPage()
        p.save()
        return response

The code and comments should be self-explanatory, but a few things deserve a
mention:

* The response gets a special MIME type, :mimetype:`application/pdf`. This
  tells browsers that the document is a PDF file, rather than an HTML file.
  If you leave this off, browsers will probably interpret the output as
  HTML, which would result in ugly, scary gobbledygook in the browser
  window.

* The response gets an additional ``Content-Disposition`` header, which
  contains the name of the PDF file. This filename is arbitrary: Call it
  whatever you want. It'll be used by browsers in the "Save as..." dialog, etc.

* The ``Content-Disposition`` header starts with ``'attachment; '`` in this
  example. This forces Web browsers to pop-up a dialog box
  prompting/confirming how to handle the document even if a default is set
  on the machine. If you leave off ``'attachment;'``, browsers will handle
  the PDF using whatever program/plugin they've been configured to use for
  PDFs. Here's what that code would look like::

      response['Content-Disposition'] = 'filename="somefilename.pdf"'

* Hooking into the ReportLab API is easy: Just pass ``response`` as the
  first argument to ``canvas.Canvas``. The ``Canvas`` class expects a
  file-like object, and :class:`~django.http.HttpResponse` objects fit the
  bill.

* Note that all subsequent PDF-generation methods are called on the PDF
  object (in this case, ``p``) -- not on ``response``.

* Finally, it's important to call ``showPage()`` and ``save()`` on the PDF
  file.

.. note::

    ReportLab is not thread-safe. Some of our users have reported odd issues
    with building PDF-generating Django views that are accessed by many people
    at the same time.

Complex PDFs
============

If you're creating a complex PDF document with ReportLab, consider using the
:mod:`io` library as a temporary holding place for your PDF file. This
library provides a file-like object interface that is particularly efficient.
Here's the above "Hello World" example rewritten to use :mod:`io`::

    from io import BytesIO
    from reportlab.pdfgen import canvas
    from django.http import HttpResponse

    def some_view(request):
        # Create the HttpResponse object with the appropriate PDF headers.
        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename="somefilename.pdf"'

        buffer = BytesIO()

        # Create the PDF object, using the BytesIO object as its "file."
        p = canvas.Canvas(buffer)

        # Draw things on the PDF. Here's where the PDF generation happens.
        # See the ReportLab documentation for the full list of functionality.
        p.drawString(100, 100, "Hello world.")

        # Close the PDF object cleanly.
        p.showPage()
        p.save()

        # Get the value of the BytesIO buffer and write it to the response.
        pdf = buffer.getvalue()
        buffer.close()
        response.write(pdf)
        return response

Further resources
=================

* PDFlib_ is another PDF-generation library that has Python bindings. To
  use it with Django, just use the same concepts explained in this article.
* `XHTML2PDF`_ is yet another PDF-generation library. It ships with an example
  of how to integrate it with Django.
* HTMLdoc_ is a command-line script that can convert HTML to PDF. It
  doesn't have a Python interface, but you can escape out to the shell
  using ``system`` or ``popen`` and retrieve the output in Python.

.. _PDFlib: http://www.pdflib.org/
.. _XHTML2PDF: https://github.com/xhtml2pdf/xhtml2pdf
.. _HTMLdoc: https://www.msweet.org/projects.php?Z1

Other formats
=============

Notice that there isn't a lot in these examples that's PDF-specific -- just the
bits using ``reportlab``. You can use a similar technique to generate any
arbitrary format that you can find a Python library for. Also see
:doc:`/howto/outputting-csv` for another example and some techniques you can use
when generated text-based formats.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Upgrade Version (`大一小学期/Week_3-Python/exam/2016/docs/howto/upgrade-version.txt`)

===================================
Upgrading Django to a newer version
===================================

While it can be a complex process at times, upgrading to the latest Django
version has several benefits:

* New features and improvements are added.
* Bugs are fixed.
* Older version of Django will eventually no longer receive security updates.
  (see :ref:`backwards-compatibility-policy`).
* Upgrading as each new Django release is available makes future upgrades less
  painful by keeping your code base up to date.

Here are some things to consider to help make your upgrade process as smooth as
possible.

Required Reading
================

If it's your first time doing an upgrade, it is useful to read the :doc:`guide
on the different release processes </internals/release-process>`.

Afterwards, you should familiarize yourself with the changes that were made in
the new Django version(s):

* Read the :doc:`release notes </releases/index>` for each 'final' release from
  the one after your current Django version, up to and including the version to
  which you plan to upgrade.
* Look at the :doc:`deprecation timeline</internals/deprecation>` for the
  relevant versions.

Pay particular attention to backwards incompatible changes to get a clear idea
of what will be needed for a successful upgrade.

Dependencies
============

In most cases it will be necessary to upgrade to the latest version of your
Django-related dependencies as well. If the Django version was recently
released or if some of your dependencies are not well-maintained, some of your
dependencies may not yet support the new Django version. In these cases you may
have to wait until new versions of your dependencies are released.

Resolving deprecation warnings
==============================

Before upgrading, it's a good idea to resolve any deprecation warnings raised
by your project while using your current version of Django. Fixing these
warnings before upgrading ensures that you're informed about areas of the code
that need altering.

In Python, deprecation warnings are silenced by default. You must turn them on
using the ``-Wall`` Python command line option or the :envvar:`PYTHONWARNINGS`
environment variable. For example, to show warnings while running tests:

.. code-block:: console

    $ python -Wall manage.py test

If you're not using the Django test runner, you may need to also ensure that
any console output is not captured which would hide deprecation warnings. For
example, if you use `py.test`:

.. code-block:: console

    $ PYTHONWARNINGS=all py.test tests --capture=no

Resolve any deprecation warnings with your current version of Django before
continuing the upgrade process.

Third party applications might use deprecated APIs in order to support multiple
versions of Django, so deprecation warnings in packages you've installed don't
necessarily indicate a problem. If a package doesn't support the latest version
of Django, consider raising an issue or sending a pull request for it.

Installation
============

Once you're ready, it is time to :doc:`install the new Django version
</topics/install>`. If you are using virtualenv_ and it is a major upgrade, you
might want to set up a new environment with all the dependencies first.

Exactly which steps you will need to take depends on your installation process.
The most convenient way is to use pip_ with the ``--upgrade`` or ``-U`` flag:

.. code-block:: console

   $ pip install -U Django

pip_ also automatically uninstalls the previous version of Django.

If you use some other installation process, you might have to manually
:ref:`uninstall the old Django version <removing-old-versions-of-django>` and
should look at the complete installation instructions.

.. _pip: https://pip.pypa.io/
.. _virtualenv: http://www.virtualenv.org/

Testing
=======

When the new environment is set up, :doc:`run the full test suite
</topics/testing/overview>` for your application. Again, it's useful to turn
on deprecation warnings on so they're shown in the test output (you can also
use the flag if you test your app manually using ``manage.py runserver``):

.. code-block:: console

    $ python -Wall manage.py test

After you have run the tests, fix any failures. While you have the release
notes fresh in your mind, it may also be a good time to take advantage of new
features in Django by refactoring your code to eliminate any deprecation
warnings.

Deployment
==========

When you are sufficiently confident your app works with the new version of
Django, you're ready to go ahead and :doc:`deploy </howto/deployment/index>`
your upgraded Django project.

If you are using caching provided by Django, you should consider clearing your
cache after upgrading. Otherwise you may run into problems, for example, if you
are caching pickled objects as these objects are not guaranteed to be
pickle-compatible across Django versions. A past instance of incompatibility
was caching pickled :class:`~django.http.HttpResponse` objects, either
directly or indirectly via the :func:`~django.views.decorators.cache.cache_page`
decorator.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Windows (`大一小学期/Week_3-Python/exam/2016/docs/howto/windows.txt`)

================================
How to install Django on Windows
================================

This document will guide you through installing Python 3.5 and Django on
Windows. It also provides instructions for installing `virtualenv`_ and
`virtualenvwrapper`_, which make it easier to work on Python projects. This is
meant as a beginner's guide for users working on Django projects and does not
reflect how Django should be installed when developing patches for Django
itself.

The steps in this guide have been tested with Windows 7, 8, and 10. In other
versions, the steps would be similar. You will need to be familiar with using
the Windows command prompt.

Install Python
==============

Django is a Python web framework, thus requiring Python to be installed on your
machine. At the time of writing, Python 3.5 is the latest version.

To install Python on your machine go to https://python.org/downloads/. The
website should offer you a download button for the latest Python version.
Download the executable installer and run it. Check the box next to ``Add
Python 3.5 to PATH`` and then click ``Install Now``.

After installation, open the command prompt and check that the Python version
matches the version you installed by executing::

    python --version

About ``pip``
=============

`pip`_ is a package manage for Python. It makes installing and uninstalling
Python packages (such as Django!) very easy. For the rest of the installation,
we'll use ``pip`` to install Python packages from the command line.

To install pip on your machine, go to
https://pip.pypa.io/en/latest/installing/, and follow the ``Installing with
get-pip.py`` instructions.

.. _pip: https://pypi.python.org/pypi/pip

Install ``virtualenv`` and ``virtualenvwrapper``
================================================

`virtualenv`_ and `virtualenvwrapper`_ provide a dedicated environment for
each Django project you create. While not mandatory, this is considered a best
practice and will save you time in the future when you're ready to deploy your
project. Simply type::

    pip install virtualenvwrapper-win

Then create a virtual environment for your project::

    mkvirtualenv myproject

The virtual environment will be activated automatically and you'll see
"(myproject)" next to the command prompt to designate that. If you start a new
command prompt, you'll need to activate the environment again using::

    workon myproject

.. _virtualenv: https://pypi.python.org/pypi/virtualenv
.. _virtualenvwrapper: https://pypi.python.org/pypi/virtualenvwrapper-win

Install Django
==============

Django can be installed easily using ``pip`` within your virtual environment.

In the command prompt, ensure your virtual environment is active, and execute
the following command::

    pip install django

This will download and install the latest Django release.

After the installation has completed, you can verify your Django installation
by executing ``django-admin --version`` in the command prompt.

See :ref:`database-installation` for information on database installation
with Django.

Common pitfalls
===============

* If ``django-admin`` only displays the help text no matter what arguments
  it is given, there is probably a problem with the file association in
  Windows. Check if there is more than one environment variable set for
  running Python scripts in ``PATH``. This usually occurs when there is more
  than one Python version installed.

* If you are connecting to the internet behind a proxy, there might be problem
  in running the command ``pip install django``. Set the environment variables
  for proxy configuration in the command prompt as follows::

    set http_proxy=http://username:password@proxyserver:proxyport
    set https_proxy=https://username:password@proxyserver:proxyport

---

### 大一小学期 Week 3 Python Exam 2016 Docs Howto Writing Migrations (`大一小学期/Week_3-Python/exam/2016/docs/howto/writing-migrations.txt`)

===========================
Writing database migrations
===========================

This document explains how to structure and write database migrations for
different scenarios you might encounter. For introductory material on
migrations, see :doc:`the topic guide </topics/migrations>`.

.. _data-migrations-and-multiple-databases:

Data migrations and multiple databases
======================================

When using multiple databases, you may need to figure out whether or not to
run a migration against a particular database. For example, you may want to
**only** run a migration on a particular database.

In order to do that you can check the database connection's alias inside a
``RunPython`` operation by looking at the ``schema_editor.connection.alias``
attribute::

    from django.db import migrations

    def forwards(apps, schema_editor):
        if not schema_editor.connection.alias == 'default':
            return
        # Your migration code goes here

    class Migration(migrations.Migration):

        dependencies = [
            # Dependencies to other migrations
        ]

        operations = [
            migrations.RunPython(forwards),
        ]

You can also provide hints that will be passed to the :meth:`allow_migrate()`
method of database routers as ``**hints``:

.. snippet::
    :filename: myapp/dbrouters.py

    class MyRouter(object):

        def allow_migrate(self, db, app_label, model_name=None, **hints):
            if 'target_db' in hints:
                return db == hints['target_db']
            return True

Then, to leverage this in your migrations, do the following::

    from django.db import migrations

    def forwards(apps, schema_editor):
        # Your migration code goes here
        ...

    class Migration(migrations.Migration):

        dependencies = [
            # Dependencies to other migrations
        ]

        operations = [
            migrations.RunPython(forwards, hints={'target_db': 'default'}),
        ]

If your ``RunPython`` or ``RunSQL`` operation only affects one model, it's good
practice to pass ``model_name`` as a hint to make it as transparent as possible
to the router. This is especially important for reusable and third-party apps.

Migrations that add unique fields
=================================

Applying a "plain" migration that adds a unique non-nullable field to a table
with existing rows will raise an error because the value used to populate
existing rows is generated only once, thus breaking the unique constraint.

Therefore, the following steps should be taken. In this example, we'll add a
non-nullable :class:`~django.db.models.UUIDField` with a default value. Modify
the respective field according to your needs.

* Add the field on your model with ``default=uuid.uuid4`` and ``unique=True``
  arguments (choose an appropriate default for the type of the field you're
  adding).

* Run the :djadmin:`makemigrations` command. This should generate a migration
  with an ``AddField`` operation.

* Generate two empty migration files for the same app by running
  ``makemigrations myapp --empty`` twice. We've renamed the migration files to
  give them meaningful names in the examples below.

* Copy the ``AddField`` operation from the auto-generated migration (the first
  of the three new files) to the last migration and change ``AddField`` to
  ``AlterField``. For example:

  .. snippet::
    :filename: 0006_remove_uuid_null.py

    # -*- coding: utf-8 -*-
    # Generated by Django A.B on YYYY-MM-DD HH:MM
    from __future__ import unicode_literals

    from django.db import migrations, models
    import uuid


    class Migration(migrations.Migration):

        dependencies = [
            ('myapp', '0005_populate_uuid_values'),
        ]

        operations = [
            migrations.AlterField(
                model_name='mymodel',
                name='uuid',
                field=models.UUIDField(default=uuid.uuid4, unique=True),
            ),
        ]

* Edit the first migration file. The generated migration class should look
  similar to this:

  .. snippet::
    :filename: 0004_add_uuid_field.py

    class Migration(migrations.Migration):

        dependencies = [
            ('myapp', '0003_auto_20150129_1705'),
        ]

        operations = [
            migrations.AddField(
                model_name='mymodel',
                name='uuid',
                field=models.UUIDField(default=uuid.uuid4, unique=True),
            ),
        ]

  Change ``unique=True`` to ``null=True`` -- this will create the intermediary
  null field and defer creating the unique constraint until we've populated
  unique values on all the rows.

* In the first empty migration file, add a
  :class:`~django.db.migrations.operations.RunPython` or
  :class:`~django.db.migrations.operations.RunSQL` operation to generate a
  unique value (UUID in the example) for each existing row. For example:

  .. snippet::
    :filename: 0005_populate_uuid_values.py

    # -*- coding: utf-8 -*-
    # Generated by Django A.B on YYYY-MM-DD HH:MM
    from __future__ import unicode_literals

    from django.db import migrations, models
    import uuid

    def gen_uuid(apps, schema_editor):
        MyModel = apps.get_model('myapp', 'MyModel')
        for row in MyModel.objects.all():
            row.uuid = uuid.uuid4()
            row.save()

    class Migration(migrations.Migration):

        dependencies = [
            ('myapp', '0004_add_uuid_field'),
        ]

        operations = [
            # omit reverse_code=... if you don't want the migration to be reversible.
            migrations.RunPython(gen_uuid, reverse_code=migrations.RunPython.noop),
        ]

* Now you can apply the migrations as usual with the :djadmin:`migrate` command.

  Note there is a race condition if you allow objects to be created while this
  migration is running. Objects created after the ``AddField`` and before
  ``RunPython`` will have their original ``uuid``’s overwritten.

.. _non-atomic-migrations:

Non-atomic migrations
~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 1.10

On databases that support DDL transactions (SQLite and PostgreSQL), migrations
will run inside a transaction by default. For use cases such as performing data
migrations on large tables, you may want to prevent a migration from running in
a transaction by setting the ``atomic`` attribute to ``False``::

    from django.db import migrations

    class Migration(migrations.Migration):
        atomic = False

Within such a migration, all operations are run without a transaction. It's
possible to execute parts of the migration inside a transaction using
:func:`~django.db.transaction.atomic()` or by passing ``atomic=True`` to
``RunPython``.

Here's an example of a non-atomic data migration that updates a large table in
smaller batches::

    import uuid

    from django.db import migrations, transaction

    def gen_uuid(apps, schema_editor):
        MyModel = apps.get_model('myapp', 'MyModel')
        while MyModel.objects.filter(uuid__isnull=True).exists():
            with transaction.atomic():
                for row in MyModel.objects.filter(uuid__isnull=True)[:1000]:
                    row.uuid = uuid.uuid4()
                    row.save()

    class Migration(migrations.Migration):
        atomic = False

        operations = [
            migrations.RunPython(gen_uuid),
        ]

The ``atomic`` attribute doesn't have an effect on databases that don't support
DDL transactions (e.g. MySQL, Oracle).

Controlling the order of migrations
===================================

Django determines the order in which migrations should be applied not by the
filename of each migration, but by building a graph using two properties on the
``Migration`` class: ``dependencies`` and ``run_before``.

If you've used the :djadmin:`makemigrations` command you've probably
already seen ``dependencies`` in action because auto-created
migrations have this defined as part of their creation process.

The ``dependencies`` property is declared like this::

    from django.db import migrations

    class Migration(migrations.Migration):

        dependencies = [
            ('myapp', '0123_the_previous_migration'),
        ]

Usually this will be enough, but from time to time you may need to
ensure that your migration runs *before* other migrations. This is
useful, for example, to make third-party apps' migrations run *after*
your :setting:`AUTH_USER_MODEL` replacement.

To achieve this, place all migrations that should depend on yours in
the ``run_before`` attribute on your ``Migration`` class::

    class Migration(migrations.Migration):
        ...

        run_before = [
            ('third_party_app', '0001_do_awesome'),
        ]

Prefer using ``dependencies`` over ``run_before`` when possible. You should
only use ``run_before`` if it is undesirable or impractical to specify
``dependencies`` in the migration which you want to run after the one you are
writing.

Migrating data between third-party apps
=======================================

You can use a data migration to move data from one third-party application to
another.

If you plan to remove the old app later, you'll need to set the ``dependencies``
property based on whether or not the old app is installed. Otherwise, you'll
have missing dependencies once you uninstall the old app. Similarly, you'll
need to catch :exc:`LookupError` in the ``apps.get_model()`` call that
retrieves models from the old app. This approach allows you to deploy your
project anywhere without first installing and then uninstalling the old app.

Here's a sample migration:

.. snippet::
    :filename: myapp/migrations/0124_move_old_app_to_new_app.py

    from django.apps import apps as global_apps
    from django.db import migrations

    def forwards(apps, schema_editor):
        try:
            OldModel = apps.get_model('old_app', 'OldModel')
        except LookupError:
            # The old app isn't installed.
            return

        NewModel = apps.get_model('new_app', 'NewModel')
        NewModel.objects.bulk_create(
            NewModel(new_attribute=old_object.old_attribute)
            for old_object in OldModel.objects.all()
        )

    class Migration(migrations.Migration):
        operations = [
            migrations.RunPython(forwards, migrations.RunPython.noop),
        ]
        dependencies = [
            ('myapp', '0123_the_previous_migration'),
            ('new_app', '0001_initial'),
        ]

        if global_apps.is_installed('old_app'):
            dependencies.append(('old_app', '0001_initial'))

Also consider what you want to happen when the migration is unapplied. You
could either do nothing (as in the example above) or remove some or all of the
data from the new application. Adjust the second argument of the
:mod:`~django.db.migrations.operations.RunPython` operation accordingly.

Changing an unmanaged model to managed
======================================

If you want to change an unmanaged model (:attr:`managed=False
<django.db.models.Options.managed>`) to managed, you must remove
``managed=False`` and generate a migration before making other schema-related
changes to the model, since schema changes that appear in the migration that
contains the operation to change ``Meta.managed`` may not be applied.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Internals Deprecation (`大一小学期/Week_3-Python/exam/2016/docs/internals/deprecation.txt`)

===========================
Django Deprecation Timeline
===========================

This document outlines when various pieces of Django will be removed or altered
in a backward incompatible way, following their deprecation, as per the
:ref:`deprecation policy <internal-release-deprecation-policy>`. More details
about each item can often be found in the release notes of two versions prior.

.. _deprecation-removed-in-2.0:

2.0
---

See the :ref:`Django 1.9 release notes<deprecated-features-1.9>` for more
details on these changes.

* The ``weak`` argument to ``django.dispatch.signals.Signal.disconnect()`` will
  be removed.

* The ``django.forms.extras`` package will be removed.

* The ``assignment_tag`` helper will be removed.

* The ``host`` argument to ``assertsRedirects`` will be removed. The
  compatibility layer which allows absolute URLs to be considered equal to
  relative ones when the path is identical will also be removed.

* ``Field.rel`` will be removed.

* ``Field.remote_field.to`` attribute will be removed.

* The ``on_delete`` argument for ``ForeignKey`` and ``OneToOneField``  will be
  required.

* ``django.db.models.fields.add_lazy_relation()`` will be removed.

* When time zone support is enabled, database backends that don't support time
  zones won't convert aware datetimes to naive values in UTC anymore when such
  values are passed as parameters to SQL queries executed outside of the ORM,
  e.g. with ``cursor.execute()``.

* The ``django.contrib.auth.tests.utils.skipIfCustomUser()`` decorator will be
  removed.

* The ``GeoManager`` and ``GeoQuerySet`` classes will be removed.

* The ``django.contrib.gis.geoip`` module will be removed.

* The ``supports_recursion`` check for template loaders will be removed from:

  * ``django.template.engine.Engine.find_template()``
  * ``django.template.loader_tags.ExtendsNode.find_template()``
  * ``django.template.loaders.base.Loader.supports_recursion()``
  * ``django.template.loaders.cached.Loader.supports_recursion()``

* The ``load_template()`` and ``load_template_sources()`` template loader
  methods will be removed.

* The ``template_dirs`` argument for template loaders will be removed:

  * ``django.template.loaders.base.Loader.get_template()``
  * ``django.template.loaders.cached.Loader.cache_key()``
  * ``django.template.loaders.cached.Loader.get_template()``
  * ``django.template.loaders.cached.Loader.get_template_sources()``
  * ``django.template.loaders.filesystem.Loader.get_template_sources()``

* The ``django.template.loaders.base.Loader.__call__()`` method will be
  removed.

* Support for custom error views with a single positional parameter will be
  dropped.

* The ``mime_type`` attribute of ``django.utils.feedgenerator.Atom1Feed`` and
  ``django.utils.feedgenerator.RssFeed`` will be removed in favor of
  ``content_type``.

* The ``app_name`` argument to :func:`~django.conf.urls.include()` will be
  removed.

* Support for passing a 3-tuple as the first argument to ``include()`` will
  be removed.

* Support for setting a URL instance namespace without an application
  namespace will be removed.

* ``Field._get_val_from_obj()`` will be removed in favor of
  ``Field.value_from_object()``.

* ``django.template.loaders.eggs.Loader`` will be removed.

* The ``current_app`` parameter to the ``contrib.auth`` views will be removed.

* The ``callable_obj`` keyword argument to
  ``SimpleTestCase.assertRaisesMessage()`` will be removed.

* Support for the ``allow_tags`` attribute on ``ModelAdmin`` methods will be
  removed.

* The ``enclosure`` keyword argument to ``SyndicationFeed.add_item()`` will be
  removed.

* The ``django.template.loader.LoaderOrigin`` and
  ``django.template.base.StringOrigin`` aliases for
  ``django.template.base.Origin`` will be removed.

See the :ref:`Django 1.10 release notes <deprecated-features-1.10>` for more
details on these changes.

* The ``makemigrations --exit`` option will be removed.

* Support for direct assignment to a reverse foreign key or many-to-many
  relation will be removed.

* The ``get_srid()`` and ``set_srid()`` methods of
  ``django.contrib.gis.geos.GEOSGeometry`` will be removed.

* The ``get_x()``, ``set_x()``, ``get_y()``, ``set_y()``, ``get_z()``, and
  ``set_z()`` methods of ``django.contrib.gis.geos.Point`` will be removed.

* The ``get_coords()`` and ``set_coords()`` methods of
  ``django.contrib.gis.geos.Point`` will be removed.

* The ``cascaded_union`` property of ``django.contrib.gis.geos.MultiPolygon``
  will be removed.

* ``django.utils.functional.allow_lazy()`` will be removed.

* The ``shell --plain`` option will be removed.

* The ``django.core.urlresolvers`` module will be removed.

* The model ``CommaSeparatedIntegerField`` will be removed. A stub field will
  remain for compatibility with historical migrations.

* Support for the template ``Context.has_key()`` method will be removed.

* Support for the ``django.core.files.storage.Storage.accessed_time()``,
  ``created_time()``, and ``modified_time()`` methods will be removed.

* Support for query lookups using the model name when
  ``Meta.default_related_name`` is set will be removed.

* The ``__search`` query lookup and the
  ``DatabaseOperations.fulltext_search_sql()`` method will be removed.

* The shim for supporting custom related manager classes without a
  ``_apply_rel_filters()`` method will be removed.

* Using ``User.is_authenticated()`` and ``User.is_anonymous()`` as methods
  will no longer be supported.

* The private attribute ``virtual_fields`` of ``Model._meta`` will be removed.

* The private keyword arguments ``virtual_only`` in
  ``Field.contribute_to_class()`` and ``virtual`` in
  ``Model._meta.add_field()`` will be removed.

* The ``javascript_catalog()`` and ``json_catalog()`` views will be removed.

* The ``django.contrib.gis.utils.precision_wkt()`` function will be removed.

* In multi-table inheritance, implicit promotion of a ``OneToOneField`` to a
  ``parent_link`` will be removed.

* Support for ``Widget._format_value()`` will be removed.

* ``FileField`` methods ``get_directory_name()`` and ``get_filename()`` will be
  removed.

* The ``mark_for_escaping()`` function and the classes it uses: ``EscapeData``,
  ``EscapeBytes``, ``EscapeText``, ``EscapeString``, and ``EscapeUnicode`` will
  be removed.

* The ``escape`` filter will change to use
  ``django.utils.html.conditional_escape()``.

* ``Manager.use_for_related_fields`` will be removed.

* Model ``Manager`` inheritance will follow MRO inheritance rules and the
  ``Meta.manager_inheritance_from_future`` to opt-in to this behavior will be
  removed.

* Support for old-style middleware using ``settings.MIDDLEWARE_CLASSES`` will
  be removed.

.. _deprecation-removed-in-1.10:

1.10
----

See the :ref:`Django 1.8 release notes<deprecated-features-1.8>` for more
details on these changes.

* Support for calling a ``SQLCompiler`` directly as an alias for calling its
  ``quote_name_unless_alias`` method will be removed.

* ``cycle`` and ``firstof`` template tags will be removed from the ``future``
  template tag library (used during the 1.6/1.7 deprecation period).

* ``django.conf.urls.patterns()`` will be removed.

* Support for the ``prefix`` argument to
  ``django.conf.urls.i18n.i18n_patterns()`` will be removed.

* ``SimpleTestCase.urls`` will be removed.

* Using an incorrect count of unpacked values in the ``for`` template tag
  will raise an exception rather than fail silently.

* The ability to reverse URLs using a dotted Python path will be removed.

* The ability to use a dotted Python path for the ``LOGIN_URL`` and
  ``LOGIN_REDIRECT_URL`` settings will be removed.

* Support for :py:mod:`optparse` will be dropped for custom management commands
  (replaced by :py:mod:`argparse`).

* The class ``django.core.management.NoArgsCommand`` will be removed. Use
  :class:`~django.core.management.BaseCommand` instead, which takes no arguments
  by default.

* ``django.core.context_processors`` module will be removed.

* ``django.db.models.sql.aggregates`` module will be removed.

* ``django.contrib.gis.db.models.sql.aggregates`` module will be removed.

* The following methods and properties of ``django.db.sql.query.Query`` will
  be removed:

  * Properties: ``aggregates`` and ``aggregate_select``
  * Methods: ``add_aggregate``, ``set_aggregate_mask``, and
    ``append_aggregate_mask``.

* ``django.template.resolve_variable`` will be removed.

* The following private APIs will be removed from
  :class:`django.db.models.options.Options` (``Model._meta``):

  * ``get_field_by_name()``
  * ``get_all_field_names()``
  * ``get_fields_with_model()``
  * ``get_concrete_fields_with_model()``
  * ``get_m2m_with_model()``
  * ``get_all_related_objects()``
  * ``get_all_related_objects_with_model()``
  * ``get_all_related_many_to_many_objects()``
  * ``get_all_related_m2m_objects_with_model()``

* The ``error_message`` argument of ``django.forms.RegexField`` will be removed.

* The ``unordered_list`` filter will no longer support old style lists.

* Support for string ``view`` arguments to ``url()`` will be removed.

* The backward compatible shim  to rename ``django.forms.Form._has_changed()``
  to ``has_changed()`` will be removed.

* The ``removetags`` template filter will be removed.

* The ``remove_tags()`` and ``strip_entities()`` functions in
  ``django.utils.html`` will be removed.

* The ``is_admin_site`` argument to
  ``django.contrib.auth.views.password_reset()`` will be removed.

* ``django.db.models.field.subclassing.SubfieldBase`` will be removed.

* ``django.utils.checksums`` will be removed; its functionality is included
  in django-localflavor 1.1+.

* The ``original_content_type_id`` attribute on
  ``django.contrib.admin.helpers.InlineAdminForm`` will be removed.

* The backwards compatibility shim to allow ``FormMixin.get_form()`` to be
  defined with no default value for its ``form_class`` argument will be removed.

* The following settings will be removed:

  * ``ALLOWED_INCLUDE_ROOTS``
  * ``TEMPLATE_CONTEXT_PROCESSORS``
  * ``TEMPLATE_DEBUG``
  * ``TEMPLATE_DIRS``
  * ``TEMPLATE_LOADERS``
  * ``TEMPLATE_STRING_IF_INVALID``

* The backwards compatibility alias ``django.template.loader.BaseLoader`` will
  be removed.

* Django template objects returned by
  :func:`~django.template.loader.get_template` and
  :func:`~django.template.loader.select_template` won't accept a
  :class:`~django.template.Context` in their
  :meth:`~django.template.backends.base.Template.render()` method anymore.

* :doc:`Template response APIs </ref/template-response>` will enforce the use
  of :class:`dict` and backend-dependent template objects instead of
  :class:`~django.template.Context` and :class:`~django.template.Template`
  respectively.

* The ``current_app`` parameter for the following function and classes will be
  removed:

  * ``django.shortcuts.render()``
  * ``django.template.Context()``
  * ``django.template.RequestContext()``
  * ``django.template.response.TemplateResponse()``

* The ``dictionary`` and ``context_instance`` parameters for the following
  functions will be removed:

  * ``django.shortcuts.render()``
  * ``django.shortcuts.render_to_response()``
  * ``django.template.loader.render_to_string()``

* The ``dirs`` parameter for the following functions will be removed:

  * ``django.template.loader.get_template()``
  * ``django.template.loader.select_template()``
  * ``django.shortcuts.render()``
  * ``django.shortcuts.render_to_response()``

* Session verification will be enabled regardless of whether or not
  ``'django.contrib.auth.middleware.SessionAuthenticationMiddleware'`` is in
  ``MIDDLEWARE_CLASSES``.

* Private attribute ``django.db.models.Field.related`` will be removed.

* The ``--list`` option of the ``migrate`` management command will be removed.

* The ``ssi`` template tag will be removed.

* Support for the ``=`` comparison operator in the ``if`` template tag will be
  removed.

* The backwards compatibility shims to allow ``Storage.get_available_name()``
  and ``Storage.save()`` to be defined without a ``max_length`` argument will
  be removed.

* Support for the legacy ``%(<foo>)s`` syntax in ``ModelFormMixin.success_url``
  will be removed.

* ``GeoQuerySet`` aggregate methods ``collect()``, ``extent()``, ``extent3d()``,
  ``make_line()``, and ``unionagg()`` will be removed.

* Ability to specify ``ContentType.name`` when creating a content type instance
  will be removed.

* Support for the old signature of ``allow_migrate`` will be removed. It changed
  from ``allow_migrate(self, db, model)`` to
  ``allow_migrate(self, db, app_label, model_name=None, **hints)``.

* Support for the syntax of ``{% cycle %}`` that uses comma-separated arguments
  will be removed.

* The warning that :class:`~django.core.signing.Signer` issues when given an
  invalid separator will become an exception.

.. _deprecation-removed-in-1.9:

1.9
---

See the :ref:`Django 1.7 release notes<deprecated-features-1.7>` for more
details on these changes.

* ``django.utils.dictconfig`` will be removed.

* ``django.utils.importlib`` will be removed.

* ``django.utils.tzinfo`` will be removed.

* ``django.utils.unittest`` will be removed.

* The ``syncdb`` command will be removed.

* ``django.db.models.signals.pre_syncdb`` and
  ``django.db.models.signals.post_syncdb`` will be removed.

* ``allow_syncdb`` on database routers will no longer automatically become
  ``allow_migrate``.

* Automatic syncing of apps without migrations will be removed. Migrations will
  become compulsory for all apps unless you pass the ``--run-syncdb`` option to
  ``migrate``.

* The SQL management commands for apps without migrations, ``sql``, ``sqlall``,
  ``sqlclear``, ``sqldropindexes``, and ``sqlindexes``, will be removed.

* Support for automatic loading of ``initial_data`` fixtures and initial SQL
  data will be removed.

* All models will need to be defined inside an installed application or
  declare an explicit :attr:`~django.db.models.Options.app_label`.
  Furthermore, it won't be possible to import them before their application
  is loaded. In particular, it won't be possible to import models inside
  the root package of their application.

* The model and form ``IPAddressField`` will be removed. A stub field will
  remain for compatibility with historical migrations.

* ``AppCommand.handle_app()`` will no longer be supported.

* ``RequestSite`` and ``get_current_site()`` will no longer be importable from
  ``django.contrib.sites.models``.

* FastCGI support via the ``runfcgi`` management command will be
  removed. Please deploy your project using WSGI.

* ``django.utils.datastructures.SortedDict`` will be removed. Use
  :class:`collections.OrderedDict` from the Python standard library instead.

* ``ModelAdmin.declared_fieldsets`` will be removed.

* Instances of ``util.py`` in the Django codebase have been renamed to
  ``utils.py`` in an effort to unify all util and utils references.
  The modules that provided backwards compatibility will be removed:

  * ``django.contrib.admin.util``
  * ``django.contrib.gis.db.backends.util``
  * ``django.db.backends.util``
  * ``django.forms.util``

* ``ModelAdmin.get_formsets`` will be removed.

* The backward compatibility shim introduced to rename the
  ``BaseMemcachedCache._get_memcache_timeout()`` method to
  ``get_backend_timeout()`` will be removed.

* The ``--natural`` and ``-n`` options for :djadmin:`dumpdata` will be removed.

* The ``use_natural_keys`` argument for ``serializers.serialize()`` will be
  removed.

* Private API ``django.forms.forms.get_declared_fields()`` will be removed.

* The ability to use a ``SplitDateTimeWidget`` with ``DateTimeField`` will be
  removed.

* The ``WSGIRequest.REQUEST`` property will be removed.

* The class ``django.utils.datastructures.MergeDict`` will be removed.

* The ``zh-cn`` and ``zh-tw`` language codes will be removed and have been
  replaced by the ``zh-hans`` and ``zh-hant`` language code respectively.

* The internal ``django.utils.functional.memoize`` will be removed.

* ``django.core.cache.get_cache`` will be removed. Add suitable entries
  to :setting:`CACHES` and use :data:`django.core.cache.caches` instead.

* ``django.db.models.loading`` will be removed.

* Passing callable arguments to querysets will no longer be possible.

* ``BaseCommand.requires_model_validation`` will be removed in favor of
  ``requires_system_checks``. Admin validators will be replaced by admin
  checks.

* The ``ModelAdmin.validator_class`` and ``default_validator_class`` attributes
  will be removed.

* ``ModelAdmin.validate()`` will be removed.

* ``django.db.backends.DatabaseValidation.validate_field`` will be removed in
  favor of the ``check_field`` method.

* The ``validate`` management command will be removed.

* ``django.utils.module_loading.import_by_path`` will be removed in favor of
  ``django.utils.module_loading.import_string``.

* ``ssi`` and ``url`` template tags will be removed from the ``future`` template
  tag library (used during the 1.3/1.4 deprecation period).

* ``django.utils.text.javascript_quote`` will be removed.

* Database test settings as independent entries in the database settings,
  prefixed by ``TEST_``, will no longer be supported.

* The `cache_choices` option to :class:`~django.forms.ModelChoiceField` and
  :class:`~django.forms.ModelMultipleChoiceField` will be removed.

* The default value of the
  :attr:`RedirectView.permanent <django.views.generic.base.RedirectView.permanent>`
  attribute will change from ``True`` to ``False``.

* ``django.contrib.sitemaps.FlatPageSitemap`` will be removed in favor of
  ``django.contrib.flatpages.sitemaps.FlatPageSitemap``.

* Private API ``django.test.utils.TestTemplateLoader`` will be removed.

* The ``django.contrib.contenttypes.generic`` module will be removed.

* Private APIs ``django.db.models.sql.where.WhereNode.make_atom()`` and
  ``django.db.models.sql.where.Constraint`` will be removed.

.. _deprecation-removed-in-1.8:

1.8
---

See the :ref:`Django 1.6 release notes<deprecated-features-1.6>` for more
details on these changes.

* ``django.contrib.comments`` will be removed.

* The following transaction management APIs will be removed:

  - ``TransactionMiddleware``,
  - the decorators and context managers ``autocommit``, ``commit_on_success``,
    and ``commit_manually``, defined in ``django.db.transaction``,
  - the functions ``commit_unless_managed`` and ``rollback_unless_managed``,
    also defined in ``django.db.transaction``,
  - the ``TRANSACTIONS_MANAGED`` setting.

* The :ttag:`cycle` and :ttag:`firstof` template tags will auto-escape their
  arguments. In 1.6 and 1.7, this behavior is provided by the version of these
  tags in the ``future`` template tag library.

* The ``SEND_BROKEN_LINK_EMAILS`` setting will be removed. Add the
  :class:`django.middleware.common.BrokenLinkEmailsMiddleware` middleware to
  your :setting:`MIDDLEWARE_CLASSES` setting instead.

* ``django.middleware.doc.XViewMiddleware`` will be removed. Use
  ``django.contrib.admindocs.middleware.XViewMiddleware`` instead.

* ``Model._meta.module_name`` was renamed to ``model_name``.

* Remove the backward compatible shims introduced to rename ``get_query_set``
  and similar queryset methods. This affects the following classes:
  ``BaseModelAdmin``, ``ChangeList``, ``BaseCommentNode``,
  ``GenericForeignKey``, ``Manager``, ``SingleRelatedObjectDescriptor`` and
  ``ReverseSingleRelatedObjectDescriptor``.

* Remove the backward compatible shims introduced to rename the attributes
  ``ChangeList.root_query_set`` and ``ChangeList.query_set``.

* ``django.views.defaults.shortcut`` will be removed, as part of the
  goal of removing all ``django.contrib`` references from the core
  Django codebase. Instead use
  ``django.contrib.contenttypes.views.shortcut``. ``django.conf.urls.shortcut``
  will also be removed.

* Support for the Python Imaging Library (PIL) module will be removed, as it
  no longer appears to be actively maintained & does not work on Python 3.
  You are advised to install `Pillow`_, which should be used instead.

  .. _`Pillow`: https://pypi.python.org/pypi/Pillow

* The following private APIs will be removed:

  - ``django.db.backend``
  - ``django.db.close_connection()``
  - ``django.db.backends.creation.BaseDatabaseCreation.set_autocommit()``
  - ``django.db.transaction.is_managed()``
  - ``django.db.transaction.managed()``

* ``django.forms.widgets.RadioInput`` will be removed in favor of
  ``django.forms.widgets.RadioChoiceInput``.

* The module ``django.test.simple`` and the class
  ``django.test.simple.DjangoTestSuiteRunner`` will be removed. Instead use
  ``django.test.runner.DiscoverRunner``.

* The module ``django.test._doctest`` will be removed. Instead use the doctest
  module from the Python standard library.

* The ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting will be removed.

* Usage of the hard-coded *Hold down "Control", or "Command" on a Mac, to select
  more than one.* string to override or append to user-provided ``help_text`` in
  forms for ManyToMany model fields will not be performed by Django anymore
  either at the model or forms layer.

* The ``Model._meta.get_(add|change|delete)_permission`` methods will
  be removed.

* The session key ``django_language`` will no longer be read for backwards
  compatibility.

* Geographic Sitemaps will be removed
  (``django.contrib.gis.sitemaps.views.index`` and
  ``django.contrib.gis.sitemaps.views.sitemap``).

* ``django.utils.html.fix_ampersands``, the ``fix_ampersands`` template filter and
  ``django.utils.html.clean_html`` will be removed following an accelerated deprecation.

.. _deprecation-removed-in-1.7:

1.7
---

See the :ref:`Django 1.5 release notes<deprecated-features-1.5>` for more
details on these changes.

* The module ``django.utils.simplejson`` will be removed. The standard library
  provides :mod:`json` which should be used instead.

* The function ``django.utils.itercompat.product`` will be removed. The Python
  builtin version should be used instead.

* Auto-correction of INSTALLED_APPS and TEMPLATE_DIRS settings when they are
  specified as a plain string instead of a tuple will be removed and raise an
  exception.

* The ``mimetype`` argument to the ``__init__`` methods of
  :class:`~django.http.HttpResponse`,
  :class:`~django.template.response.SimpleTemplateResponse`, and
  :class:`~django.template.response.TemplateResponse`, will be removed.
  ``content_type`` should be used instead. This also applies to the
  ``render_to_response()`` shortcut and the sitemap views,
  :func:`~django.contrib.sitemaps.views.index` and
  :func:`~django.contrib.sitemaps.views.sitemap`.

* When :class:`~django.http.HttpResponse` is instantiated with an iterator,
  or when :attr:`~django.http.HttpResponse.content` is set to an iterator,
  that iterator will be immediately consumed.

* The ``AUTH_PROFILE_MODULE`` setting, and the ``get_profile()`` method on
  the User model, will be removed.

* The ``cleanup`` management command will be removed. It's replaced by
  ``clearsessions``.

* The ``daily_cleanup.py`` script will be removed.

* The ``depth`` keyword argument will be removed from
  :meth:`~django.db.models.query.QuerySet.select_related`.

* The undocumented ``get_warnings_state()``/``restore_warnings_state()``
  functions from :mod:`django.test.utils` and the ``save_warnings_state()``/
  ``restore_warnings_state()``
  :ref:`django.test.*TestCase <django-testcase-subclasses>` methods are
  deprecated. Use the :class:`warnings.catch_warnings` context manager
  available starting with Python 2.6 instead.

* The undocumented ``check_for_test_cookie`` method in
  :class:`~django.contrib.auth.forms.AuthenticationForm` will be removed
  following an accelerated deprecation. Users subclassing this form should
  remove calls to this method, and instead ensure that their auth related views
  are CSRF protected, which ensures that cookies are enabled.

* The version of :func:`django.contrib.auth.views.password_reset_confirm` that
  supports base36 encoded user IDs
  (``django.contrib.auth.views.password_reset_confirm_uidb36``) will be
  removed. If your site has been running Django 1.6 for more than
  :setting:`PASSWORD_RESET_TIMEOUT_DAYS`, this change will have no effect. If
  not, then any password reset links generated before you upgrade to Django 1.7
  won't work after the upgrade.

* The ``django.utils.encoding.StrAndUnicode`` mix-in will be removed.
  Define a ``__str__`` method and apply the
  :func:`~django.utils.encoding.python_2_unicode_compatible` decorator instead.

.. _deprecation-removed-in-1.6:

1.6
---

See the :ref:`Django 1.4 release notes<deprecated-features-1.4>` for more
details on these changes.

* ``django.contrib.databrowse`` will be removed.

* ``django.contrib.localflavor`` will be removed following an accelerated
  deprecation.

* ``django.contrib.markup`` will be removed following an accelerated
  deprecation.

* The compatibility modules ``django.utils.copycompat`` and
  ``django.utils.hashcompat`` as well as the functions
  ``django.utils.itercompat.all`` and ``django.utils.itercompat.any`` will
  be removed. The Python builtin versions should be used instead.

* The ``csrf_response_exempt`` and ``csrf_view_exempt`` decorators will
  be removed. Since 1.4 ``csrf_response_exempt`` has been a no-op (it
  returns the same function), and ``csrf_view_exempt`` has been a
  synonym for ``django.views.decorators.csrf.csrf_exempt``, which should
  be used to replace it.

* The ``django.core.cache.backends.memcached.CacheClass`` backend
  was split into two in Django 1.3 in order to introduce support for
  PyLibMC. The historical ``CacheClass`` will be removed in favor of
  ``django.core.cache.backends.memcached.MemcachedCache``.

* The UK-prefixed objects of ``django.contrib.localflavor.uk`` will only
  be accessible through their GB-prefixed names (GB is the correct
  ISO 3166 code for United Kingdom).

* The ``IGNORABLE_404_STARTS`` and ``IGNORABLE_404_ENDS`` settings have been
  superseded by :setting:`IGNORABLE_404_URLS` in the 1.4 release. They will be
  removed.

* The form wizard has been refactored to use class-based views with pluggable
  backends in 1.4. The previous implementation will be removed.

* Legacy ways of calling
  :func:`~django.views.decorators.cache.cache_page` will be removed.

* The backward-compatibility shim to automatically add a debug-false
  filter to the ``'mail_admins'`` logging handler will be removed. The
  :setting:`LOGGING` setting should include this filter explicitly if
  it is desired.

* The builtin truncation functions ``django.utils.text.truncate_words()``
  and ``django.utils.text.truncate_html_words()`` will be removed in
  favor of the ``django.utils.text.Truncator`` class.

* The :class:`~django.contrib.gis.geoip.GeoIP` class was moved to
  :mod:`django.contrib.gis.geoip` in 1.4 -- the shortcut in
  :mod:`django.contrib.gis.utils` will be removed.

* ``django.conf.urls.defaults`` will be removed. The functions
  :func:`~django.conf.urls.include`, ``patterns()`` and
  :func:`~django.conf.urls.url` plus :data:`~django.conf.urls.handler404`,
  :data:`~django.conf.urls.handler500`, are now available through
  :mod:`django.conf.urls` .

* The functions ``setup_environ()`` and ``execute_manager()`` will be removed
  from :mod:`django.core.management`. This also means that the old (pre-1.4)
  style of :file:`manage.py` file will no longer work.

* Setting the ``is_safe`` and ``needs_autoescape`` flags as attributes of
  template filter functions will no longer be supported.

* The attribute ``HttpRequest.raw_post_data`` was renamed to ``HttpRequest.body``
  in 1.4. The backward compatibility will be removed --
  ``HttpRequest.raw_post_data`` will no longer work.

* The value for the ``post_url_continue`` parameter in
  ``ModelAdmin.response_add()`` will have to be either ``None`` (to redirect
  to the newly created object's edit page) or a pre-formatted url. String
  formats, such as the previous default ``'../%s/'``, will not be accepted any
  more.

.. _deprecation-removed-in-1.5:

1.5
---

See the :ref:`Django 1.3 release notes<deprecated-features-1.3>` for more
details on these changes.

* Starting Django without a :setting:`SECRET_KEY` will result in an exception
  rather than a ``DeprecationWarning``. (This is accelerated from the usual
  deprecation path; see the :doc:`Django 1.4 release notes</releases/1.4>`.)

* The ``mod_python`` request handler will be removed. The ``mod_wsgi``
  handler should be used instead.

* The ``template`` attribute on ``django.test.client.Response``
  objects returned by the :ref:`test client <test-client>` will be removed.
  The :attr:`~django.test.Response.templates` attribute should be
  used instead.

* The ``django.test.simple.DjangoTestRunner`` will be removed.
  Instead use a unittest-native class.  The features of the
  ``django.test.simple.DjangoTestRunner`` (including fail-fast and
  Ctrl-C test termination) can currently be provided by the unittest-native
  :class:`~unittest.TextTestRunner`.

* The undocumented function
  ``django.contrib.formtools.utils.security_hash`` will be removed,
  instead use ``django.contrib.formtools.utils.form_hmac``

* The function-based generic view modules will be removed in favor of their
  class-based equivalents, outlined :doc:`here
  </topics/class-based-views/index>`.

* The ``django.core.servers.basehttp.AdminMediaHandler`` will be
  removed.  In its place use
  ``django.contrib.staticfiles.handlers.StaticFilesHandler``.

* The template tags library ``adminmedia`` and the template tag ``{%
  admin_media_prefix %}`` will be removed in favor of the generic static files
  handling. (This is faster than the usual deprecation path; see the
  :doc:`Django 1.4 release notes</releases/1.4>`.)

* The ``url`` and ``ssi`` template tags will be modified so that the first
  argument to each tag is a template variable, not an implied string. In 1.4,
  this behavior is provided by a version of the tag in the ``future`` template
  tag library.

* The ``reset`` and ``sqlreset`` management commands will be removed.

* Authentication backends will need to support an inactive user
  being passed to all methods dealing with permissions.
  The ``supports_inactive_user`` attribute will no longer be checked
  and can be removed from custom backends.

* :meth:`~django.contrib.gis.geos.GEOSGeometry.transform` will raise
  a :class:`~django.contrib.gis.geos.GEOSException` when called
  on a geometry with no SRID value.

* ``django.http.CompatCookie`` will be removed in favor of
  ``django.http.SimpleCookie``.

* ``django.core.context_processors.PermWrapper`` and
  ``django.core.context_processors.PermLookupDict`` will be removed in
  favor of the corresponding
  ``django.contrib.auth.context_processors.PermWrapper`` and
  ``django.contrib.auth.context_processors.PermLookupDict``, respectively.

* The :setting:`MEDIA_URL` or :setting:`STATIC_URL` settings will be
  required to end with a trailing slash to ensure there is a consistent
  way to combine paths in templates.

* ``django.db.models.fields.URLField.verify_exists`` will be removed. The
  feature was deprecated in 1.3.1 due to intractable security and
  performance issues and will follow a slightly accelerated deprecation
  timeframe.

* Translations located under the so-called *project path* will be ignored during
  the translation building process performed at runtime. The
  :setting:`LOCALE_PATHS` setting can be used for the same task by including the
  filesystem path to a ``locale`` directory containing non-app-specific
  translations in its value.

* The Markup contrib app will no longer support versions of Python-Markdown
  library earlier than 2.1. An accelerated timeline was used as this was
  a security related deprecation.

* The ``CACHE_BACKEND`` setting will be removed. The cache backend(s) should be
  specified in the :setting:`CACHES` setting.

.. _deprecation-removed-in-1.4:

1.4
---

See the :ref:`Django 1.2 release notes<deprecated-features-1.2>` for more
details on these changes.

* ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` will be removed.  Use
  the ``{% csrf_token %}`` template tag inside forms to enable CSRF
  protection. ``CsrfViewMiddleware`` remains and is enabled by default.

* The old imports for CSRF functionality (``django.contrib.csrf.*``),
  which moved to core in 1.2, will be removed.

* The ``django.contrib.gis.db.backend`` module will be removed in favor
  of the specific backends.

* ``SMTPConnection`` will be removed in favor of a generic Email backend API.

* The many to many SQL generation functions on the database backends
  will be removed.

* The ability to use the ``DATABASE_*`` family of top-level settings to
  define database connections will be removed.

* The ability to use shorthand notation to specify a database backend
  (i.e., ``sqlite3`` instead of ``django.db.backends.sqlite3``) will be
  removed.

* The ``get_db_prep_save``, ``get_db_prep_value`` and
  ``get_db_prep_lookup`` methods will have to support multiple databases.

* The ``Message`` model (in ``django.contrib.auth``), its related
  manager in the ``User`` model (``user.message_set``), and the
  associated methods (``user.message_set.create()`` and
  ``user.get_and_delete_messages()``), will be removed.  The
  :doc:`messages framework </ref/contrib/messages>` should be used
  instead. The related ``messages`` variable returned by the
  auth context processor will also be removed. Note that this
  means that the admin application will depend on the messages
  context processor.

* Authentication backends will need to support the ``obj`` parameter for
  permission checking. The ``supports_object_permissions`` attribute
  will no longer be checked and can be removed from custom backends.

* Authentication backends will need to support the ``AnonymousUser`` class
  being passed to all methods dealing with permissions.  The
  ``supports_anonymous_user`` variable will no longer be checked and can be
  removed from custom backends.

* The ability to specify a callable template loader rather than a
  ``Loader`` class will be removed, as will the ``load_template_source``
  functions that are included with the built in template loaders for
  backwards compatibility.

* ``django.utils.translation.get_date_formats()`` and
  ``django.utils.translation.get_partial_date_formats()``. These functions
  will be removed; use the locale-aware
  ``django.utils.formats.get_format()`` to get the appropriate formats.

* In ``django.forms.fields``, the constants: ``DEFAULT_DATE_INPUT_FORMATS``,
  ``DEFAULT_TIME_INPUT_FORMATS`` and
  ``DEFAULT_DATETIME_INPUT_FORMATS`` will be removed. Use
  ``django.utils.formats.get_format()`` to get the appropriate
  formats.

* The ability to use a function-based test runner will be removed,
  along with the ``django.test.simple.run_tests()`` test runner.

* The ``views.feed()`` view and ``feeds.Feed`` class in
  ``django.contrib.syndication`` will be removed. The class-based view
  ``views.Feed`` should be used instead.

* ``django.core.context_processors.auth``.  This release will
  remove the old method in favor of the new method in
  ``django.contrib.auth.context_processors.auth``.

* The ``postgresql`` database backend will be removed, use the
  ``postgresql_psycopg2`` backend instead.

* The ``no`` language code will be removed and has been replaced by the
  ``nb`` language code.

* Authentication backends will need to define the boolean attribute
  ``supports_inactive_user`` until version 1.5 when it will be assumed that
  all backends will handle inactive users.

* ``django.db.models.fields.XMLField`` will be removed. This was
  deprecated as part of the 1.3 release. An accelerated deprecation
  schedule has been used because the field hasn't performed any role
  beyond that of a simple ``TextField`` since the removal of ``oldforms``.
  All uses of ``XMLField`` can be replaced with ``TextField``.

* The undocumented ``mixin`` parameter to the ``open()`` method of
  ``django.core.files.storage.Storage`` (and subclasses) will be removed.

.. _deprecation-removed-in-1.3:

1.3
---

See the :ref:`Django 1.1 release notes<deprecated-features-1.1>` for more
details on these changes.

* ``AdminSite.root()``.  This method of hooking up the admin URLs will be
  removed in favor of including ``admin.site.urls``.

* Authentication backends need to define the boolean attributes
  ``supports_object_permissions`` and ``supports_anonymous_user`` until
  version 1.4, at which point it will be assumed that all backends will
  support these options.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Internals Git (`大一小学期/Week_3-Python/exam/2016/docs/internals/git.txt`)

=================================
The Django source code repository
=================================

When deploying a Django application into a real production environment, you
will almost always want to use `an official packaged release of Django`_.

However, if you'd like to try out in-development code from an upcoming release
or contribute to the development of Django, you'll need to obtain a clone of
Django's source code repository.

This document covers the way the code repository is laid out and how to work
with and find things in it.

.. _an official packaged release of Django: https://www.djangoproject.com/download/

High-level overview
===================

The Django source code repository uses `Git`_ to track changes to the code
over time, so you'll need a copy of the Git client (a program called ``git``)
on your computer, and you'll want to familiarize yourself with the basics of
how Git works.

Git's website offers downloads for various operating systems. The site also
contains vast amounts of `documentation`_.

The Django Git repository is located online at `github.com/django/django
<https://github.com/django/django>`_. It contains the full source code for all
Django releases, which you can browse online.

The Git repository includes several `branches`_:

* ``master`` contains the main in-development code which will become
  the next packaged release of Django. This is where most development
  activity is focused.

* ``stable/A.B.x`` are the branches where release preparation work happens.
  They are also used for bugfix and security releases which occur as necessary
  after the initial release of a feature version.

* ``soc20XX/<project>`` branches were used by students who worked on Django
  during the 2009 and 2010 Google Summer of Code programs.

* ``attic/<project>`` branches were used to develop major or experimental new
  features without affecting the rest of Django's code.

The Git repository also contains `tags`_. These are the exact revisions from
which packaged Django releases were produced, since version 1.0.

The source code for the `Djangoproject.com <https://www.djangoproject.com/>`_
website can be found at `github.com/django/djangoproject.com
<https://github.com/django/djangoproject.com>`_.

.. _Git: http://git-scm.com/
.. _documentation: http://git-scm.com/documentation
.. _branches: https://github.com/django/django/branches
.. _tags: https://github.com/django/django/tags

The master branch
=================

If you'd like to try out the in-development code for the next release of
Django, or if you'd like to contribute to Django by fixing bugs or developing
new features, you'll want to get the code from the master branch.

Note that this will get *all* of Django: in addition to the top-level
``django`` module containing Python code, you'll also get a copy of Django's
documentation, test suite, packaging scripts and other miscellaneous bits.
Django's code will be present in your clone as a directory named
``django``.

To try out the in-development code with your own applications, simply place
the directory containing your clone on your Python import path. Then
``import`` statements which look for Django will find the ``django`` module
within your clone.

If you're going to be working on Django's code (say, to fix a bug or
develop a new feature), you can probably stop reading here and move
over to :doc:`the documentation for contributing to Django
</internals/contributing/index>`, which covers things like the preferred
coding style and how to generate and submit a patch.

Other branches
==============

Django uses branches to prepare for releases of Django.

In the past when Django was hosted on Subversion, branches were also used for
feature development. Now Django is hosted on Git and feature development is
done on contributor's forks, but the Subversion feature branches remain in Git
for historical reference.

Stable branches
---------------

These branches can be found in the repository as ``stable/A.B.x``
branches and will be created right after the first alpha is tagged.

For example, immediately after *Django 1.5 alpha 1* was tagged, the branch
``stable/1.5.x`` was created and all further work on preparing the code for the
final 1.5 release was done there.

These branches also provide limited bugfix support for the most recent released
version of Django and security support for the two most recently-released
versions of Django.

For example, after the release of Django 1.5, the branch ``stable/1.5.x``
receives only fixes for security and critical stability bugs, which are
eventually released as Django 1.5.1 and so on, ``stable/1.4.x`` receives only
security fixes, and ``stable/1.3.x`` no longer receives any updates.

.. admonition:: Historical information

    This policy for handling ``stable/A.B.x`` branches was adopted starting
    with the Django 1.5 release cycle.

    Previously, these branches weren't created until right after the releases
    and the stabilization work occurred on the main repository branch. Thus,
    no new features development work for the next release of Django could be
    committed until the final release happened.

    For example, shortly after the release of Django 1.3 the branch
    ``stable/1.3.x`` was created. Official support for that release has expired,
    and so it no longer receives direct maintenance from the Django project.
    However, that and all other similarly named branches continue to exist and
    interested community members have occasionally used them to provide
    unofficial support for old Django releases.

Feature-development branches
----------------------------

.. admonition:: Historical information

    Since Django moved to Git in 2012, anyone can clone the repository and
    create their own branches, alleviating the need for official branches in
    the source code repository.

    The following section is mostly useful if you're exploring the repository's
    history, for example if you're trying to understand how some features were
    designed.

Feature-development branches tend by their nature to be temporary. Some
produce successful features which are merged back into Django's master to
become part of an official release, but others do not; in either case there
comes a time when the branch is no longer being actively worked on by any
developer. At this point the branch is considered closed.

Unfortunately, Django used to be maintained with the Subversion revision
control system, that has no standard way of indicating this. As a workaround,
branches of Django which are closed and no longer maintained were moved into
``attic``.

For reference, the following are branches whose code eventually became
part of Django itself, and so are no longer separately maintained:

* ``boulder-oracle-sprint``: Added support for Oracle databases to
  Django's object-relational mapper. This has been part of Django
  since the 1.0 release.

* ``gis``: Added support for geographic/spatial queries to Django's
  object-relational mapper. This has been part of Django since the 1.0
  release, as the bundled application ``django.contrib.gis``.

* ``i18n``: Added :doc:`internationalization support </topics/i18n/index>` to
  Django. This has been part of Django since the 0.90 release.

* ``magic-removal``: A major refactoring of both the internals and
  public APIs of Django's object-relational mapper. This has been part
  of Django since the 0.95 release.

* ``multi-auth``: A refactoring of :doc:`Django's bundled
  authentication framework </topics/auth/index>` which added support for
  :ref:`authentication backends <authentication-backends>`. This has
  been part of Django since the 0.95 release.

* ``new-admin``: A refactoring of :doc:`Django's bundled
  administrative application </ref/contrib/admin/index>`. This became part of
  Django as of the 0.91 release, but was superseded by another
  refactoring (see next listing) prior to the Django 1.0 release.

* ``newforms-admin``: The second refactoring of Django's bundled
  administrative application. This became part of Django as of the 1.0
  release, and is the basis of the current incarnation of
  ``django.contrib.admin``.

* ``queryset-refactor``: A refactoring of the internals of Django's
  object-relational mapper. This became part of Django as of the 1.0
  release.

* ``unicode``: A refactoring of Django's internals to consistently use
  Unicode-based strings in most places within Django and Django
  applications. This became part of Django as of the 1.0 release.

When Django moved from SVN to Git, the information about branch merges wasn't
preserved in the source code repository. This means that the ``master`` branch
of Django doesn't contain merge commits for the above branches.

However, this information is `available as a grafts file`_. You can restore it
by putting the following lines in ``.git/info/grafts`` in your local clone::

  ac64e91a0cadc57f4bc5cd5d66955832320ca7a1 553a20075e6991e7a60baee51ea68c8adc520d9a 0cb8e31823b2e9f05c4ae868c19f5f38e78a5f2e
  79e68c225b926302ebb29c808dda8afa49856f5c d0f57e7c7385a112cb9e19d314352fc5ed5b0747 aa239e3e5405933af6a29dac3cf587b59a099927
  5cf8f684237ab5addaf3549b2347c3adf107c0a7 cb45fd0ae20597306cd1f877efc99d9bd7cbee98 e27211a0deae2f1d402537f0ebb64ad4ccf6a4da
  f69cf70ed813a8cd7e1f963a14ae39103e8d5265 d5dbeaa9be359a4c794885c2e9f1b5a7e5e51fb8 d2fcbcf9d76d5bb8a661ee73dae976c74183098b
  aab3a418ac9293bb4abd7670f65d930cb0426d58 4ea7a11659b8a0ab07b0d2e847975f7324664f10 adf4b9311d5d64a2bdd58da50271c121ea22e397
  ff60c5f9de3e8690d1e86f3e9e3f7248a15397c8 7ef212af149540aa2da577a960d0d87029fd1514 45b4288bb66a3cda401b45901e85b645674c3988
  9dda4abee1225db7a7b195b84c915fdd141a7260 4fe5c9b7ee09dc25921918a6dbb7605edb374bc9 3a7c14b583621272d4ef53061287b619ce3c290d
  a19ed8aea395e8e07164ff7d85bd7dff2f24edca dc375fb0f3b7fbae740e8cfcd791b8bccb8a4e66 42ea7a5ce8aece67d16c6610a49560c1493d4653
  9c52d56f6f8a9cdafb231adf9f4110473099c9b5 c91a30f00fd182faf8ca5c03cd7dbcf8b735b458 4a5c5c78f2ecd4ed8859cd5ac773ff3a01bccf96
  953badbea5a04159adbfa970f5805c0232b6a401 4c958b15b250866b70ded7d82aa532f1e57f96ae 5664a678b29ab04cad425c15b2792f4519f43928
  471596fc1afcb9c6258d317c619eaf5fd394e797 4e89105d64bb9e04c409139a41e9c7aac263df4c 3e9035a9625c8a8a5e88361133e87ce455c4fc13
  9233d0426537615e06b78d28010d17d5a66adf44 6632739e94c6c38b4c5a86cf5c80c48ae50ac49f 18e151bc3f8a85f2766d64262902a9fcad44d937

.. _available as a grafts file: https://github.com/ramiro/django-git-grafts

Additionally, the following branches are closed, but their code was
never merged into Django and the features they aimed to implement
were never finished:

* ``full-history``

* ``generic-auth``

* ``multiple-db-support``

* ``per-object-permissions``

* ``schema-evolution``

* ``schema-evolution-ng``

* ``search-api``

* ``sqlalchemy``

All of the above-mentioned branches now reside in ``attic``.

Finally, the repository contains ``soc2009/xxx`` and ``soc2010/xxx`` feature
branches, used for Google Summer of Code projects.

Tags
====

Each Django release is tagged and signed by a :ref:`releaser
<releasers-list>`.

The tags can be found on GitHub's `tags`_ page.

.. _tags: https://github.com/django/django/tags

---

### 大一小学期 Week 3 Python Exam 2016 Docs Internals Howto Release Django (`大一小学期/Week_3-Python/exam/2016/docs/internals/howto-release-django.txt`)

=====================
How is Django Formed?
=====================

.. highlight:: console

This document explains how to release Django.

**Please, keep these instructions up-to-date if you make changes!** The point
here is to be descriptive, not prescriptive, so feel free to streamline or
otherwise make changes, but **update this document accordingly!**

Overview
========

There are three types of releases that you might need to make:

* Security releases: disclosing and fixing a vulnerability. This'll
  generally involve two or three simultaneous releases -- e.g.
  1.5.x, 1.6.x, and, depending on timing, perhaps a 1.7 alpha/beta/rc.

* Regular version releases: either a final release (e.g. 1.5) or a
  bugfix update (e.g. 1.5.1).

* Pre-releases: e.g. 1.6 alpha, beta, or rc.

The short version of the steps involved is:

#. If this is a security release, pre-notify the security distribution list
   one week before the actual release.

#. Proofread the release notes, looking for organization and writing errors.
   Draft a blog post and email announcement.

#. Update version numbers and create the release package(s).

#. Upload the package(s) to the ``djangoproject.com`` server.

#. Upload the new version(s) to PyPI.

#. Declare the new version in the admin on ``djangoproject.com``.

#. Post the blog entry and send out the email announcements.

#. Update version numbers post-release.

There are a lot of details, so please read on.

Prerequisites
=============

You'll need a few things before getting started:

* A GPG key. If the key you want to use is not your default signing key, you'll
  need to add ``-u you@example.com`` to every GPG signing command below, where
  ``you@example.com`` is the email address associated with the key you want to
  use.

* An install of some required Python packages::

      $ pip install wheel twine

* Access to Django's record on PyPI. Create a file with your credentials:

  .. snippet::
    :filename: ~/.pypirc

    [pypi]
    username:YourUsername
    password:YourPassword

* Access to the ``djangoproject.com`` server to upload files.

* Access to the admin on ``djangoproject.com`` as a "Site maintainer".

* Access to post to ``django-announce``.

* If this is a security release, access to the pre-notification distribution
  list.

If this is your first release, you'll need to coordinate with James and/or
Jacob to get all these things lined up.

Pre-release tasks
=================

A few items need to be taken care of before even beginning the release process.
This stuff starts about a week before the release; most of it can be done
any time leading up to the actual release:

#. If this is a security release, send out pre-notification **one week** before
   the release. We maintain a list of who gets these pre-notification emails in
   the private ``django-core`` repository. Send the mail to
   ``security@djangoproject.com`` and BCC the pre-notification recipients.
   This email should be signed by the key you'll use for the release, and
   should include patches for each issue being fixed.

#. As the release approaches, watch Trac to make sure no release blockers
   are left for the upcoming release.

#. Check with the other committers to make sure they don't have any
   uncommitted changes for the release.

#. Proofread the release notes, including looking at the online
   version to catch any broken links or reST errors, and make sure the
   release notes contain the correct date.

#. Double-check that the release notes mention deprecation timelines
   for any APIs noted as deprecated, and that they mention any changes
   in Python version support.

#. Double-check that the release notes index has a link to the notes
   for the new release; this will be in ``docs/releases/index.txt``.

#. If this is a feature release, ensure translations from Transifex have been
   integrated. This is typically done by a separate translation's manager
   rather than the releaser, but here are the steps. Provided you have an
   account on Transifex::

        $ python scripts/manage_translations.py fetch

   and then commit the changed/added files (both .po and .mo). Sometimes there
   are validation errors which need to be debugged, so avoid doing this task
   immediately before a release is needed.

#. :ref:`Update the django-admin manual page <django-admin-manpage>`::

        $ cd docs
        $ make man
        $ man _build/man/django-admin.1  # do a quick sanity check
        $ cp _build/man/django-admin.1 man/django-admin.1

   and then commit the changed man page.

Preparing for release
=====================

Write the announcement blog post for the release. You can enter it into the
admin at any time and mark it as inactive. Here are a few examples: `example
security release announcement`__, `example regular release announcement`__,
`example pre-release announcement`__.

__ https://www.djangoproject.com/weblog/2013/feb/19/security/
__ https://www.djangoproject.com/weblog/2012/mar/23/14/
__ https://www.djangoproject.com/weblog/2012/nov/27/15-beta-1/

Actually rolling the release
============================

OK, this is the fun part, where we actually push out a release!

#. Check `Jenkins`__ is green for the version(s) you're putting out. You
   probably shouldn't issue a release until it's green.

   __ http://djangoci.com

#. A release always begins from a release branch, so you should make sure
   you're on a stable branch and up-to-date. For example::

        $ git checkout stable/1.5.x
        $ git pull

#. If this is a security release, merge the appropriate patches from
   ``django-private``. Rebase these patches as necessary to make each one a
   simple commit on the release branch rather than a merge commit. To ensure
   this, merge them with the ``--ff-only`` flag; for example::

        $ git checkout stable/1.5.x
        $ git merge --ff-only security/1.5.x

   (This assumes ``security/1.5.x`` is a branch in the ``django-private`` repo
   containing the necessary security patches for the next release in the 1.5
   series.)

   If git refuses to merge with ``--ff-only``, switch to the security-patch
   branch and rebase it on the branch you are about to merge it into (``git
   checkout security/1.5.x; git rebase stable/1.5.x``) and then switch back and
   do the merge. Make sure the commit message for each security fix explains
   that the commit is a security fix and that an announcement will follow
   (`example security commit`__).

   __ https://github.com/django/django/commit/3ef4bbf495cc6c061789132e3d50a8231a89406b

#. For a feature release, remove the ``UNDER DEVELOPMENT`` header at the
   top of the release notes and add the release date on the next line. For a
   patch release, replace ``*Under Development*`` with the release date. Make
   this change on all branches where the release notes for a particular version
   are located.

#. Update the version number in ``django/__init__.py`` for the release.
   Please see `notes on setting the VERSION tuple`_ below for details
   on ``VERSION``.

#. If this is a pre-release package, update the "Development Status" trove
   classifier in ``setup.py`` to reflect this. Otherwise, make sure the
   classifier is set to ``Development Status :: 5 - Production/Stable``.

#. Tag the release using ``git tag``. For example::

        $ git tag --sign --message="Tag 1.5.1" 1.5.1

   You can check your work by running ``git tag --verify <tag>``.

#. Push your work, including the tag: ``git push --tags``.

#. Make sure you have an absolutely clean tree by running ``git clean -dfx``.

#. Run ``make -f extras/Makefile`` to generate the release packages. This will
   create the release packages in a ``dist/`` directory.

#. Generate the hashes of the release packages::

        $ cd dist
        $ md5sum *
        $ sha1sum *
        $ sha256sum *

#. Create a "checksums" file, ``Django-<<VERSION>>.checksum.txt`` containing
   the hashes and release information. Start with this template and insert the
   correct version, date, GPG key ID (from
   ``gpg --list-keys --keyid-format LONG``), release URL, and checksums:

   .. code-block:: text

    This file contains MD5, SHA1, and SHA256 checksums for the source-code
    tarball and wheel files of Django <<VERSION>>, released <<DATE>>.

    To use this file, you will need a working install of PGP or other
    compatible public-key encryption software. You will also need to have
    the Django release manager's public key in your keyring; this key has
    the ID ``XXXXXXXXXXXXXXXX`` and can be imported from the MIT
    keyserver. For example, if using the open-source GNU Privacy Guard
    implementation of PGP:

        gpg --keyserver pgp.mit.edu --recv-key XXXXXXXXXXXXXXXX

    Once the key is imported, verify this file::

        gpg --verify <<THIS FILENAME>>

    Once you have verified this file, you can use normal MD5, SHA1, or SHA256
    checksumming applications to generate the checksums of the Django
    package and compare them to the checksums listed below.

    Release packages:
    =================

    https://www.djangoproject.com/m/releases/<<RELEASE TAR.GZ FILENAME>>
    https://www.djangoproject.com/m/releases/<<RELEASE WHL FILENAME>>

    MD5 checksums:
    ==============

    <<MD5SUM>>  <<RELEASE TAR.GZ FILENAME>>
    <<MD5SUM>>  <<RELEASE WHL FILENAME>>

    SHA1 checksums:
    ===============

    <<SHA1SUM>>  <<RELEASE TAR.GZ FILENAME>>
    <<SHA1SUM>>  <<RELEASE WHL FILENAME>>

    SHA256 checksums:
    =================

    <<SHA256SUM>>  <<RELEASE TAR.GZ FILENAME>>
    <<SHA256SUM>>  <<RELEASE WHL FILENAME>>

#. Sign the checksum file (``gpg --clearsign --digest-algo SHA256
   Django-<version>.checksum.txt``). This generates a signed document,
   ``Django-<version>.checksum.txt.asc`` which you can then verify using ``gpg
   --verify Django-<version>.checksum.txt.asc``.

If you're issuing multiple releases, repeat these steps for each release.

Making the release(s) available to the public
=============================================

Now you're ready to actually put the release out there. To do this:

#. Upload the release package(s) to the djangoproject server, replacing
   A.B. with the appropriate version number, e.g. 1.5 for a 1.5.x release::

        $ scp Django-* djangoproject.com:/home/www/www/media/releases/A.B

#. Upload the checksum file(s)::

        $ scp Django-A.B.C.checksum.txt.asc djangoproject.com:/home/www/www/media/pgp/Django-A.B.C.checksum.txt

#. Test that the release packages install correctly using ``easy_install``
   and ``pip``. Here's one method (which requires `virtualenvwrapper`__)::

        $ RELEASE_VERSION='1.7.2'
        $ MAJOR_VERSION=`echo $RELEASE_VERSION| cut -c 1-3`

        $ mktmpenv
        $ easy_install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django-$RELEASE_VERSION.tar.gz
        $ deactivate
        $ mktmpenv
        $ pip install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django-$RELEASE_VERSION.tar.gz
        $ deactivate
        $ mktmpenv
        $ pip install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django-$RELEASE_VERSION-py2.py3-none-any.whl
        $ deactivate

   This just tests that the tarballs are available (i.e. redirects are up) and
   that they install correctly, but it'll catch silly mistakes.

   __ https://pypi.python.org/pypi/virtualenvwrapper

#. Ask a few people on IRC to verify the checksums by visiting the checksums
   file (e.g. https://www.djangoproject.com/m/pgp/Django-1.5b1.checksum.txt)
   and following the instructions in it. For bonus points, they can also unpack
   the downloaded release tarball and verify that its contents appear to be
   correct (proper version numbers, no stray ``.pyc`` or other undesirable
   files).

#. Upload the release packages to PyPI (for pre-releases, only upload the wheel
   file)::

       $ twine upload -s dist/*

#. Go to the `Add release page in the admin`__, enter the new release number
   exactly as it appears in the name of the tarball (Django-<version>.tar.gz).
   So for example enter "1.5.1" or "1.4c2", etc. If the release is part of
   an LTS branch, mark it so.

   __ https://www.djangoproject.com/admin/releases/release/add/

#. Make the blog post announcing the release live.

#. For a new version release (e.g. 1.5, 1.6), update the default stable version
   of the docs by flipping the ``is_default`` flag to ``True`` on the
   appropriate ``DocumentRelease`` object in the ``docs.djangoproject.com``
   database (this will automatically flip it to ``False`` for all
   others); you can do this using the site's admin.

#. Post the release announcement to the |django-announce|, |django-developers|,
   and |django-users| mailing lists. This should include a link to the
   announcement blog post. If this is a security release, also include
   oss-security@lists.openwall.com.

#. Add a link to the blog post in the topic of the #django IRC channel:
   ``/msg chanserv TOPIC #django new topic goes here``.

Post-release
============

You're almost done! All that's left to do now is:

#. Update the ``VERSION`` tuple in ``django/__init__.py`` again,
   incrementing to whatever the next expected release will be. For
   example, after releasing 1.5.1, update ``VERSION`` to
   ``VERSION = (1, 5, 2, 'alpha', 0)``.

#. Add the release in `Trac's versions list`_ if necessary (and make it the
   default if it's a final release). Not all versions are declared;
   take example on previous releases.

#. If this was a security release, update :doc:`/releases/security` with
   details of the issues addressed.

.. _Trac's versions list: https://code.djangoproject.com/admin/ticket/versions

New stable branch tasks
=======================

There are several items to do in the time following the creation of a new
stable branch (often following an alpha release). Some of these tasks don't
need to be done by the releaser.

#. Create a new ``DocumentRelease`` object in the ``docs.djangoproject.com``
   database for the new version's docs, and update the
   ``docs/fixtures/doc_releases.json`` JSON fixture, so people without access
   to the production DB can still run an up-to-date copy of the docs site.

#. Create a stub release note for the new feature version. Use the stub from
   the previous feature release version or copy the contents from the previous
   feature version and delete most of the contents leaving only the headings.

#. Increase the default PBKDF2 iterations in
   ``django.contrib.auth.hashers.PBKDF2PasswordHasher`` by about 20%
   (pick a round number). Run the tests, and update the 3 failing
   hasher tests with the new values. Make sure this gets noted in the
   release notes (see the 1.8 release notes for an example).

#. Remove features that have reached the end of their deprecation cycle. Each
   removal should be done in a separate commit for clarity. In the commit
   message, add a "refs #XXXX" to the original ticket where the deprecation
   began if possible.

#. Remove ``.. versionadded::``, ``.. versionadded::``, and ``.. deprecated::``
   annotations in the documentation from two releases ago. For example, in
   Django 1.9, notes for 1.7 will be removed.

#. Add the new branch to `Read the Docs
   <https://readthedocs.org/projects/django/>`_. Since the automatically
   generated version names ("stable-A.B.x") differ from the version numbers
   we've used historically in Read the Docs ("A.B.x"), we currently ask Eric
   Holscher to add the version for us. Someday the alias functionality may be
   built-in to the Read the Docs UI.

Notes on setting the VERSION tuple
==================================

Django's version reporting is controlled by the ``VERSION`` tuple in
``django/__init__.py``. This is a five-element tuple, whose elements
are:

#. Major version.
#. Minor version.
#. Micro version.
#. Status -- can be one of "alpha", "beta", "rc" or "final".
#. Series number, for alpha/beta/RC packages which run in sequence
   (allowing, for example, "beta 1", "beta 2", etc.).

For a final release, the status is always "final" and the series
number is always 0. A series number of 0 with an "alpha" status will
be reported as "pre-alpha".

Some examples:

* ``(1, 2, 1, 'final', 0)`` → "1.2.1"

* ``(1, 3, 0, 'alpha', 0)`` → "1.3 pre-alpha"

* ``(1, 3, 0, 'beta', 2)`` → "1.3 beta 2"

---

### 大一小学期 Week 3 Python Exam 2016 Docs Internals Index (`大一小学期/Week_3-Python/exam/2016/docs/internals/index.txt`)

================
Django internals
================

Documentation for people hacking on Django itself. This is the place to go if
you'd like to help improve Django or learn about how Django is managed.

.. toctree::
   :maxdepth: 2

   contributing/index
   mailing-lists
   organization
   team
   roles
   security
   release-process
   deprecation
   git
   howto-release-django

---

### 大一小学期 Week 3 Python Exam 2016 Docs Internals Mailing Lists (`大一小学期/Week_3-Python/exam/2016/docs/internals/mailing-lists.txt`)

=============
Mailing lists
=============

.. Important::

    Please report security issues **only** to
    security@djangoproject.com.  This is a private list only open to
    long-time, highly trusted Django developers, and its archives are
    not public. For further details, please see :doc:`our security
    policies </internals/security>`.

Django has several official mailing lists on Google Groups that are open to
anyone.

.. _django-users-mailing-list:

``django-users``
================

This is the right place if you are looking to ask any question regarding the
installation, usage, or debugging of Django.

.. note::

    If it's the first time you send an email to this list, your email must be
    accepted first so don't worry if :ref:`your message does not appear
    <message-does-not-appear-on-django-users>` instantly.

* `django-users mailing archive`_
* `django-users subscription email address`_
* `django-users posting email`_

.. _django-users mailing archive: https://groups.google.com/d/forum/django-users
.. _django-users subscription email address: mailto:django-users+subscribe@googlegroups.com
.. _django-users posting email: mailto:django-users@googlegroups.com

.. _django-core-mentorship-mailing-list:

``django-core-mentorship``
==========================

The Django Core Mentorship list is intended to provide a welcoming
introductory environment for community members interested in contributing to
the Django Project.

* `django-core-mentorship mailing archive`_
* `django-core-mentorship subscription email address`_
* `django-core-mentorship posting email`_

.. _django-core-mentorship mailing archive: https://groups.google.com/d/forum/django-core-mentorship
.. _django-core-mentorship subscription email address: mailto:django-core-mentorship+subscribe@googlegroups.com
.. _django-core-mentorship posting email: mailto:django-core-mentorship@googlegroups.com

.. _django-developers-mailing-list:

``django-developers``
=====================

The discussion about the development of Django itself takes place here.

.. note::

    Please make use of
    :ref:`django-users mailing list <django-users-mailing-list>` if you want
    to ask for tech support, doing so in this list is inappropriate.

* `django-developers mailing archive`_
* `django-developers subscription email address`_
* `django-developers posting email`_

.. _django-developers mailing archive: https://groups.google.com/d/forum/django-developers
.. _django-developers subscription email address: mailto:django-developers+subscribe@googlegroups.com
.. _django-developers posting email: mailto:django-developers@googlegroups.com

.. _django-i18n-mailing-list:

``django-i18n``
===============

This is the place to discuss the internationalization and localization of
Django's components.

* `django-i18n mailing archive`_
* `django-i18n subscription email address`_
* `django-i18n posting email`_

.. _django-i18n mailing archive: https://groups.google.com/d/forum/django-i18n
.. _django-i18n subscription email address: mailto:django-i18n+subscribe@googlegroups.com
.. _django-i18n posting email: mailto:django-i18n@googlegroups.com

.. _django-announce-mailing-list:

``django-announce``
===================

A (very) low-traffic list for announcing new releases of Django and important
bugfixes.

* `django-announce mailing archive`_
* `django-announce subscription email address`_
* `django-announce posting email`_

.. _django-announce mailing archive: https://groups.google.com/d/forum/django-announce
.. _django-announce subscription email address: mailto:django-announce+subscribe@googlegroups.com
.. _django-announce posting email: mailto:django-announce@googlegroups.com

.. _django-updates-mailing-list:

``django-updates``
==================

All the ticket updates are mailed automatically to this list, which is tracked
by developers and interested community members.

* `django-updates mailing archive`_
* `django-updates subscription email address`_
* `django-updates posting email`_

.. _django-updates mailing archive: https://groups.google.com/d/forum/django-updates
.. _django-updates subscription email address: mailto:django-updates+subscribe@googlegroups.com
.. _django-updates posting email: mailto:django-updates@googlegroups.com

---

### 大一小学期 Week 3 Python Exam 2016 Docs Internals Organization (`大一小学期/Week_3-Python/exam/2016/docs/internals/organization.txt`)

==================================
Organization of the Django Project
==================================

Principles
==========

The Django Project is managed by a team of volunteers pursuing three goals:

- Driving the development of the Django Web Framework,
- Fostering the ecosystem of Django-related software,
- Leading the Django community in accordance with the values described in the
  `Django Code of Conduct`_.

The Django Project isn't a legal entity. The `Django Software Foundation`_, a
non-profit organization, handles financial and legal matters related to the
Django Project. Other than that, the Django Software Foundation lets the
Django Project manage the development of the Django framework, its ecosystem
and its community.

.. _Django Code of Conduct: https://www.djangoproject.com/conduct/
.. _Django Software Foundation: https://www.djangoproject.com/foundation/

The Django core team makes the decisions, nominates its new members, and
elects its technical board. While it holds decision power in theory, it aims
at using it as rarely as possible in practice. Rough consensus should be the
norm and formal voting an exception.

.. _core-team:

Core team
=========

Role
----

The core team is the group of trusted volunteers who manage the Django
Project. They assume many roles required to achieve the project's goals,
especially those that require a high level of trust. They make the decisions
that shape the future of the project.

Core team members are expected to act as role models for the community and
custodians of the project, on behalf of the community and all those who rely
on Django.

They will intervene, where necessary, in online discussions or at official
Django events on the rare occasions that a situation arises that requires
intervention.

They have authority over the Django Project infrastructure, including the
Django Project website itself, the Django GitHub organization and
repositories, the Trac bug tracker, the mailing lists, IRC channels, etc.

Prerogatives
------------

Core team members may participate in formal votes, typically to nominate new
team members and to elect the technical board.

Some contributions don't require commit access. Depending on the reasons why a
contributor joins the team, they may or may not have commit permissions to the
Django code repository.

However, should the need arise, any team member may ask for commit access by
writing to the core team's mailing list. Access will be granted unless the
person withdraws their request or the technical board vetoes the proposal.

Core team members who have commit access are referred to as "committers" or
"core developers".

Other permissions, such as access to the servers, are granted to those who
need them through the same process.

Membership
----------

The core team finds its origins with the :ref:`four people
<original-team-list>` who created Django. It has grown to :ref:`a few dozen
people <core-team-list>` by co-opting volunteers who demonstrate:

- a good grasp of the philosophy of the Django Project
- a solid track record of being constructive and helpful
- significant contributions to the project's goals, in any form
- willingness to dedicate some time to improving Django

As the project matures, contributions go way beyond code. Here's an incomplete
list of areas where contributions may be considered for joining the core team,
in no particular order:

- Working on community management and outreach
- Providing support on the mailing-lists and on IRC
- Triaging tickets
- Writing patches (code, docs, or tests)
- Reviewing patches (code, docs, or tests)
- Participating in design decisions
- Providing expertise in a particular domain (security, i18n, etc.)
- Managing the continuous integration infrastructure
- Managing the servers (website, tracker, documentation, etc.)
- Maintaining related projects (djangoproject.com site, ex-contrib apps, etc.)
- Creating visual designs

Very few areas are reserved to core team members:

- Reviewing security reports
- Merging patches (code, docs, or tests)
- Packaging releases

Core team membership acknowledges sustained and valuable efforts that align
well with the philosophy and the goals of the Django Project.

It is granted by a four fifths majority of votes cast in a core team vote and
no veto by the technical board.

Core team members are always looking for promising contributors, teaching them
how the project is managed, and submitting their names to the core team's vote
when they're ready. If you would like to join the core team, you can contact a
core team member privately or ask for guidance on the :ref:`Django Core
Mentorship mailing-list <django-core-mentorship-mailing-list>`.

There's no time limit on core team membership. However, in order to provide
the general public with a reasonable idea of how many people maintain Django,
core team members who have stopped contributing are encouraged to declare
themselves as "past team members". Those who haven't made any non-trivial
contribution in two years may be asked to move themselves to this category,
and moved there if they don't respond. Past team members lose their privileges
such as voting rights and commit access.

.. _technical-board:

Technical board
===============

Role
----

The technical board is a group of experienced and active committers who steer
technical choices. Their main concern is to maintain the quality and stability
of the Django Web Framework.

Prerogatives
------------

The technical board holds two prerogatives:

- Making major technical decisions when no consensus is found otherwise. This
  happens on the |django-developers| mailing-list.
- Veto a grant of commit access or remove commit access. This happens on the
  django-core mailing-list.

In both cases, the technical board is a last resort. In these matters, it
fulfills a similar function to the former Benevolent Dictators For Life.

When the board wants to exercise one of these prerogatives, it must hold a
private, simple majority vote on the resolution. The quorum is the full
committee — each member must cast a vote or abstain explicitly. Then the board
communicates the result, and if possible the reasons, on the appropriate
mailing-list. There's no appeal for such decisions.

In addition, at its discretion, the technical board may act in an advisory
capacity on non-technical decisions.

Membership
----------

The technical board is an elected group of five committers. They're expected
to be experienced but there's no formal seniority requirement. Its current
composition is published :ref:`here <technical-board-list>`.

A new board is elected after each feature release of Django. The election
process is managed by a returns officer nominated by the outgoing technical
board. The election process works as follows:

1. Candidates advertise their application for the technical board to the team.

   They must be committers already. There's no term limit for technical board
   members.

2. Each team member can vote for zero to five people among the candidates.
   Candidates are ranked by the total number of votes they received.

   In case of a tie, the person who joined the core team earlier wins.

Both the application and the voting period last between one and two weeks, at
the outgoing board's discretion.

Changing the organization
=========================

Changes to this document require a four fifths majority of votes cast in a
core team vote and no veto by the technical board.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Internals Release Process (`大一小学期/Week_3-Python/exam/2016/docs/internals/release-process.txt`)

========================
Django's release process
========================

.. _official-releases:

Official releases
=================

Since version 1.0, Django's release numbering works as follows:

* Versions are numbered in the form ``A.B`` or ``A.B.C``.

* ``A.B`` is the *feature release* version number. Each version will be mostly
  backwards compatible with the previous release. Exceptions to this rule will
  be listed in the release notes.

* ``C`` is the *patch release* version number, which is incremented for bugfix
  and security releases. These releases will be 100% backwards-compatible with
  the previous patch release. The only exception is when a security or data
  loss issue can't be fixed without breaking backwards-compatibility. If this
  happens, the release notes will provide detailed upgrade instructions.

* Before a new feature release, we'll make alpha, beta, and release candidate
  releases. These are of the form ``A.B alpha/beta/rc N``, which means the
  ``Nth`` alpha/beta/release candidate of version ``A.B``.

In git, each Django release will have a tag indicating its version number,
signed with the Django release key. Additionally, each release series has its
own branch, called ``stable/A.B.x``, and bugfix/security releases will be
issued from those branches.

For more information about how the Django project issues new releases for
security purposes, please see :doc:`our security policies <security>`.

.. glossary::

  Feature release
    Feature releases (A.B, A.B+1, etc.) will happen roughly every eight months
    -- see `release process`_ for details. These releases will contain new
    features, improvements to existing features, and such.

  Patch release
    Patch releases (A.B.C, A.B.C+1, etc.) will be issued as needed, to fix
    bugs and/or security issues.

    These releases will be 100% compatible with the associated feature release,
    unless this is impossible for security reasons or to prevent data loss.
    So the answer to "should I upgrade to the latest patch release?" will always
    be "yes."

  Long-term support release
    Certain feature releases will be designated as long-term support (LTS)
    releases. These releases will get security and data loss fixes applied for
    a guaranteed period of time, typically three years.

    See `the download page`_ for the releases that have been designated for
    long-term support.

    .. _the download page: https://www.djangoproject.com/download/

Release cadence
===============

Starting with Django 2.0, version numbers will use a loose form of `semantic
versioning <http://semver.org/>`_ such that each version following an LTS will
bump to the next "dot zero" version. For example: 2.0, 2.1, 2.2 (LTS), 3.0,
3.1, 3.2 (LTS), etc.

SemVer makes it easier to see at a glance how compatible releases are with each
other. It also helps to anticipate when compatibility shims will be removed.
It's not a pure form of SemVer as each feature release will continue to have a
few documented backwards incompatibilities where a deprecation path isn't
possible or not worth the cost. Also, deprecations started in an LTS release
(X.2) will be dropped in a non-dot-zero release (Y.1) to accommodate our policy
of keeping deprecation shims for at least two feature releases. Read on to the
next section for an example.

.. _internal-release-deprecation-policy:

Deprecation policy
==================

A feature release may deprecate certain features from previous releases. If a
feature is deprecated in feature release A.x, it will continue to work in all
A.x versions (for all versions of x) but raise warnings. Deprecated features
will be removed in the B.0 release, or B.1 for features deprecated in the last
A.x feature release to ensure deprecations are done over at least 2 feature
releases.

So, for example, if we decided to start the deprecation of a function in
Django 4.2:

* Django 4.2 will contain a backwards-compatible replica of the function which
  will raise a ``RemovedInDjango51Warning``.

* Django 5.0 (the version that follows 4.2) will still contain the
  backwards-compatible replica.

* Django 5.1 will remove the feature outright.

The warnings are silent by default. You can turn on display of these warnings
with the ``python -Wd`` option.

A more generic example:

* X.0
* X.1
* X.2 LTS
* Y.0: Drop deprecation shims added in X.0 and X.1.
* Y.1: Drop deprecation shims added in X.2.
* Y.2 LTS: No deprecation shims dropped (while Y.0 is no longer supported,
  third-party apps need to maintain compatibility back to X.2 LTS to ease
  LTS to LTS upgrades).
* Z.0: Drop deprecation shims added in Y.0 and Y.1.

.. _backwards-compatibility-policy:

Supported versions
==================

At any moment in time, Django's developer team will support a set of releases to
varying levels. See `the supported versions section
<https://www.djangoproject.com/download/#supported-versions>`_ of the download
page for the current state of support for each version.

* The current development master will get new features and bug fixes
  requiring non-trivial refactoring.

* Patches applied to the master branch must also be applied to the last feature
  release branch, to be released in the next patch release of that feature
  series, when they fix critical problems:

  * Security issues.

  * Data loss bugs.

  * Crashing bugs.

  * Major functionality bugs in newly-introduced features.

  * Regressions from older versions of Django.

  The rule of thumb is that fixes will be backported to the last feature
  release for bugs that would have prevented a release in the first place
  (release blockers).

* Security fixes and data loss bugs will be applied to the current master, the
  last two feature release branches, and any other supported long-term
  support release branches.

* Documentation fixes generally will be more freely backported to the last
  release branch. That's because it's highly advantageous to have the docs for
  the last release be up-to-date and correct, and the risk of introducing
  regressions is much less of a concern.

As a concrete example, consider a moment in time halfway between the release of
Django 5.1 and 5.2. At this point in time:

* Features will be added to development master, to be released as Django 5.2.

* Critical bug fixes will be applied to the ``stable/5.1.x`` branch, and
  released as 5.1.1, 5.1.2, etc.

* Security fixes and bug fixes for data loss issues will be applied to
  ``master`` and to the ``stable/5.1.x``, ``stable/5.0.x``, and
  ``stable/4.2.x`` (LTS) branches. They will trigger the release of ``5.1.1``,
  ``5.0.5``, ``4.2.8``, etc.

* Documentation fixes will be applied to master, and, if easily backported, to
  the latest stable branch, ``5.1.x``.

.. _release-process:

Release process
===============

Django uses a time-based release schedule, with feature releases every eight
months or so.

After each feature release, the release manager will announce a timeline for
the next feature release.

Release cycle
-------------

Each release cycle consists of three parts:

Phase one: feature proposal
~~~~~~~~~~~~~~~~~~~~~~~~~~~

The first phase of the release process will include figuring out what major
features to include in the next version. This should include a good deal of
preliminary work on those features -- working code trumps grand design.

Major features for an upcoming release will be added to the wiki roadmap page,
e.g. https://code.djangoproject.com/wiki/Version1.9Roadmap.

Phase two: development
~~~~~~~~~~~~~~~~~~~~~~

The second part of the release schedule is the "heads-down" working period.
Using the roadmap produced at the end of phase one, we'll all work very hard to
get everything on it done.

At the end of phase two, any unfinished features will be postponed until the
next release.

Phase two will culminate with an alpha release. At this point, the
``stable/A.B.x`` branch will be forked from ``master``.

Phase three: bugfixes
~~~~~~~~~~~~~~~~~~~~~

The last part of a release cycle is spent fixing bugs -- no new features will
be accepted during this time. We'll try to release a beta release one month
after the alpha and a release candidate one month after the beta.

The release candidate marks the string freeze, and it happens at least two
weeks before the final release. After this point, new translatable strings
must not be added.

During this phase, committers will be more and more conservative with
backports, to avoid introducing regressions. After the release candidate, only
release blockers and documentation fixes should be backported.

In parallel to this phase, ``master`` can receive new features, to be released
in the ``A.B+1`` cycle.

Bug-fix releases
----------------

After a feature release (e.g. A.B), the previous release will go into bugfix
mode.

The branch for the previous feature release (e.g. ``stable/A.B-1.x``) will
include bugfixes. Critical bugs fixed on master must *also* be fixed on the
bugfix branch; this means that commits need to cleanly separate bug fixes from
feature additions. The developer who commits a fix to master will be
responsible for also applying the fix to the current bugfix branch.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Internals Roles (`大一小学期/Week_3-Python/exam/2016/docs/internals/roles.txt`)

=====
Roles
=====

.. _technical-board-list:

Technical board
===============

The technical board for the 1.10 release cycle is:

* James Bennett
* Andrew Godwin
* Russell Keith-Magee
* Carl Meyer
* Marc Tamlyn

.. _committers:

Committers
==========

Most :ref:`core team <core-team>` members have commit access. They're called
"committers" or "core developers".

Being part of the core team is a pre-requisite for having commit access.

.. _security-team-list:

Security team
=============

The security team is responsible for :doc:`Django's security policies
</internals/security>`. It handles private reports of security issues.

The current security team members are:

- Florian Apolloner
- James Bennett
- Jeremy Dunck
- Adrian Holovaty
- Jacob Kaplan-Moss
- Russell Keith-Magee
- Paul McMillan
- Carl Meyer
- Donald Stufft

.. _releasers-list:

Releasers
=========

Releasers take care of :doc:`building Django releases
</internals/howto-release-django>`.

The current releasers are:

- James Bennett
- Jacob Kaplan-Moss
- Tim Graham

Ops team
========

The ops team maintains Django's infrastructure like the Django Project server,
Trac instance, and continuous integration infrastructure.

- Florian Apolloner
- Aymeric Augustin
- Tim Graham
- Jannis Leidel

---

### 大一小学期 Week 3 Python Exam 2016 Docs Internals Security (`大一小学期/Week_3-Python/exam/2016/docs/internals/security.txt`)

==========================
Django's security policies
==========================

Django's development team is strongly committed to responsible
reporting and disclosure of security-related issues. As such, we've
adopted and follow a set of policies which conform to that ideal and
are geared toward allowing us to deliver timely security updates to
the official distribution of Django, as well as to third-party
distributions.

.. _reporting-security-issues:

Reporting security issues
=========================

**Short version: please report security issues by emailing
security@djangoproject.com**.

Most normal bugs in Django are reported to `our public Trac instance`_, but
due to the sensitive nature of security issues, we ask that they **not** be
publicly reported in this fashion.

Instead, if you believe you've found something in Django which has security
implications, please send a description of the issue via email to
``security@djangoproject.com``. Mail sent to that address reaches a
:ref:`subset of the core team <security-team-list>`, who can forward security
issues into the private committers' mailing list for broader discussion if
needed.

Once you've submitted an issue via email, you should receive an acknowledgment
from a member of the security team within 48 hours, and depending on the
action to be taken, you may receive further followup emails.

.. note::

    If you want to send an encrypted email (*optional*), the public key ID for
    ``security@djangoproject.com`` is ``0xfcb84b8d1d17f80b``, and this public
    key is available from most commonly-used keyservers.

.. _our public Trac instance: https://code.djangoproject.com/query

.. _security-support:

Supported versions
==================

At any given time, the Django team provides official security support
for several versions of Django:

* The `master development branch`_, hosted on GitHub, which will
  become the next release of Django, receives security support.

* The two most recent Django release series receive security
  support. For example, during the development cycle leading to the
  release of Django 1.5, support will be provided for Django 1.4 and
  Django 1.3. Upon the release of Django 1.5, Django 1.3's security
  support will end.

* :term:`Long-term support release`\s will receive security updates for a
  specified period.

When new releases are issued for security reasons, the accompanying
notice will include a list of affected versions. This list is
comprised solely of *supported* versions of Django: older versions may
also be affected, but we do not investigate to determine that, and
will not issue patches or new releases for those versions.

.. _master development branch: https://github.com/django/django/

.. _security-disclosure:

How Django discloses security issues
====================================

Our process for taking a security issue from private discussion to
public disclosure involves multiple steps.

Approximately one week before full public disclosure, we will send
advance notification of the issue to a list of people and
organizations, primarily composed of operating-system vendors and
other distributors of Django. This notification will consist of an
email message, signed with the Django release key, containing:

* A full description of the issue and the affected versions of Django.

* The steps we will be taking to remedy the issue.

* The patch(es), if any, that will be applied to Django.

* The date on which the Django team will apply these patches, issue
  new releases and publicly disclose the issue.

Simultaneously, the reporter of the issue will receive notification of
the date on which we plan to take the issue public.

On the day of disclosure, we will take the following steps:

1. Apply the relevant patch(es) to Django's codebase. The commit
   messages for these patches will indicate that they are for security
   issues, but will not describe the issue in any detail; instead,
   they will warn of upcoming disclosure.

2. Issue the relevant release(s), by placing new packages on `the
   Python Package Index`_ and on the Django website, and tagging the
   new release(s) in Django's git repository.

3. Post a public entry on `the official Django development blog`_,
   describing the issue and its resolution in detail, pointing to the
   relevant patches and new releases, and crediting the reporter of
   the issue (if the reporter wishes to be publicly identified).

4. Post a notice to the |django-announce| and oss-security@lists.openwall.com
   mailing lists that links to the blog post.

.. _the Python Package Index: https://pypi.python.org/pypi
.. _the official Django development blog: https://www.djangoproject.com/weblog/

If a reported issue is believed to be particularly time-sensitive --
due to a known exploit in the wild, for example -- the time between
advance notification and public disclosure may be shortened
considerably.

Additionally, if we have reason to believe that an issue reported to
us affects other frameworks or tools in the Python/web ecosystem, we
may privately contact and discuss those issues with the appropriate
maintainers, and coordinate our own disclosure and resolution with
theirs.

The Django team also maintains an :doc:`archive of security issues
disclosed in Django</releases/security>`.


.. _security-notifications:

Who receives advance notification
=================================

The full list of people and organizations who receive advance
notification of security issues is not and will not be made public.

We also aim to keep this list as small as effectively possible, in
order to better manage the flow of confidential information prior to
disclosure. As such, our notification list is *not* simply a list of
users of Django, and merely being a user of Django is not sufficient
reason to be placed on the notification list.

In broad terms, recipients of security notifications fall into three
groups:

1. Operating-system vendors and other distributors of Django who
   provide a suitably-generic (i.e., *not* an individual's personal
   email address) contact address for reporting issues with their
   Django package, or for general security reporting. In either case,
   such addresses **must not** forward to public mailing lists or bug
   trackers. Addresses which forward to the private email of an
   individual maintainer or security-response contact are acceptable,
   although private security trackers or security-response groups are
   strongly preferred.

2. On a case-by-case basis, individual package maintainers who have
   demonstrated a commitment to responding to and responsibly acting
   on these notifications.

3. On a case-by-case basis, other entities who, in the judgment of the
   Django development team, need to be made aware of a pending
   security issue. Typically, membership in this group will consist of
   some of the largest and/or most likely to be severely impacted
   known users or distributors of Django, and will require a
   demonstrated ability to responsibly receive, keep confidential and
   act on these notifications.

Requesting notifications
========================

If you believe that you, or an organization you are authorized to
represent, fall into one of the groups listed above, you can ask to be
added to Django's notification list by emailing
``security@djangoproject.com``. Please use the subject line "Security
notification request".

Your request **must** include the following information:

* Your full, real name and the name of the organization you represent,
  if applicable, as well as your role within that organization.

* A detailed explanation of how you or your organization fit at least
  one set of criteria listed above.

* A detailed explanation of why you are requesting security
  notifications. Again, please keep in mind that this is *not* simply
  a list for users of Django, and the overwhelming majority of users
  of Django should not request notifications and will not be added to
  our notification list if they do.

* The email address you would like to have added to our notification
  list.

* An explanation of who will be receiving/reviewing mail sent to that
  address, as well as information regarding any automated actions that
  will be taken (i.e., filing of a confidential issue in a bug
  tracker).

* For individuals, the ID of a public key associated with your address
  which can be used to verify email received from you and encrypt
  email sent to you, as needed.

Once submitted, your request will be considered by the Django
development team; you will receive a reply notifying you of the result
of your request within 30 days.

Please also bear in mind that for any individual or organization,
receiving security notifications is a privilege granted at the sole
discretion of the Django development team, and that this privilege can
be revoked at any time, with or without explanation.

If you are added to the notification list, security-related emails
will be sent to you by Django's release team, and all notification
emails will be signed with a key authorized to issue Django
releases. The list of authorized keys is in `the Django releasers
file`_.

.. _the Django releasers file: https://www.djangoproject.com/m/pgp/django-releasers.txt

---

### 大一小学期 Week 3 Python Exam 2016 Docs Internals Team (`大一小学期/Week_3-Python/exam/2016/docs/internals/team.txt`)

===========
Django team
===========

.. _original-team-list:

The original team
=================

Django originally started at World Online, the Web department of the `Lawrence
Journal-World`_ of Lawrence, Kansas, USA.

`Adrian Holovaty`_
    Adrian is a Web developer with a background in journalism. He's known in
    journalism circles as one of the pioneers of "journalism via computer
    programming", and in technical circles as "the guy who invented Django."

    He was lead developer at World Online for 2.5 years, during which time
    Django was developed and implemented on World Online's sites. He was the
    leader and founder of EveryBlock_, a "news feed for your block." He now
    develops Soundslice_.

    Adrian lives in Chicago, USA.

`Simon Willison`_
    Simon is a well-respected Web developer from England. He had a one-year
    internship at World Online, during which time he and Adrian developed Django
    from scratch. The most enthusiastic Brit you'll ever meet, he's passionate
    about best practices in Web development and maintains a well-read
    `web-development blog`_.

    Simon lives in Brighton, England.

`Jacob Kaplan-Moss`_
    Jacob is Director of Platform Security at Heroku_. He worked at World
    Online for four years, where he helped open source Django and found
    the Django Software Foundation. Jacob lives on a hobby farm outside of
    Lawrence where he spends his weekends playing with dirt and power tools.

`Wilson Miner`_
    Wilson's design-fu is what makes Django look so nice. He created the design
    that was used for nearly the first ten years on the Django Project website,
    as well as the current design for Django's acclaimed admin interface. Wilson
    was the designer for EveryBlock and Rdio_. He now designs for Facebook.

    Wilson lives in San Francisco, USA.

.. _lawrence journal-world: http://ljworld.com/
.. _adrian holovaty: http://holovaty.com/
.. _everyblock: https://everyblock.com/
.. _soundslice: https://www.soundslice.com/
.. _simon willison: http://simonwillison.net/
.. _web-development blog: `simon willison`_
.. _jacob kaplan-moss: https://jacobian.org/
.. _revolution systems: http://revsys.com/
.. _wilson miner: http://wilsonminer.com/
.. _heroku: https://heroku.com/
.. _Rdio: http://rdio.com

.. _core-team-list:

The current team
================

These are the folks who have a long history of contributions, a solid track
record of being helpful on the mailing lists, and a proven desire to dedicate
serious time to Django. In return, they've been invited to join the :ref:`core
team <core-team>`.

`Luke Plant`_
    At University Luke studied physics and Materials Science and also
    met `Michael Meeks`_ who introduced him to Linux and Open Source,
    re-igniting an interest in programming.  Since then he has
    contributed to a number of Open Source projects and worked
    professionally as a developer.

    Luke has contributed many excellent improvements to Django,
    including database-level improvements, the CSRF middleware and
    many unit tests.

    Luke currently works for a church in Bradford, UK, and part-time
    as a freelance developer.

    .. _luke plant: http://lukeplant.me.uk/
    .. _michael meeks: https://en.wikipedia.org/wiki/Michael_Meeks_(software)

`Russell Keith-Magee`_
    Russell studied physics as an undergraduate, and studied neural networks for
    his PhD. His first job was with a startup in the defense industry developing
    simulation frameworks. Over time, mostly through work with Django, he's
    become more involved in Web development.

    Russell has helped with several major aspects of Django, including a
    couple major internal refactorings, creation of the test system, and more.

    Russell lives in the most isolated capital city in the world — Perth,
    Australia.

    .. _russell keith-magee: http://cecinestpasun.com/

`James Bennett`_
    James has been one of Django's release managers, and also
    contributes to the documentation and provide the occasional
    bugfix.

    James came to Web development from philosophy when he discovered
    that programmers get to argue just as much while collecting much
    better pay. He lives in San Mateo, California and previously
    worked at World Online and Mozilla; currently, he's part of the
    Web engineering team at `Clover`_.

    He `keeps a blog`_, and enjoys fine port and talking to his car.

    .. _james bennett: http://b-list.org/
    .. _Clover: https://www.cloverhealth.com/
    .. _keeps a blog: `james bennett`_

Justin Bronn
    Justin Bronn is a computer scientist and attorney specializing
    in legal topics related to intellectual property and spatial law.

    In 2007, Justin began developing ``django.contrib.gis`` in a branch,
    a.k.a. GeoDjango_, which was merged in time for Django 1.0.  While
    implementing GeoDjango, Justin obtained a deep knowledge of Django's
    internals including the ORM, the admin, and Oracle support.

    Justin lives in Houston, TX.

    .. _GeoDjango: http://geodjango.org/

Karen Tracey
    Karen has a background in distributed operating systems (graduate school),
    communications software (industry) and crossword puzzle construction
    (freelance).  The last of these brought her to Django, in late 2006, when
    she set out to put a Web front-end on her crossword puzzle database.
    That done, she stuck around in the community answering questions, debugging
    problems, etc. -- because coding puzzles are as much fun as word puzzles.

    Karen lives in Apex, NC, USA.

`Jannis Leidel`_
    Jannis graduated in media design from `Bauhaus-University Weimar`_,
    is the author of a number of pluggable Django apps and likes to
    contribute to Open Source projects like virtualenv_ and pip_.

    He has worked on Django's auth, admin and staticfiles apps as well as
    the form, core, internationalization and test systems. He currently works
    at Mozilla_.

    Jannis lives in Berlin, Germany.

    .. _Jannis Leidel: https://jezdez.com/
    .. _Bauhaus-University Weimar: http://www.uni-weimar.de/
    .. _virtualenv: http://www.virtualenv.org/
    .. _pip: https://pip.pypa.io/
    .. _Mozilla: https://www.mozilla.org/

`Andrew Godwin`_
    Andrew is a freelance Python developer and tinkerer, and has been
    developing against Django since 2007. He graduated from Oxford University
    with a degree in Computer Science, and has become most well known
    in the Django community for his work on South, the schema migrations
    library.

    Andrew lives in San Francisco, CA, USA.

    .. _Andrew Godwin: https://www.aeracode.org/

`Carl Meyer`_
    Carl has been a Django user since 2007 (long enough to remember
    queryset-refactor, but not magic-removal), and builds web apps at OddBird_.
    He became a Django contributor by accident, because fixing bugs is more
    interesting than working around them.

    Carl lives in Rapid City, SD, USA.

    .. _Carl Meyer: http://www.oddbird.net/
    .. _OddBird: http://www.oddbird.net/

Ramiro Morales
    Ramiro has been reading Django source code and submitting patches since
    mid-2006 after researching for a Python Web tool with matching awesomeness
    and being pointed to it by an old ninja.

    A software developer in the electronic transactions industry, he is a
    living proof of the fact that anyone with enough enthusiasm can contribute
    to Django, learning a lot and having fun in the process.

    Ramiro lives in Córdoba, Argentina.

`Chris Beaven`_
    Chris has been submitting patches and suggesting crazy ideas for Django
    since early 2006. An advocate for community involvement and a long-term
    triager, he is still often found answering questions in the #django IRC
    channel.

    Chris lives in Napier, New Zealand (adding to the pool of Oceanic core
    developers). He works remotely as a developer for `Lincoln Loop`_.

    .. _Chris Beaven: http://smileychris.com/
    .. _Lincoln Loop: https://lincolnloop.com/

Honza Král
    Honza first discovered Django in 2006 and started using it right away,
    first for school and personal projects and later in his full-time job. He
    contributed various patches and fixes mostly to the newforms library,
    newforms admin and, through participation in the Google Summer of Code
    project, assisted in creating the :ref:`model validation
    <validating-objects>` functionality.

    He is currently working for `Whiskey Media`_ in San Francisco developing
    awesome sites running on pure Django.

    .. _Whiskey Media: http://www.whiskeymedia.com/

Tim Graham
    When exploring Web frameworks for an independent study project in the fall
    of 2008, Tim discovered Django and was lured to it by the documentation.
    He enjoys contributing to the docs because they're awesome.

    Tim works as a software engineer and lives in Philadelphia, PA, USA.

Paul McMillan
    Paul found Django in 2008 while looking for a more
    structured approach to web programming. He stuck around after
    figuring out that the developers of Django had already invented
    many of the wheels he needed. His passion for breaking (and then
    fixing) things led to his current role working to maintain and
    improve the security of Django.

`Julien Phalip`_
    Julien has a background in software engineering and human-computer
    interaction. As a Web developer, he enjoys tinkering with the backend as
    much as designing and coding user interfaces. Julien discovered Django in
    2007 while doing his PhD in Computing Sciences. Since then he has
    contributed patches to various components of the framework, in particular
    the admin. Julien was a co-founder of the `Interaction Consortium`_. He
    now works at Odopod_, a digital agency based in San Francisco, CA, USA.

    .. _Julien Phalip: http://julienphalip.com
    .. _Interaction Consortium: http://interaction.net.au
    .. _Odopod: http://odopod.com

`Aymeric Augustin`_
    Aymeric is an engineer with a background in mathematics and computer
    science. He chose Django because he believes that software should be simple,
    explicit and tested. His perfectionist tendencies quickly led him to triage
    tickets and contribute patches.

    Aymeric has a pragmatic approach to software engineering, can't live without
    a continuous integration server, and likes proving that Django is a good
    choice for enterprise software.

    .. _Aymeric Augustin: https://myks.org/

`Claude Paroz`_
    Claude is a former teacher who fell in love with free software at the
    beginning of the 21st century. He's now working as freelancer in Web
    development in his native Switzerland. He has found in Django a perfect
    match for his needs of a stable, clean, documented and well-maintained Web
    framework.

    He's also helping the GNOME Translation Project as maintainer of the
    Django-based `l10n.gnome.org`_.

    .. _Claude Paroz: http://www.2xlibre.net
    .. _l10n.gnome.org: https://l10n.gnome.org

Anssi Kääriäinen
    Anssi works as a developer at Finnish National Institute for Health and
    Welfare. He is also a computer science student at Aalto University. In his
    work he uses Django for developing internal business applications and sees
    Django as a great match for that use case.

    Anssi is interested in developing the object relational mapper (ORM) and
    all related features. He's also a fan of benchmarking and he tries keep
    Django as fast as possible.

Florian Apolloner
    Florian is currently studying Physics at the `Graz University of Technology`_.
    Soon after he started using Django he joined the `Ubuntuusers webteam`_ to
    work on *Inyoka*, the software powering the whole Ubuntuusers site.

    For the time being he lives in Graz, Austria (not Australia ;)).

    .. _Graz University of Technology: http://tugraz.at/
    .. _Ubuntuusers webteam: https://wiki.ubuntuusers.de/ubuntuusers/Webteam

Jeremy Dunck
    Jeremy was rescued from corporate IT drudgery by Free Software and, in part,
    Django.  Many of Jeremy's interests center around access to information.

    Jeremy was the lead developer of Pegasus News, one of the first uses of
    Django outside World Online, and has since joined Votizen, a startup intent
    on reducing the influence of money in politics.

    He serves as DSF Secretary, organizes and helps organize sprints, cares
    about the health and equity of the Django community.  He has gone an
    embarrassingly long time without a working blog.

    Jeremy lives in Mountain View, CA, USA.

`Bryan Veloso`_
    Bryan found Django 0.96 through a fellow designer who was evangelizing
    its use. It was his first foray outside of the land that was PHP-based
    templating. Although he has only ever used Django for personal projects,
    it is the very reason he considers himself a designer/developer
    hybrid and is working to further design within the Django community.

    Bryan works as a designer at GitHub by day, and masquerades as a `vlogger`_
    and `shoutcaster`_ in the after-hours. Bryan lives in Los Angeles, CA, USA.

    .. _bryan veloso: http://avalonstar.com/
    .. _vlogger: https://youtube.com/bryanveloso/
    .. _shoutcaster: http://twitch.tv/vlogalonstar/

`Simon Charette`_
    Simon is a mathematics student who discovered Django while searching for a
    replacement framework to an in-house PHP entity. Since that faithful day
    Django has been a big part of his life. So far, he's been involved in some
    ORM and forms API fixes.

    Apart from contributing to multiple open source projects he spends most of
    his spare-time playing `Ultimate Frisbee`_ and working part-time
    at this awesome place called `Reptiletech`_.

    Simon lives in Montréal, Québec, Canada.

    .. _Simon Charette: https://github.com/charettes
    .. _Ultimate Frisbee: http://www.montrealultimate.ca
    .. _Reptiletech: https://www.reptiletech.com

Donald Stufft
    Donald found Python and Django in 2007 while trying to find a language,
    and web framework that he really enjoyed using after many years of PHP. He
    fell in love with the beauty of Python and the way Django made tasks simple
    and easy. His contributions to Django focus primarily on ensuring that it
    is and remains a secure web framework.

    Donald currently works at `Nebula Inc`_ as a Software Engineer for their
    security team and lives in the Greater Philadelphia Area.

    .. _Nebula Inc: https://www.nebula.com/

Marc Tamlyn
    Marc started life on the web using Django 1.2 back in 2010, and has never
    looked back. He was involved with rewriting the class-based view
    documentation at DjangoCon EU 2012, and also helped to develop `CCBV`_, an
    additional class-based view reference tool.

    Marc is currently a full-time parent, part-time developer, and lives in
    Oxford, UK.

    .. _CCBV: https://ccbv.co.uk/

Shai Berger
    Shai started working with Python back in 1998, and with Django just
    before 1.0. He is a Free Software enthusiast, but life happens, and
    he was driven by consulting gigs to contribute to the Oracle and
    SQL Server backends of South, and then the Oracle backend of Django
    itself. Finally, he joined core to help maintain the Oracle backend.

    Shai works for `Platonix`_, a small consulting company he started
    with a few friends in 1996, and lives near Tel Aviv, Israel.

    .. _Platonix: http://tech.platonix.com

Baptiste Mispelon
    Baptiste discovered Django around the 1.2 version and promptly switched away
    from his homegrown PHP framework. He started getting more involved in the
    project after attending DjangoCon EU 2012, mostly by triaging tickets and
    submitting small patches.

    Baptiste currently lives in Budapest, Hungary and works for `M2BPO`_,
    a small French company providing services to architects.

    .. _M2BPO: https://www.m2bpo.fr

Daniele Procida
    Daniele unexpectedly became a Django developer on 29th April 2009. Since
    then he has relied daily on Django's documentation, which has been a
    constant companion to him. More recently he has been able to contribute
    back to the project by helping improve the documentation itself.

    He is the author of `Arkestra`_ and `Don't be afraid to commit`_. He lives
    in Cardiff, Wales, and works for `Divio`_.

    .. _Divio: https://divio.ch/
    .. _Arkestra: http://arkestra-project.org/
    .. _Don\'t be afraid to commit: https://dont-be-afraid-to-commit.readthedocs.io

`Erik Romijn`_
    Erik started using Django in the days of 1.2. His largest contribution to Django was
    ``GenericIPAddressField``, and he has worked on all sorts of patches since.
    While developing with Django, he always keeps a little list of even the slightest
    Django frustrations, to tackle them at a later time and prevent other developers
    from having to deal with the same issues.

    Erik is an independent app maker, mostly developing web and mobile apps, as
    `Solid Links`_. He also enjoys helping ordinary developers to build safer web apps,
    for which Django is already a great start, and developed `Erik's Pony Checkup`_ with
    that goal in mind. Erik lives in Amsterdam, The Netherlands.

    .. _Erik Romijn: http://erik.io/
    .. _Solid Links: https://solidlinks.nl/
    .. _Erik's Pony Checkup: https://ponycheckup.com/

`Loïc Bistuer`_
    Loïc studied telecommunications engineering and works as an independent
    software developer and consultant.

    He discovered Django in 2008 shortly before the 1.0 release and has been
    hooked ever since. He contributes mostly to Django's ORM and Form
    components. His main contributions include advanced query prefetching,
    streamlining QuerySet and Manager to improve query reusability, and a
    significant refactor of forms error handling.

    Loïc is originally from the South of France and currently lives in
    Bangkok, Thailand.

    .. _Loïc Bistuer: https://github.com/loic

`Michael Manfre`_
    Michael started running Django on Windows against a Microsoft SQL Server
    (MSSQL) database in 2008. He quickly became the maintainer of the
    django-mssql 3rd party database backend. Much of his involvement with
    Django relates to the ORM, the private 3rd party database API, and using
    Django on Windows.

    Michael lives in Cary, NC, USA.

    .. _Michael Manfre: http://manfre.net

`Collin Anderson`_
    Collin found Django in November 2006. He was in awe of the admin and ORM
    and was amazed that the documentation was teaching him best web practices
    like redirecting after a successful POST request. Why had he never learned
    this before? No one knows to this day.

    He enjoys helping people on the |django-users| mailing list and making
    Django simple and easy for newcomers.

    Collin lives in South Bend, IN, USA where he uses Django to `increase
    unity`_.

    .. _Collin Anderson: https://github.com/collinanderson
    .. _increase unity: http://onetencommunications.com/about/

`Tom Christie`_
    Tom has background in speech recognition, networking, and web development.
    He has a particular interest in Web API design and is the original author
    of `Django REST framework`_.

    Tom lives in the seaside city of Brighton, UK.

    .. _Tom Christie: https://twitter.com/_tomchristie
    .. _Django REST framework: http://django-rest-framework.org

`Curtis Maloney`_
    Curtis is a self-taught programmer from Melbourne, Australia, who eschews
    specialization.  Upon finding Django when it was first open sourced, he
    realized it was possible to enjoy web development.

    He spends a lot of time helping people on the #django IRC channel, and has
    authored and released a number of `smaller django apps`_.

    .. _Curtis Maloney: http://musings.tinbrain.net/blog/
    .. _smaller django apps: https://github.com/funkybob/

`Markus Holtermann`_
    Markus is a senior backend developer at `LaterPay`_ in Munich. He studied
    Computer Science at the `Technical University of Berlin`_. He started
    working with Django in 2010 when he joined the `ubuntuusers.de`_ web team
    to work on *Inyoka*. Markus made his first contribution to the Django
    project during DjangoCon Europe 2013 in Warsaw. He was the web team leader
    for the `EuroPython 2014 website`_ and started regular contributions to
    Django after that.

    Markus lives in Berlin, Germany.

    .. _Markus Holtermann: https://github.com/MarkusH
    .. _LaterPay: https://www.laterpay.net/
    .. _Technical University of Berlin: http://www.tu-berlin.de/
    .. _ubuntuusers.de: https://ubuntuusers.de/
    .. _EuroPython 2014 website: https://ep2014.europython.eu/

`Josh Smeaton`_
    Josh was given the opportunity to work on a new Django app around version
    1.1 after working with a homegrown PHP reporting framework. The simplicity
    of the ORM and the power of the Admin were extremely liberating.

    Still being involved with custom reporting applications, he decided to try
    his hand at improving the ORM support for analytics. His contributions
    focus on giving more power to users of the ORM.

    Josh lives in Melbourne, Australia where he heads up development for a SaaS
    telecommunications company.

    .. _Josh Smeaton: https://github.com/jarshwah

`Preston Timmons`_
    Preston is a software developer with a background in mathematics. He enjoys
    Django because it enables consistent, simple, and tested systems to be
    built that even new programmers can quickly dive into. Preston lives in
    Dallas, TX.

    .. _Preston Timmons: https://github.com/prestontimmons

`Tomek Paczkowski`_
    Tomek started using Django in 2007 as a tool for quickly dealing with
    university projects. Since then, he worked with various technologies
    like Ruby on Rails, JavaScript and Android but always returned to
    Python and Django.

    Tomek loves the Django community. He organized multiple Django
    sprints, co-organized `DjangoCon Europe 2013`_ and has mentored at many
    `Django Girls`_ events.

    Originally from Poland, Tomek currently lives in London, where he
    works at Squirrel_.

    .. _Tomek Paczkowski: https://hauru.eu
    .. _DjangoCon Europe 2013: http://love.djangocircus.com
    .. _Django Girls: https://djangogirls.org
    .. _Squirrel: https://squirrel.me

`Ola Sitarska`_
    Ola started working with Django in 2009, when she discovered the power of
    the Django admin and quickly fell in love with the beauty of Python.

    She co-organized `DjangoCon Europe 2013`_ in Warsaw and co-authored the
    `Django Girls Tutorial`_, the most beginner friendly Django tutorial out
    there. Together with Ola Sendecka, she started `Django Girls`_, a community
    and series of Django workshops for women who've never programmed before.

    In 2015, she became a Django Software Foundation board member. Ola was also
    a part of the team responsible for shipping the djangoproject.com redesign.

    Originally from Poland, Ola currently lives in London, where she
    works with friends at `Potato`_.

    .. _Ola Sitarska: http://ola.sitarska.com/
    .. _DjangoCon Europe 2013: http://love.djangocircus.com
    .. _Django Girls Tutorial: http://tutorial.djangogirls.org
    .. _Django Girls: https://djangogirls.org
    .. _Potato: https://p.ota.to

`Ola Sendecka`_
    Ola started her adventure with Django when writing a university project in
    2009. After that she attended her first DjangoCon Europe which
    defined her future life as a Django professional.

    Since then she has been an active community member. Ola co-organized a number of
    Django sprints and conferences including:
    `DjangoCon Europe 2013`_, `Django Under the Hood 2015`_ and
    `DjangoCon Europe 2016`_. Together with Ola Sitarska she founded
    `Django Girls`_, co-authored the `Django Girls Tutorial`_ and
    is a member of the Django Girls Foundation. She is also an author of
    the `Coding is for Girls`_ YouTube series teaching programming and Django
    to beginners.

    Originally from Poland, Ola currently lives in London, where she works for `Potato`_.

    .. _Ola Sendecka: https://twitter.com/asendecka
    .. _DjangoCon Europe 2013: http://love.djangocircus.com
    .. _Django Under the Hood 2015: http://www.djangounderthehood.com/
    .. _DjangoCon Europe 2016: http://2016.djangocon.eu
    .. _Django Girls: https://djangogirls.org
    .. _Django Girls Tutorial: http://tutorial.djangogirls.org
    .. _Coding is for Girls: https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A
    .. _Potato: https://p.ota.to


Past team members
=================

Georg "Hugo" Bauer
    Georg created Django's internationalization system, managed i18n
    contributions and made a ton of excellent tweaks, feature additions and bug
    fixes.

Robert Wittams
    Robert was responsible for the *first* refactoring of Django's admin
    application to allow for easier reuse and has made a ton of
    excellent tweaks, feature additions and bug fixes.

`Alex Gaynor`_
    Alex was involved in many parts of Django, he contributed to the ORM,
    forms, admin, amongst others; he is most known for his work on
    multiple-database support in Django.

    Alex lives in Washington, DC, USA.

    .. _Alex Gaynor: https://alexgaynor.net

`Simon Meers`_
    Simon discovered Django 0.96 during his Computer Science PhD research and
    has been developing with it full-time ever since. His core code
    contributions are mostly in Django's admin application.

    Simon works as a freelance developer based in Wollongong, Australia.

    .. _Simon Meers: http://simonmeers.com/

`Gabriel Hurley`_
    Gabriel has been working with Django since 2008, shortly after the 1.0
    release. Convinced by his business partner that Python and Django were the
    right direction for the company, he couldn't have been more happy with the
    decision. His contributions range across many areas in Django, but years of
    copy-editing and an eye for detail lead him to be particularly at home
    while working on Django's documentation.

    Gabriel works as a developer in the SF Bay Area, CA, USA.

    .. _gabriel hurley: http://strikeawe.com/

Malcolm Tredinnick
    Malcolm originally wanted to be a mathematician and somehow ended up a
    software developer. He contributed to many Open Source projects, served on
    the board of the GNOME foundation, and was a great chess player.

    Malcolm was deeply involved in many part of Django - most notably, the
    ORM, but many other internals bear his fingerprints. Django’s support for
    unicode and autoescaping in templates can both be almost entirely
    attributed to Malcolm.

    He was an International Man of Mystery and lived in Sydney, Australia.

    *Malcolm passed away on March 17, 2013.*

`Preston Holmes`_
    Preston is a recovering neuroscientist who originally discovered Django as
    part of a sweeping move to Python from a grab bag of half a dozen
    languages. He was drawn to Django's balance of practical batteries included
    philosophy, care and thought in code design, and strong open source
    community. Currently working in the rent-your-infra space (aka Cloud), he
    is always looking for opportunities to volunteer for community oriented
    education projects, such as for kids and scientists (e.g. Software
    Carpentry).

    Preston lives with his family and animal menagerie in Santa Barbara, CA, USA.

    .. _Preston Holmes: http://www.ptone.com/

`Idan Gazit`_
    As a self-professed design geek, Idan was initially attracted to Django
    sometime between magic-removal and queryset-refactor. Formally trained
    as a software engineer, Idan straddles the worlds of design and code,
    jack of two trades and master of none. He is passionate about usability
    and finding novel ways to extract meaning from data, and is a longtime
    photographer_.

    Idan is currently hacking on all things data and visualization at Heroku_.

    .. _Idan Gazit: http://gazit.me
    .. _photographer: https://flickr.com/photos/idangazit

Matt Boersma
    Matt helped with Django's Oracle support.

Ian Kelly
    Ian also helped with Oracle support.

Joseph Kocherhans
    Joseph was the director of lead development at EveryBlock and previously
    developed at the Lawrence Journal-World. He often disappears for several
    days into the woods, attempts to teach himself computational linguistics,
    and annoys his neighbors with his Charango_ playing.

    Joseph's first contribution to Django was a series of improvements to the
    authorization system leading up to support for pluggable authorization.
    Since then, he's worked on the new forms system, its use in the admin, and
    many other smaller improvements.

    Joseph lives in Chicago, USA.

    .. _charango: https://en.wikipedia.org/wiki/Charango

`Gary Wilson`_
    Gary starting contributing patches to Django in 2006 while developing Web
    applications for `The University of Texas`_ (UT).  Since, he has made
    contributions to the email and forms systems, as well as many other
    improvements and code cleanups throughout the code base.

    Gary lives in Austin, Texas, USA.

    .. _Gary Wilson: http://thegarywilson.com/
    .. _The University of Texas: https://www.utexas.edu/

`Brian Rosner`_
    Brian enjoys learning more about programming languages and system
    architectures and contributing to open source projects.

    He helped immensely in getting Django's "newforms-admin" branch finished
    in time for Django 1.0.

    Brian lives in Denver, Colorado, USA.

    .. _brian rosner: http://brosner.com/

`James Tauber`_
    James is the lead developer of Pinax_ and the CEO and founder of
    Eldarion_. He has been doing open source software since 1993, Python
    since 1998 and Django since 2006. He serves on the board of the Python
    Software Foundation and is currently on a leave of absence from a PhD in
    linguistics.

    James currently lives in Boston, MA, USA but originally hails from
    Perth, Western Australia where he attended the same high school as
    Russell Keith-Magee.

    .. _James Tauber: http://jtauber.com/
    .. _eldarion: http://eldarion.com/
    .. _pinax: http://pinaxproject.com/

---

### 大一小学期 Week 3 Python Exam 2016 Docs Intro Contributing (`大一小学期/Week_3-Python/exam/2016/docs/intro/contributing.txt`)

===================================
Writing your first patch for Django
===================================

Introduction
============

Interested in giving back to the community a little? Maybe you've found a bug
in Django that you'd like to see fixed, or maybe there's a small feature you
want added.

Contributing back to Django itself is the best way to see your own concerns
addressed. This may seem daunting at first, but it's really pretty simple.
We'll walk you through the entire process, so you can learn by example.

Who's this tutorial for?
------------------------

.. seealso::

    If you are looking for a reference on how to submit patches, see the
    :doc:`/internals/contributing/writing-code/submitting-patches`
    documentation.

For this tutorial, we expect that you have at least a basic understanding of
how Django works. This means you should be comfortable going through the
existing tutorials on :doc:`writing your first Django app</intro/tutorial01>`.
In addition, you should have a good understanding of Python itself. But if you
don't, `Dive Into Python`__ is a fantastic (and free) online book for
beginning Python programmers.

Those of you who are unfamiliar with version control systems and Trac will find
that this tutorial and its links include just enough information to get started.
However, you'll probably want to read some more about these different tools if
you plan on contributing to Django regularly.

For the most part though, this tutorial tries to explain as much as possible,
so that it can be of use to the widest audience.

.. admonition:: Where to get help:

    If you're having trouble going through this tutorial, please post a message
    to |django-developers| or drop by `#django-dev on irc.freenode.net`__ to
    chat with other Django users who might be able to help.

__ http://www.diveintopython3.net/
__ irc://irc.freenode.net/django-dev

What does this tutorial cover?
------------------------------

We'll be walking you through contributing a patch to Django for the first time.
By the end of this tutorial, you should have a basic understanding of both the
tools and the processes involved. Specifically, we'll be covering the following:

* Installing Git.
* How to download a development copy of Django.
* Running Django's test suite.
* Writing a test for your patch.
* Writing the code for your patch.
* Testing your patch.
* Generating a patch file for your changes.
* Where to look for more information.

Once you're done with the tutorial, you can look through the rest of
:doc:`Django's documentation on contributing</internals/contributing/index>`.
It contains lots of great information and is a must read for anyone who'd like
to become a regular contributor to Django. If you've got questions, it's
probably got the answers.

.. admonition:: Python 3 required!

    This tutorial assumes you are using Python 3. Get the latest version at
    `Python's download page <https://www.python.org/download/>`_ or with your
    operating system's package manager.

.. admonition:: For Windows users

    When installing Python on Windows, make sure you check the option "Add
    python.exe to Path", so that it is always available on the command line.

Code of Conduct
===============

As a contributor, you can help us keep the Django community open and inclusive.
Please read and follow our `Code of Conduct <https://www.djangoproject.com/conduct/>`_.

Installing Git
==============

For this tutorial, you'll need Git installed to download the current
development version of Django and to generate patch files for the changes you
make.

To check whether or not you have Git installed, enter ``git`` into the command
line. If you get messages saying that this command could not be found, you'll
have to download and install it, see `Git's download page`__.

.. admonition:: For Windows users

    When installing Git on Windows, it is recommended that you pick the
    "Git Bash" option so that Git runs in its own shell. This tutorial assumes
    that's how you have installed it.

If you're not that familiar with Git, you can always find out more about its
commands (once it's installed) by typing ``git help`` into the command line.

__ http://git-scm.com/download

Getting a copy of Django's development version
==============================================

The first step to contributing to Django is to get a copy of the source code.
From the command line, use the ``cd`` command to navigate to the directory
where you'll want your local copy of Django to live.

Download the Django source code repository using the following command:

.. code-block:: console

    $ git clone https://github.com/django/django.git

Now that you have a local copy of Django, you can install it just like you would
install any package using ``pip``. The most convenient way to do so is by using
a *virtual environment* (or virtualenv) which is a feature built into Python
that allows you to keep a separate directory of installed packages for each of
your projects so that they don't interfere with each other.

It's a good idea to keep all your virtualenvs in one place, for example in
``.virtualenvs/`` in your home directory. Create it if it doesn't exist yet:

.. code-block:: console

    $ mkdir ~/.virtualenvs

Now create a new virtualenv by running:

.. code-block:: console

    $ python3 -m venv ~/.virtualenvs/djangodev

The path is where the new environment will be saved on your computer.

.. admonition:: For Windows users

    Using the built-in ``venv`` module will not work if you are also using the
    Git Bash shell on Windows, since activation scripts are only created for the
    system shell (``.bat``) and PowerShell (``.ps1``). Use the ``virtualenv``
    package instead:

    .. code-block:: none

        $ pip install virtualenv
        $ virtualenv ~/.virtualenvs/djangodev

.. admonition:: For Ubuntu users

    On some versions of Ubuntu the above command might fail. Use the
    ``virtualenv`` package instead, first making sure you have ``pip3``:

    .. code-block:: console

        $ sudo apt-get install python3-pip
        $ # Prefix the next command with sudo if it gives a permission denied error
        $ pip3 install virtualenv
        $ virtualenv --python=`which python3` ~/.virtualenvs/djangodev

The final step in setting up your virtualenv is to activate it:

.. code-block:: console

    $ source ~/.virtualenvs/djangodev/bin/activate

If the ``source`` command is not available, you can try using a dot instead:

.. code-block:: console

    $ . ~/.virtualenvs/djangodev/bin/activate

.. admonition:: For Windows users

    To activate your virtualenv on Windows, run:

    .. code-block:: none

        $ source ~/virtualenvs/djangodev/Scripts/activate

You have to activate the virtualenv whenever you open a new terminal window.
virtualenvwrapper__ is a useful tool for making this more convenient.

__ https://virtualenvwrapper.readthedocs.io/en/latest/

Anything you install through ``pip`` from now on will be installed in your new
virtualenv, isolated from other environments and system-wide packages. Also, the
name of the currently activated virtualenv is displayed on the command line to
help you keep track of which one you are using. Go ahead and install the
previously cloned copy of Django:

.. code-block:: console

    $ pip install -e /path/to/your/local/clone/django/

The installed version of Django is now pointing at your local copy. You will
immediately see any changes you make to it, which is of great help when writing
your first patch.

Rolling back to a previous revision of Django
=============================================

For this tutorial, we'll be using ticket :ticket:`24788` as a case study, so
we'll rewind Django's version history in git to before that ticket's patch was
applied. This will allow us to go through all of the steps involved in writing
that patch from scratch, including running Django's test suite.

**Keep in mind that while we'll be using an older revision of Django's trunk
for the purposes of the tutorial below, you should always use the current
development revision of Django when working on your own patch for a ticket!**

.. note::

    The patch for this ticket was written by Paweł Marczewski, and it was
    applied to Django as `commit 4df7e8483b2679fc1cba3410f08960bac6f51115`__.
    Consequently, we'll be using the revision of Django just prior to that,
    `commit 4ccfc4439a7add24f8db4ef3960d02ef8ae09887`__.

__ https://github.com/django/django/commit/4df7e8483b2679fc1cba3410f08960bac6f51115
__ https://github.com/django/django/commit/4ccfc4439a7add24f8db4ef3960d02ef8ae09887

Navigate into Django's root directory (that's the one that contains ``django``,
``docs``, ``tests``, ``AUTHORS``, etc.). You can then check out the older
revision of Django that we'll be using in the tutorial below:

.. code-block:: console

    $ git checkout 4ccfc4439a7add24f8db4ef3960d02ef8ae09887

Running Django's test suite for the first time
==============================================

When contributing to Django it's very important that your code changes don't
introduce bugs into other areas of Django. One way to check that Django still
works after you make your changes is by running Django's test suite. If all
the tests still pass, then you can be reasonably sure that your changes
haven't completely broken Django. If you've never run Django's test suite
before, it's a good idea to run it once beforehand just to get familiar with
what its output is supposed to look like.

Before running the test suite, install its dependencies by first ``cd``-ing
into the Django ``tests/`` directory and then running:

.. code-block:: console

    $ pip install -r requirements/py3.txt

If you encounter an error during the installation, your system might be missing
a dependency for one or more of the Python packages. Consult the failing
package's documentation or search the Web with the error message that you
encounter.

Now we are ready to run the test suite. If you're using GNU/Linux, Mac OS X or
some other flavor of Unix, run:

.. code-block:: console

    $ ./runtests.py

Now sit back and relax. Django's entire test suite has over 9,600 different
tests, so it can take anywhere from 5 to 15 minutes to run, depending on the
speed of your computer.

While Django's test suite is running, you'll see a stream of characters
representing the status of each test as it's run. ``E`` indicates that an error
was raised during a test, and ``F`` indicates that a test's assertions failed.
Both of these are considered to be test failures. Meanwhile, ``x`` and ``s``
indicated expected failures and skipped tests, respectively. Dots indicate
passing tests.

Skipped tests are typically due to missing external libraries required to run
the test; see :ref:`running-unit-tests-dependencies` for a list of dependencies
and be sure to install any for tests related to the changes you are making (we
won't need any for this tutorial). Some tests are specific to a particular
database backend and will be skipped if not testing with that backend. SQLite
is the database backend for the default settings. To run the tests using a
different backend, see :ref:`running-unit-tests-settings`.

Once the tests complete, you should be greeted with a message informing you
whether the test suite passed or failed. Since you haven't yet made any changes
to Django's code, the entire test suite **should** pass. If you get failures or
errors make sure you've followed all of the previous steps properly. See
:ref:`running-unit-tests` for more information. If you're using Python 3.5+,
there will be a couple failures related to deprecation warnings that you can
ignore. These failures have since been fixed in Django.

Note that the latest Django trunk may not always be stable. When developing
against trunk, you can check `Django's continuous integration builds`__ to
determine if the failures are specific to your machine or if they are also
present in Django's official builds. If you click to view a particular build,
you can view the "Configuration Matrix" which shows failures broken down by
Python version and database backend.

__ http://djangoci.com

.. note::

    For this tutorial and the ticket we're working on, testing against SQLite
    is sufficient, however, it's possible (and sometimes necessary) to
    :ref:`run the tests using a different database
    <running-unit-tests-settings>`.

Writing some tests for your ticket
==================================

In most cases, for a patch to be accepted into Django it has to include tests.
For bug fix patches, this means writing a regression test to ensure that the
bug is never reintroduced into Django later on. A regression test should be
written in such a way that it will fail while the bug still exists and pass
once the bug has been fixed. For patches containing new features, you'll need
to include tests which ensure that the new features are working correctly.
They too should fail when the new feature is not present, and then pass once it
has been implemented.

A good way to do this is to write your new tests first, before making any
changes to the code. This style of development is called
`test-driven development`__ and can be applied to both entire projects and
single patches. After writing your tests, you then run them to make sure that
they do indeed fail (since you haven't fixed that bug or added that feature
yet). If your new tests don't fail, you'll need to fix them so that they do.
After all, a regression test that passes regardless of whether a bug is present
is not very helpful at preventing that bug from reoccurring down the road.

Now for our hands-on example.

__ https://en.wikipedia.org/wiki/Test-driven_development

Writing some tests for ticket #24788
------------------------------------

Ticket :ticket:`24788` proposes a small feature addition: the ability to
specify the class level attribute ``prefix`` on Form classes, so that::

    […] forms which ship with apps could effectively namespace themselves such
    that N overlapping form fields could be POSTed at once and resolved to the
    correct form.

In order to resolve this ticket, we'll add a ``prefix`` attribute to the
``BaseForm`` class. When creating instances of this class, passing a prefix to
the ``__init__()`` method will still set that prefix on the created instance.
But not passing a prefix (or passing ``None``) will use the class-level prefix.
Before we make those changes though, we're going to write a couple tests to
verify that our modification functions correctly and continues to function
correctly in the future.

Navigate to Django's ``tests/forms_tests/tests/`` folder and open the
``test_forms.py`` file. Add the following code on line 1674 right before the
``test_forms_with_null_boolean`` function::

    def test_class_prefix(self):
        # Prefix can be also specified at the class level.
        class Person(Form):
            first_name = CharField()
            prefix = 'foo'

        p = Person()
        self.assertEqual(p.prefix, 'foo')

        p = Person(prefix='bar')
        self.assertEqual(p.prefix, 'bar')

This new test checks that setting a class level prefix works as expected, and
that passing a ``prefix`` parameter when creating an instance still works too.

.. admonition:: But this testing thing looks kinda hard...

    If you've never had to deal with tests before, they can look a little hard
    to write at first glance. Fortunately, testing is a *very* big subject in
    computer programming, so there's lots of information out there:

    * A good first look at writing tests for Django can be found in the
      documentation on :doc:`/topics/testing/overview`.
    * Dive Into Python (a free online book for beginning Python developers)
      includes a great `introduction to Unit Testing`__.
    * After reading those, if you want something a little meatier to sink
      your teeth into, there's always the Python :mod:`unittest` documentation.

__ http://www.diveintopython.net/unit_testing/index.html

Running your new test
---------------------

Remember that we haven't actually made any modifications to ``BaseForm`` yet,
so our tests are going to fail. Let's run all the tests in the ``forms_tests``
folder to make sure that's really what happens. From the command line, ``cd``
into the Django ``tests/`` directory and run:

.. code-block:: console

    $ ./runtests.py forms_tests

If the tests ran correctly, you should see one failure corresponding to the test
method we added. If all of the tests passed, then you'll want to make sure that
you added the new test shown above to the appropriate folder and class.

Writing the code for your ticket
================================

Next we'll be adding the functionality described in ticket :ticket:`24788` to
Django.

Writing the code for ticket #24788
----------------------------------

Navigate to the ``django/django/forms/`` folder and open the ``forms.py`` file.
Find the ``BaseForm`` class on line 72 and add the ``prefix`` class attribute
right after the ``field_order`` attribute::

    class BaseForm(object):
        # This is the main implementation of all the Form logic. Note that this
        # class is different than Form. See the comments by the Form class for
        # more information. Any improvements to the form API should be made to
        # *this* class, not to the Form class.
        field_order = None
        prefix = None

Verifying your test now passes
------------------------------

Once you're done modifying Django, we need to make sure that the tests we wrote
earlier pass, so we can see whether the code we wrote above is working
correctly. To run the tests in the ``forms_tests`` folder, ``cd`` into the
Django ``tests/`` directory and run:

.. code-block:: console

    $ ./runtests.py forms_tests

Oops, good thing we wrote those tests! You should still see one failure with
the following exception::

    AssertionError: None != 'foo'

We forgot to add the conditional statement in the ``__init__`` method. Go ahead
and change ``self.prefix = prefix`` that is now on line 87 of
``django/forms/forms.py``, adding a conditional statement::

    if prefix is not None:
        self.prefix = prefix

Re-run the tests and everything should pass. If it doesn't, make sure you
correctly modified the ``BaseForm`` class as shown above and copied the new test
correctly.

Running Django's test suite for the second time
===============================================

Once you've verified that your patch and your test are working correctly, it's
a good idea to run the entire Django test suite just to verify that your change
hasn't introduced any bugs into other areas of Django. While successfully
passing the entire test suite doesn't guarantee your code is bug free, it does
help identify many bugs and regressions that might otherwise go unnoticed.

To run the entire Django test suite, ``cd`` into the Django ``tests/``
directory and run:

.. code-block:: console

    $ ./runtests.py

As long as you don't see any failures, you're good to go.

Writing Documentation
=====================

This is a new feature, so it should be documented. Add the following section on
line 1068 (at the end of the file) of ``django/docs/ref/forms/api.txt``::

    The prefix can also be specified on the form class::

        >>> class PersonForm(forms.Form):
        ...     ...
        ...     prefix = 'person'

    .. versionadded:: 1.9

        The ability to specify ``prefix`` on the form class was added.

Since this new feature will be in an upcoming release it is also added to the
release notes for Django 1.9, on line 164 under the "Forms" section in the file
``docs/releases/1.9.txt``::

    * A form prefix can be specified inside a form class, not only when
      instantiating a form. See :ref:`form-prefix` for details.

For more information on writing documentation, including an explanation of what
the ``versionadded`` bit is all about, see
:doc:`/internals/contributing/writing-documentation`. That page also includes
an explanation of how to build a copy of the documentation locally, so you can
preview the HTML that will be generated.

Generating a patch for your changes
===================================

Now it's time to generate a patch file that can be uploaded to Trac or applied
to another copy of Django. To get a look at the content of your patch, run the
following command:

.. code-block:: console

    $ git diff

This will display the differences between your current copy of Django (with
your changes) and the revision that you initially checked out earlier in the
tutorial.

Once you're done looking at the patch, hit the ``q`` key to exit back to the
command line. If the patch's content looked okay, you can run the following
command to save the patch file to your current working directory:

.. code-block:: console

    $ git diff > 24788.diff

You should now have a file in the root Django directory called ``24788.diff``.
This patch file contains all your changes and should look this:

.. code-block:: diff

    diff --git a/django/forms/forms.py b/django/forms/forms.py
    index 509709f..d1370de 100644
    --- a/django/forms/forms.py
    +++ b/django/forms/forms.py
    @@ -75,6 +75,7 @@ class BaseForm(object):
         # information. Any improvements to the form API should be made to *this*
         # class, not to the Form class.
         field_order = None
    +    prefix = None

         def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                      initial=None, error_class=ErrorList, label_suffix=None,
    @@ -83,7 +84,8 @@ class BaseForm(object):
             self.data = data or {}
             self.files = files or {}
             self.auto_id = auto_id
    -        self.prefix = prefix
    +        if prefix is not None:
    +            self.prefix = prefix
             self.initial = initial or {}
             self.error_class = error_class
             # Translators: This is the default suffix added to form field labels
    diff --git a/docs/ref/forms/api.txt b/docs/ref/forms/api.txt
    index 3bc39cd..008170d 100644
    --- a/docs/ref/forms/api.txt
    +++ b/docs/ref/forms/api.txt
    @@ -1065,3 +1065,13 @@ You can put several Django forms inside one ``<form>`` tag. To give each
         >>> print(father.as_ul())
         <li><label for="id_father-first_name">First name:</label> <input type="text" name="father-first_name" id="id_father-first_name" /></li>
         <li><label for="id_father-last_name">Last name:</label> <input type="text" name="father-last_name" id="id_father-last_name" /></li>
    +
    +The prefix can also be specified on the form class::
    +
    +    >>> class PersonForm(forms.Form):
    +    ...     ...
    +    ...     prefix = 'person'
    +
    +.. versionadded:: 1.9
    +
    +    The ability to specify ``prefix`` on the form class was added.
    diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt
    index 5b58f79..f9bb9de 100644
    --- a/docs/releases/1.9.txt
    +++ b/docs/releases/1.9.txt
    @@ -161,6 +161,9 @@ Forms
       :attr:`~django.forms.Form.field_order` attribute, the ``field_order``
       constructor argument , or the :meth:`~django.forms.Form.order_fields` method.

    +* A form prefix can be specified inside a form class, not only when
    +  instantiating a form. See :ref:`form-prefix` for details.
    +
     Generic Views
     ^^^^^^^^^^^^^

    diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py
    index 690f205..e07fae2 100644
    --- a/tests/forms_tests/tests/test_forms.py
    +++ b/tests/forms_tests/tests/test_forms.py
    @@ -1671,6 +1671,18 @@ class FormsTestCase(SimpleTestCase):
             self.assertEqual(p.cleaned_data['last_name'], 'Lennon')
             self.assertEqual(p.cleaned_data['birthday'], datetime.date(1940, 10, 9))

    +    def test_class_prefix(self):
    +        # Prefix can be also specified at the class level.
    +        class Person(Form):
    +            first_name = CharField()
    +            prefix = 'foo'
    +
    +        p = Person()
    +        self.assertEqual(p.prefix, 'foo')
    +
    +        p = Person(prefix='bar')
    +        self.assertEqual(p.prefix, 'bar')
    +
         def test_forms_with_null_boolean(self):
             # NullBooleanField is a bit of a special case because its presentation (widget)
             # is different than its data. This is handled transparently, though.

So what do I do next?
=====================

Congratulations, you've generated your very first Django patch! Now that you've
got that under your belt, you can put those skills to good use by helping to
improve Django's codebase. Generating patches and attaching them to Trac
tickets is useful, however, since we are using git - adopting a more :doc:`git
oriented workflow </internals/contributing/writing-code/working-with-git>` is
recommended.

Since we never committed our changes locally, perform the following to get your
git branch back to a good starting point:

.. code-block:: console

    $ git reset --hard HEAD
    $ git checkout master

More information for new contributors
-------------------------------------

Before you get too into writing patches for Django, there's a little more
information on contributing that you should probably take a look at:

* You should make sure to read Django's documentation on
  :doc:`claiming tickets and submitting patches
  </internals/contributing/writing-code/submitting-patches>`.
  It covers Trac etiquette, how to claim tickets for yourself, expected
  coding style for patches, and many other important details.
* First time contributors should also read Django's :doc:`documentation
  for first time contributors</internals/contributing/new-contributors/>`.
  It has lots of good advice for those of us who are new to helping out
  with Django.
* After those, if you're still hungry for more information about
  contributing, you can always browse through the rest of
  :doc:`Django's documentation on contributing</internals/contributing/index>`.
  It contains a ton of useful information and should be your first source
  for answering any questions you might have.

Finding your first real ticket
------------------------------

Once you've looked through some of that information, you'll be ready to go out
and find a ticket of your own to write a patch for. Pay special attention to
tickets with the "easy pickings" criterion. These tickets are often much
simpler in nature and are great for first time contributors. Once you're
familiar with contributing to Django, you can move on to writing patches for
more difficult and complicated tickets.

If you just want to get started already (and nobody would blame you!), try
taking a look at the list of `easy tickets that need patches`__ and the
`easy tickets that have patches which need improvement`__. If you're familiar
with writing tests, you can also look at the list of
`easy tickets that need tests`__. Just remember to follow the guidelines about
claiming tickets that were mentioned in the link to Django's documentation on
:doc:`claiming tickets and submitting patches
</internals/contributing/writing-code/submitting-patches>`.

__ https://code.djangoproject.com/query?status=new&status=reopened&has_patch=0&easy=1&col=id&col=summary&col=status&col=owner&col=type&col=milestone&order=priority
__ https://code.djangoproject.com/query?status=new&status=reopened&needs_better_patch=1&easy=1&col=id&col=summary&col=status&col=owner&col=type&col=milestone&order=priority
__ https://code.djangoproject.com/query?status=new&status=reopened&needs_tests=1&easy=1&col=id&col=summary&col=status&col=owner&col=type&col=milestone&order=priority

What's next?
------------

After a ticket has a patch, it needs to be reviewed by a second set of eyes.
After uploading a patch or submitting a pull request, be sure to update the
ticket metadata by setting the flags on the ticket to say "has patch",
"doesn't need tests", etc, so others can find it for review. Contributing
doesn't necessarily always mean writing a patch from scratch. Reviewing
existing patches is also a very helpful contribution. See
:doc:`/internals/contributing/triaging-tickets` for details.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Intro Index (`大一小学期/Week_3-Python/exam/2016/docs/intro/index.txt`)

===============
Getting started
===============

New to Django? Or to Web development in general? Well, you came to the right
place: read this material to quickly get up and running.

.. toctree::
   :maxdepth: 1

   overview
   install
   tutorial01
   tutorial02
   tutorial03
   tutorial04
   tutorial05
   tutorial06
   tutorial07
   reusable-apps
   whatsnext
   contributing

.. seealso::

    If you're new to Python_, you might want to start by getting an idea of what
    the language is like. Django is 100% Python, so if you've got minimal
    comfort with Python you'll probably get a lot more out of Django.

    If you're new to programming entirely, you might want to start with this
    `list of Python resources for non-programmers`_

    If you already know a few other languages and want to get up to speed with
    Python quickly, we recommend `Dive Into Python`_. If that's not quite your
    style, there are many other `books about Python`_.

    .. _python: https://python.org/
    .. _list of Python resources for non-programmers: https://wiki.python.org/moin/BeginnersGuide/NonProgrammers
    .. _Dive Into Python: http://www.diveintopython3.net/
    .. _books about Python: https://wiki.python.org/moin/PythonBooks

---

### 大一小学期 Week 3 Python Exam 2016 Docs Intro Install (`大一小学期/Week_3-Python/exam/2016/docs/intro/install.txt`)

===================
Quick install guide
===================

Before you can use Django, you'll need to get it installed. We have a
:doc:`complete installation guide </topics/install>` that covers all the
possibilities; this guide will guide you to a simple, minimal installation
that'll work while you walk through the introduction.

Install Python
==============

Being a Python Web framework, Django requires Python. See
:ref:`faq-python-version-support` for details. Python includes a lightweight
database called SQLite_ so you won't need to set up a database just yet.

.. _sqlite: https://sqlite.org/

Get the latest version of Python at https://www.python.org/download/ or with
your operating system's package manager.

.. admonition:: Django on Jython

    If you use Jython_ (a Python implementation for the Java platform), you'll
    need to follow a few additional steps. See :doc:`/howto/jython` for details.

.. _jython: http://www.jython.org/

You can verify that Python is installed by typing ``python`` from your shell;
you should see something like::

    Python 3.4.x
    [GCC 4.x] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>>

Set up a database
=================

This step is only necessary if you'd like to work with a "large" database engine
like PostgreSQL, MySQL, or Oracle. To install such a database, consult the
:ref:`database installation information <database-installation>`.

Remove any old versions of Django
=================================

If you are upgrading your installation of Django from a previous version, you
will need to :ref:`uninstall the old Django version before installing the new
version <removing-old-versions-of-django>`.

Install Django
==============

You've got three easy options to install Django:

* Install a version of Django :doc:`provided by your operating system
  distribution </misc/distributions>`. This is the quickest option for those
  who have operating systems that distribute Django.

* :ref:`Install an official release <installing-official-release>`. This
  is the best approach for most users.

* :ref:`Install the latest development version
  <installing-development-version>`. This option is for enthusiasts who want
  the latest-and-greatest features and aren't afraid of running brand new code.
  You might encounter new bugs in the development version, but reporting them
  helps the development of Django. Also, releases of third-party packages are
  less likely to be compatible with the development version than with the
  latest stable release.

.. admonition:: Always refer to the documentation that corresponds to the
    version of Django you're using!

    If you do either of the first two steps, keep an eye out for parts of the
    documentation marked **new in development version**. That phrase flags
    features that are only available in development versions of Django, and
    they likely won't work with an official release.


Verifying
=========

To verify that Django can be seen by Python, type ``python`` from your shell.
Then at the Python prompt, try to import Django:

.. parsed-literal::

    >>> import django
    >>> print(django.get_version())
    |version|

You may have another version of Django installed.

That's it!
==========

That's it -- you can now :doc:`move onto the tutorial </intro/tutorial01>`.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Intro Overview (`大一小学期/Week_3-Python/exam/2016/docs/intro/overview.txt`)

==================
Django at a glance
==================

Because Django was developed in a fast-paced newsroom environment, it was
designed to make common Web-development tasks fast and easy. Here's an informal
overview of how to write a database-driven Web app with Django.

The goal of this document is to give you enough technical specifics to
understand how Django works, but this isn't intended to be a tutorial or
reference -- but we've got both! When you're ready to start a project, you can
:doc:`start with the tutorial </intro/tutorial01>` or :doc:`dive right into more
detailed documentation </topics/index>`.

Design your model
=================

Although you can use Django without a database, it comes with an
`object-relational mapper`_ in which you describe your database layout in Python
code.

.. _object-relational mapper: https://en.wikipedia.org/wiki/Object-relational_mapping

The :doc:`data-model syntax </topics/db/models>` offers many rich ways of
representing your models -- so far, it's been solving many years' worth of
database-schema problems. Here's a quick example:

.. snippet::
    :filename: mysite/news/models.py

    from django.db import models

    class Reporter(models.Model):
        full_name = models.CharField(max_length=70)

        def __str__(self):              # __unicode__ on Python 2
            return self.full_name

    class Article(models.Model):
        pub_date = models.DateField()
        headline = models.CharField(max_length=200)
        content = models.TextField()
        reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)

        def __str__(self):              # __unicode__ on Python 2
            return self.headline

Install it
==========

Next, run the Django command-line utility to create the database tables
automatically:

.. code-block:: console

    $ python manage.py migrate

The :djadmin:`migrate` command looks at all your available models and creates
tables in your database for whichever tables don't already exist, as well as
optionally providing :doc:`much richer schema control </topics/migrations>`.

Enjoy the free API
==================

With that, you've got a free, and rich, :doc:`Python API </topics/db/queries>`
to access your data. The API is created on the fly, no code generation
necessary:

.. code-block:: python

    # Import the models we created from our "news" app
    >>> from news.models import Reporter, Article

    # No reporters are in the system yet.
    >>> Reporter.objects.all()
    <QuerySet []>

    # Create a new Reporter.
    >>> r = Reporter(full_name='John Smith')

    # Save the object into the database. You have to call save() explicitly.
    >>> r.save()

    # Now it has an ID.
    >>> r.id
    1

    # Now the new reporter is in the database.
    >>> Reporter.objects.all()
    <QuerySet [<Reporter: John Smith>]>

    # Fields are represented as attributes on the Python object.
    >>> r.full_name
    'John Smith'

    # Django provides a rich database lookup API.
    >>> Reporter.objects.get(id=1)
    <Reporter: John Smith>
    >>> Reporter.objects.get(full_name__startswith='John')
    <Reporter: John Smith>
    >>> Reporter.objects.get(full_name__contains='mith')
    <Reporter: John Smith>
    >>> Reporter.objects.get(id=2)
    Traceback (most recent call last):
        ...
    DoesNotExist: Reporter matching query does not exist.

    # Create an article.
    >>> from datetime import date
    >>> a = Article(pub_date=date.today(), headline='Django is cool',
    ...     content='Yeah.', reporter=r)
    >>> a.save()

    # Now the article is in the database.
    >>> Article.objects.all()
    <QuerySet [<Article: Django is cool>]>

    # Article objects get API access to related Reporter objects.
    >>> r = a.reporter
    >>> r.full_name
    'John Smith'

    # And vice versa: Reporter objects get API access to Article objects.
    >>> r.article_set.all()
    <QuerySet [<Article: Django is cool>]>

    # The API follows relationships as far as you need, performing efficient
    # JOINs for you behind the scenes.
    # This finds all articles by a reporter whose name starts with "John".
    >>> Article.objects.filter(reporter__full_name__startswith='John')
    <QuerySet [<Article: Django is cool>]>

    # Change an object by altering its attributes and calling save().
    >>> r.full_name = 'Billy Goat'
    >>> r.save()

    # Delete an object with delete().
    >>> r.delete()

A dynamic admin interface: it's not just scaffolding -- it's the whole house
============================================================================

Once your models are defined, Django can automatically create a professional,
production ready :doc:`administrative interface </ref/contrib/admin/index>` --
a website that lets authenticated users add, change and delete objects. It's
as easy as registering your model in the admin site:

.. snippet::
    :filename: mysite/news/models.py

    from django.db import models

    class Article(models.Model):
        pub_date = models.DateField()
        headline = models.CharField(max_length=200)
        content = models.TextField()
        reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)

.. snippet::
    :filename: mysite/news/admin.py

    from django.contrib import admin

    from . import models

    admin.site.register(models.Article)

The philosophy here is that your site is edited by a staff, or a client, or
maybe just you -- and you don't want to have to deal with creating backend
interfaces just to manage content.

One typical workflow in creating Django apps is to create models and get the
admin sites up and running as fast as possible, so your staff (or clients) can
start populating data. Then, develop the way data is presented to the public.

Design your URLs
================

A clean, elegant URL scheme is an important detail in a high-quality Web
application. Django encourages beautiful URL design and doesn't put any cruft
in URLs, like ``.php`` or ``.asp``.

To design URLs for an app, you create a Python module called a :doc:`URLconf
</topics/http/urls>`. A table of contents for your app, it contains a simple
mapping between URL patterns and Python callback functions. URLconfs also serve
to decouple URLs from Python code.

Here's what a URLconf might look like for the ``Reporter``/``Article``
example above:

.. snippet::
    :filename: mysite/news/urls.py

    from django.conf.urls import url

    from . import views

    urlpatterns = [
        url(r'^articles/([0-9]{4})/$', views.year_archive),
        url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
        url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
    ]

The code above maps URLs, as simple :ref:`regular expressions <regex-howto>`,
to the location of Python callback functions ("views"). The regular expressions
use parenthesis to "capture" values from the URLs. When a user requests a page,
Django runs through each pattern, in order, and stops at the first one that
matches the requested URL. (If none of them matches, Django calls a
special-case 404 view.) This is blazingly fast, because the regular expressions
are compiled at load time.

Once one of the regexes matches, Django imports and calls the given view, which
is a simple Python function. Each view gets passed a request object --
which contains request metadata -- and the values captured in the regex.

For example, if a user requested the URL "/articles/2005/05/39323/", Django
would call the function ``news.views.article_detail(request,
'2005', '05', '39323')``.

Write your views
================

Each view is responsible for doing one of two things: Returning an
:class:`~django.http.HttpResponse` object containing the content for the
requested page, or raising an exception such as :class:`~django.http.Http404`.
The rest is up to you.

Generally, a view retrieves data according to the parameters, loads a template
and renders the template with the retrieved data. Here's an example view for
``year_archive`` from above:

.. snippet::
    :filename: mysite/news/views.py

    from django.shortcuts import render

    from .models import Article

    def year_archive(request, year):
        a_list = Article.objects.filter(pub_date__year=year)
        context = {'year': year, 'article_list': a_list}
        return render(request, 'news/year_archive.html', context)

This example uses Django's :doc:`template system </topics/templates>`, which has
several powerful features but strives to stay simple enough for non-programmers
to use.

Design your templates
=====================

The code above loads the ``news/year_archive.html`` template.

Django has a template search path, which allows you to minimize redundancy among
templates. In your Django settings, you specify a list of directories to check
for templates with :setting:`DIRS <TEMPLATES-DIRS>`. If a template doesn't exist
in the first directory, it checks the second, and so on.

Let's say the ``news/year_archive.html`` template was found. Here's what that
might look like:

.. snippet:: html+django
    :filename: mysite/news/templates/news/year_archive.html

    {% extends "base.html" %}

    {% block title %}Articles for {{ year }}{% endblock %}

    {% block content %}
    <h1>Articles for {{ year }}</h1>

    {% for article in article_list %}
        <p>{{ article.headline }}</p>
        <p>By {{ article.reporter.full_name }}</p>
        <p>Published {{ article.pub_date|date:"F j, Y" }}</p>
    {% endfor %}
    {% endblock %}

Variables are surrounded by double-curly braces. ``{{ article.headline }}``
means "Output the value of the article's headline attribute." But dots aren't
used only for attribute lookup. They also can do dictionary-key lookup, index
lookup and function calls.

Note ``{{ article.pub_date|date:"F j, Y" }}`` uses a Unix-style "pipe" (the "|"
character). This is called a template filter, and it's a way to filter the value
of a variable. In this case, the date filter formats a Python datetime object in
the given format (as found in PHP's date function).

You can chain together as many filters as you'd like. You can write :ref:`custom
template filters <howto-writing-custom-template-filters>`. You can write
:doc:`custom template tags </howto/custom-template-tags>`, which run custom
Python code behind the scenes.

Finally, Django uses the concept of "template inheritance". That's what the
``{% extends "base.html" %}`` does. It means "First load the template called
'base', which has defined a bunch of blocks, and fill the blocks with the
following blocks." In short, that lets you dramatically cut down on redundancy
in templates: each template has to define only what's unique to that template.

Here's what the "base.html" template, including the use of :doc:`static files
</howto/static-files/index>`, might look like:

.. snippet:: html+django
    :filename: mysite/templates/base.html

    {% load static %}
    <html>
    <head>
        <title>{% block title %}{% endblock %}</title>
    </head>
    <body>
        <img src="{% static "images/sitelogo.png" %}" alt="Logo" />
        {% block content %}{% endblock %}
    </body>
    </html>

Simplistically, it defines the look-and-feel of the site (with the site's logo),
and provides "holes" for child templates to fill. This makes a site redesign as
easy as changing a single file -- the base template.

It also lets you create multiple versions of a site, with different base
templates, while reusing child templates. Django's creators have used this
technique to create strikingly different mobile versions of sites -- simply by
creating a new base template.

Note that you don't have to use Django's template system if you prefer another
system. While Django's template system is particularly well-integrated with
Django's model layer, nothing forces you to use it. For that matter, you don't
have to use Django's database API, either. You can use another database
abstraction layer, you can read XML files, you can read files off disk, or
anything you want. Each piece of Django -- models, views, templates -- is
decoupled from the next.

This is just the surface
========================

This has been only a quick overview of Django's functionality. Some more useful
features:

* A :doc:`caching framework </topics/cache>` that integrates with memcached
  or other backends.

* A :doc:`syndication framework </ref/contrib/syndication>` that makes
  creating RSS and Atom feeds as easy as writing a small Python class.

* More sexy automatically-generated admin features -- this overview barely
  scratched the surface.

The next obvious steps are for you to `download Django`_, read :doc:`the
tutorial </intro/tutorial01>` and join `the community`_. Thanks for your
interest!

.. _download Django: https://www.djangoproject.com/download/
.. _the community: https://www.djangoproject.com/community/

---

### 大一小学期 Week 3 Python Exam 2016 Docs Intro Reusable Apps (`大一小学期/Week_3-Python/exam/2016/docs/intro/reusable-apps.txt`)

=============================================
Advanced tutorial: How to write reusable apps
=============================================

This advanced tutorial begins where :doc:`Tutorial 7 </intro/tutorial07>`
left off. We'll be turning our Web-poll into a standalone Python package
you can reuse in new projects and share with other people.

If you haven't recently completed Tutorials 1–7, we encourage you to review
these so that your example project matches the one described below.

Reusability matters
===================

It's a lot of work to design, build, test and maintain a web application. Many
Python and Django projects share common problems. Wouldn't it be great if we
could save some of this repeated work?

Reusability is the way of life in Python. `The Python Package Index (PyPI)
<https://pypi.python.org/pypi>`_ has a vast range of packages you can use in
your own Python programs. Check out `Django Packages
<https://www.djangopackages.com>`_ for existing reusable apps you could
incorporate in your project. Django itself is also just a Python package. This
means that you can take existing Python packages or Django apps and compose
them into your own web project. You only need to write the parts that make
your project unique.

Let's say you were starting a new project that needed a polls app like the one
we've been working on. How do you make this app reusable? Luckily, you're well
on the way already. In :doc:`Tutorial 3 </intro/tutorial03>`, we saw how we
could decouple polls from the project-level URLconf using an ``include``.
In this tutorial, we'll take further steps to make the app easy to use in new
projects and ready to publish for others to install and use.

.. admonition:: Package? App?

    A Python :term:`package` provides a way of grouping related Python code for
    easy reuse. A package contains one or more files of Python code (also known
    as "modules").

    A package can be imported with ``import foo.bar`` or ``from foo import
    bar``. For a directory (like ``polls``) to form a package, it must contain
    a special file ``__init__.py``, even if this file is empty.

    A Django *application* is just a Python package that is specifically
    intended for use in a Django project. An application may use common Django
    conventions, such as having ``models``, ``tests``, ``urls``, and ``views``
    submodules.

    Later on we use the term *packaging* to describe the process of making a
    Python package easy for others to install. It can be a little confusing, we
    know.

Your project and your reusable app
==================================

After the previous tutorials, our project should look like this::

    mysite/
        manage.py
        mysite/
            __init__.py
            settings.py
            urls.py
            wsgi.py
        polls/
            __init__.py
            admin.py
            migrations/
                __init__.py
                0001_initial.py
            models.py
            static/
                polls/
                    images/
                        background.gif
                    style.css
            templates/
                polls/
                    detail.html
                    index.html
                    results.html
            tests.py
            urls.py
            views.py
        templates/
            admin/
                base_site.html

You created ``mysite/templates`` in :doc:`Tutorial 7 </intro/tutorial07>`,
and ``polls/templates`` in :doc:`Tutorial 3 </intro/tutorial03>`. Now perhaps
it is clearer why we chose to have separate template directories for the
project and application: everything that is part of the polls application is in
``polls``. It makes the application self-contained and easier to drop into a
new project.

The ``polls`` directory could now be copied into a new Django project and
immediately reused. It's not quite ready to be published though. For that, we
need to package the app to make it easy for others to install.

.. _installing-reusable-apps-prerequisites:

Installing some prerequisites
=============================

The current state of Python packaging is a bit muddled with various tools. For
this tutorial, we're going to use setuptools_ to build our package. It's the
recommended packaging tool (merged with the ``distribute`` fork). We'll also be
using `pip`_ to install and uninstall it. You should install these
two packages now. If you need help, you can refer to :ref:`how to install
Django with pip<installing-official-release>`. You can install ``setuptools``
the same way.

.. _setuptools: https://pypi.python.org/pypi/setuptools
.. _pip: https://pypi.python.org/pypi/pip

Packaging your app
==================

Python *packaging* refers to preparing your app in a specific format that can
be easily installed and used. Django itself is packaged very much like
this. For a small app like polls, this process isn't too difficult.

1. First, create a parent directory for ``polls``, outside of your Django
   project. Call this directory ``django-polls``.

   .. admonition::  Choosing a name for your app

       When choosing a name for your package, check resources like PyPI to avoid
       naming conflicts with existing packages. It's often useful to prepend
       ``django-`` to your module name when creating a package to distribute.
       This helps others looking for Django apps identify your app as Django
       specific.

       Application labels (that is, the final part of the dotted path to
       application packages) *must* be unique in :setting:`INSTALLED_APPS`.
       Avoid using the same label as any of the Django :doc:`contrib packages
       </ref/contrib/index>`, for example ``auth``, ``admin``, or
       ``messages``.

2. Move the ``polls`` directory into the ``django-polls`` directory.

3. Create a file ``django-polls/README.rst`` with the following contents:

   .. snippet::
       :filename: django-polls/README.rst

       =====
       Polls
       =====

       Polls is a simple Django app to conduct Web-based polls. For each
       question, visitors can choose between a fixed number of answers.

       Detailed documentation is in the "docs" directory.

       Quick start
       -----------

       1. Add "polls" to your INSTALLED_APPS setting like this::

           INSTALLED_APPS = [
               ...
               'polls',
           ]

       2. Include the polls URLconf in your project urls.py like this::

           url(r'^polls/', include('polls.urls')),

       3. Run `python manage.py migrate` to create the polls models.

       4. Start the development server and visit http://127.0.0.1:8000/admin/
          to create a poll (you'll need the Admin app enabled).

       5. Visit http://127.0.0.1:8000/polls/ to participate in the poll.

4. Create a ``django-polls/LICENSE`` file. Choosing a license is beyond the
   scope of this tutorial, but suffice it to say that code released publicly
   without a license is *useless*. Django and many Django-compatible apps are
   distributed under the BSD license; however, you're free to pick your own
   license. Just be aware that your licensing choice will affect who is able
   to use your code.

5. Next we'll create a ``setup.py`` file which provides details about how to
   build and install the app.  A full explanation of this file is beyond the
   scope of this tutorial, but the `setuptools docs
   <https://setuptools.readthedocs.io/en/latest/>`_ have a good
   explanation. Create a file ``django-polls/setup.py`` with the following
   contents:

   .. snippet::
       :filename: django-polls/setup.py

       import os
       from setuptools import find_packages, setup

       with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as readme:
           README = readme.read()

       # allow setup.py to be run from any path
       os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))

       setup(
           name='django-polls',
           version='0.1',
           packages=find_packages(),
           include_package_data=True,
           license='BSD License',  # example license
           description='A simple Django app to conduct Web-based polls.',
           long_description=README,
           url='https://www.example.com/',
           author='Your Name',
           author_email='yourname@example.com',
           classifiers=[
               'Environment :: Web Environment',
               'Framework :: Django',
               'Framework :: Django :: X.Y',  # replace "X.Y" as appropriate
               'Intended Audience :: Developers',
               'License :: OSI Approved :: BSD License',  # example license
               'Operating System :: OS Independent',
               'Programming Language :: Python',
               # Replace these appropriately if you are stuck on Python 2.
               'Programming Language :: Python :: 3',
               'Programming Language :: Python :: 3.4',
               'Programming Language :: Python :: 3.5',
               'Topic :: Internet :: WWW/HTTP',
               'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
           ],
       )

6. Only Python modules and packages are included in the package by default. To
   include additional files, we'll need to create a ``MANIFEST.in`` file. The
   setuptools docs referred to in the previous step discuss this file in more
   details. To include the templates, the ``README.rst`` and our ``LICENSE``
   file, create a file ``django-polls/MANIFEST.in`` with the following
   contents:

   .. snippet::
       :filename: django-polls/MANIFEST.in

       include LICENSE
       include README.rst
       recursive-include polls/static *
       recursive-include polls/templates *

7. It's optional, but recommended, to include detailed documentation with your
   app. Create an empty directory ``django-polls/docs`` for future
   documentation. Add an additional line to ``django-polls/MANIFEST.in``::

    recursive-include docs *

   Note that the ``docs`` directory won't be included in your package unless
   you add some files to it. Many Django apps also provide their documentation
   online through sites like `readthedocs.org <https://readthedocs.org>`_.

8. Try building your package with ``python setup.py sdist`` (run from inside
   ``django-polls``). This creates a directory called ``dist`` and builds your
   new package, ``django-polls-0.1.tar.gz``.

For more information on packaging, see Python's `Tutorial on Packaging and
Distributing Projects <https://packaging.python.org/en/latest/distributing.html>`_.

Using your own package
======================

Since we moved the ``polls`` directory out of the project, it's no longer
working. We'll now fix this by installing our new ``django-polls`` package.

.. admonition:: Installing as a user library

   The following steps install ``django-polls`` as a user library. Per-user
   installs have a lot of advantages over installing the package system-wide,
   such as being usable on systems where you don't have administrator access
   as well as preventing the package from affecting system services and other
   users of the machine.

   Note that per-user installations can still affect the behavior of system
   tools that run as that user, so ``virtualenv`` is a more robust solution
   (see below).

1. To install the package, use pip (you already :ref:`installed it
   <installing-reusable-apps-prerequisites>`, right?)::

    pip install --user django-polls/dist/django-polls-0.1.tar.gz

2. With luck, your Django project should now work correctly again. Run the
   server again to confirm this.

3. To uninstall the package, use pip::

    pip uninstall django-polls

.. _pip: https://pypi.python.org/pypi/pip

Publishing your app
===================

Now that we've packaged and tested ``django-polls``, it's ready to share with
the world! If this wasn't just an example, you could now:

* Email the package to a friend.

* Upload the package on your website.

* Post the package on a public repository, such as `the Python Package Index
  (PyPI)`_. `packaging.python.org <https://packaging.python.org>`_ has `a good
  tutorial <https://packaging.python.org/en/latest/distributing.html#uploading-your-project-to-pypi>`_
  for doing this.

Installing Python packages with virtualenv
==========================================

Earlier, we installed the polls app as a user library. This has some
disadvantages:

* Modifying the user libraries can affect other Python software on your system.

* You won't be able to run multiple versions of this package (or others with
  the same name).

Typically, these situations only arise once you're maintaining several Django
projects. When they do, the best solution is to use `virtualenv
<http://www.virtualenv.org/>`_. This tool allows you to maintain multiple
isolated Python environments, each with its own copy of the libraries and
package namespace.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Intro Tutorial01 (`大一小学期/Week_3-Python/exam/2016/docs/intro/tutorial01.txt`)

=====================================
Writing your first Django app, part 1
=====================================

Let's learn by example.

Throughout this tutorial, we'll walk you through the creation of a basic
poll application.

It'll consist of two parts:

* A public site that lets people view polls and vote in them.
* An admin site that lets you add, change, and delete polls.

We'll assume you have :doc:`Django installed </intro/install>` already. You can
tell Django is installed and which version by running the following command:

.. code-block:: console

    $ python -m django --version

If Django is installed, you should see the version of your installation. If it
isn't, you'll get an error telling "No module named django".

This tutorial is written for Django |version| and Python 3.4 or later. If the
Django version doesn't match, you can refer to the tutorial for your version
of Django by using the version switcher at the bottom right corner of this
page, or update Django to the newest version. If you are still using Python
2.7, you will need to adjust the code samples slightly, as described in
comments.

See :doc:`How to install Django </topics/install>` for advice on how to remove
older versions of Django and install a newer one.

.. admonition:: Where to get help:

    If you're having trouble going through this tutorial, please post a message
    to |django-users| or drop by `#django on irc.freenode.net
    <irc://irc.freenode.net/django>`_ to chat with other Django users who might
    be able to help.

Creating a project
==================

If this is your first time using Django, you'll have to take care of some
initial setup. Namely, you'll need to auto-generate some code that establishes a
Django :term:`project` -- a collection of settings for an instance of Django,
including database configuration, Django-specific options and
application-specific settings.

From the command line, ``cd`` into a directory where you'd like to store your
code, then run the following command:

.. code-block:: console

   $ django-admin startproject mysite

This will create a ``mysite`` directory in your current directory. If it didn't
work, see :ref:`troubleshooting-django-admin`.

.. note::

    You'll need to avoid naming projects after built-in Python or Django
    components. In particular, this means you should avoid using names like
    ``django`` (which will conflict with Django itself) or ``test`` (which
    conflicts with a built-in Python package).

.. admonition:: Where should this code live?

    If your background is in plain old PHP (with no use of modern frameworks),
    you're probably used to putting code under the Web server's document root
    (in a place such as ``/var/www``). With Django, you don't do that. It's
    not a good idea to put any of this Python code within your Web server's
    document root, because it risks the possibility that people may be able
    to view your code over the Web. That's not good for security.

    Put your code in some directory **outside** of the document root, such as
    :file:`/home/mycode`.

Let's look at what :djadmin:`startproject` created::

    mysite/
        manage.py
        mysite/
            __init__.py
            settings.py
            urls.py
            wsgi.py

These files are:

* The outer :file:`mysite/` root directory is just a container for your
  project. Its name doesn't matter to Django; you can rename it to anything
  you like.

* :file:`manage.py`: A command-line utility that lets you interact with this
  Django project in various ways. You can read all the details about
  :file:`manage.py` in :doc:`/ref/django-admin`.

* The inner :file:`mysite/` directory is the actual Python package for your
  project. Its name is the Python package name you'll need to use to import
  anything inside it (e.g. ``mysite.urls``).

* :file:`mysite/__init__.py`: An empty file that tells Python that this
  directory should be considered a Python package. If you're a Python beginner,
  read :ref:`more about packages <tut-packages>` in the official Python docs.

* :file:`mysite/settings.py`: Settings/configuration for this Django
  project.  :doc:`/topics/settings` will tell you all about how settings
  work.

* :file:`mysite/urls.py`: The URL declarations for this Django project; a
  "table of contents" of your Django-powered site. You can read more about
  URLs in :doc:`/topics/http/urls`.

* :file:`mysite/wsgi.py`: An entry-point for WSGI-compatible web servers to
  serve your project. See :doc:`/howto/deployment/wsgi/index` for more details.

The development server
======================

Let's verify your Django project works. Change into the outer :file:`mysite` directory, if
you haven't already, and run the following commands:

.. code-block:: console

   $ python manage.py runserver

You'll see the following output on the command line:

.. parsed-literal::

    Performing system checks...

    System check identified no issues (0 silenced).

    You have unapplied migrations; your app may not work properly until they are applied.
    Run 'python manage.py migrate' to apply them.

    |today| - 15:50:53
    Django version |version|, using settings 'mysite.settings'
    Starting development server at http://127.0.0.1:8000/
    Quit the server with CONTROL-C.

.. note::
    Ignore the warning about unapplied database migrations for now; we'll deal
    with the database shortly.

You've started the Django development server, a lightweight Web server written
purely in Python. We've included this with Django so you can develop things
rapidly, without having to deal with configuring a production server -- such as
Apache -- until you're ready for production.

Now's a good time to note: **don't** use this server in anything resembling a
production environment. It's intended only for use while developing. (We're in
the business of making Web frameworks, not Web servers.)

Now that the server's running, visit http://127.0.0.1:8000/ with your Web
browser. You'll see a "Welcome to Django" page, in pleasant, light-blue pastel.
It worked!

.. admonition:: Changing the port

    By default, the :djadmin:`runserver` command starts the development server
    on the internal IP at port 8000.

    If you want to change the server's port, pass
    it as a command-line argument. For instance, this command starts the server
    on port 8080:

    .. code-block:: console

        $ python manage.py runserver 8080

    If you want to change the server's IP, pass it along with the port. So to
    listen on all public IPs (useful if you want to show off your work on other
    computers on your network), use:

    .. code-block:: console

        $ python manage.py runserver 0.0.0.0:8000

    Full docs for the development server can be found in the
    :djadmin:`runserver` reference.

.. admonition:: Automatic reloading of :djadmin:`runserver`

    The development server automatically reloads Python code for each request
    as needed. You don't need to restart the server for code changes to take
    effect. However, some actions like adding files don't trigger a restart,
    so you'll have to restart the server in these cases.

Creating the Polls app
======================

Now that your environment -- a "project" -- is set up, you're set to start
doing work.

Each application you write in Django consists of a Python package that follows
a certain convention. Django comes with a utility that automatically generates
the basic directory structure of an app, so you can focus on writing code
rather than creating directories.

.. admonition:: Projects vs. apps

    What's the difference between a project and an app? An app is a Web
    application that does something -- e.g., a Weblog system, a database of
    public records or a simple poll app. A project is a collection of
    configuration and apps for a particular website. A project can contain
    multiple apps. An app can be in multiple projects.

Your apps can live anywhere on your :ref:`Python path <tut-searchpath>`. In
this tutorial, we'll create our poll app right next to your :file:`manage.py`
file so that it can be imported as its own top-level module, rather than a
submodule of ``mysite``.

To create your app, make sure you're in the same directory as :file:`manage.py`
and type this command:

.. code-block:: console

    $ python manage.py startapp polls

That'll create a directory :file:`polls`, which is laid out like this::

    polls/
        __init__.py
        admin.py
        apps.py
        migrations/
            __init__.py
        models.py
        tests.py
        views.py

This directory structure will house the poll application.

Write your first view
=====================

Let's write the first view. Open the file ``polls/views.py``
and put the following Python code in it:

.. snippet::
    :filename: polls/views.py

    from django.http import HttpResponse


    def index(request):
        return HttpResponse("Hello, world. You're at the polls index.")

This is the simplest view possible in Django. To call the view, we need to map
it to a URL - and for this we need a URLconf.

To create a URLconf in the polls directory, create a file called ``urls.py``.
Your app directory should now look like::

    polls/
        __init__.py
        admin.py
        apps.py
        migrations/
            __init__.py
        models.py
        tests.py
        urls.py
        views.py

In the ``polls/urls.py`` file include the following code:

.. snippet::
    :filename: polls/urls.py

    from django.conf.urls import url

    from . import views

    urlpatterns = [
        url(r'^$', views.index, name='index'),
    ]

The next step is to point the root URLconf at the ``polls.urls`` module. In
``mysite/urls.py``, add an import for ``django.conf.urls.include`` and insert
an :func:`~django.conf.urls.include` in the ``urlpatterns`` list, so you have:

.. snippet::
    :filename: mysite/urls.py

    from django.conf.urls import include, url
    from django.contrib import admin

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

The :func:`~django.conf.urls.include` function allows referencing other
URLconfs. Note that the regular expressions for the
:func:`~django.conf.urls.include` function doesn't have a ``$`` (end-of-string
match character) but rather a trailing slash. Whenever Django encounters
:func:`~django.conf.urls.include`, it chops off whatever part of the URL
matched up to that point and sends the remaining string to the included URLconf
for further processing.

The idea behind :func:`~django.conf.urls.include` is to make it easy to
plug-and-play URLs. Since polls are in their own URLconf
(``polls/urls.py``), they can be placed under "/polls/", or under
"/fun_polls/", or under "/content/polls/", or any other path root, and the
app will still work.

.. admonition:: When to use :func:`~django.conf.urls.include()`

    You should always use ``include()`` when you include other URL patterns.
    ``admin.site.urls`` is the only exception to this.

.. admonition:: Doesn't match what you see?

    If you're seeing ``include(admin.site.urls)`` instead of just
    ``admin.site.urls``, you're probably using a version of Django that
    doesn't match this tutorial version.  You'll want to either switch to the
    older tutorial or the newer Django version.

You have now wired an ``index`` view into the URLconf. Lets verify it's
working, run the following command:

.. code-block:: console

   $ python manage.py runserver

Go to http://localhost:8000/polls/ in your browser, and you should see the
text "*Hello, world. You're at the polls index.*", which you defined in the
``index`` view.

The :func:`~django.conf.urls.url` function is passed four arguments, two
required: ``regex`` and ``view``, and two optional: ``kwargs``, and ``name``.
At this point, it's worth reviewing what these arguments are for.

:func:`~django.conf.urls.url` argument: regex
---------------------------------------------

The term "regex" is a commonly used short form meaning "regular expression",
which is a syntax for matching patterns in strings, or in this case, url
patterns. Django starts at the first regular expression and makes its way down
the list,  comparing the requested URL against each regular expression until it
finds one that matches.

Note that these regular expressions do not search GET and POST parameters, or
the domain name. For example, in a request to
``https://www.example.com/myapp/``, the URLconf will look for ``myapp/``. In a
request to ``https://www.example.com/myapp/?page=3``, the URLconf will also
look for ``myapp/``.

If you need help with regular expressions, see `Wikipedia's entry`_ and the
documentation of the :mod:`re` module. Also, the O'Reilly book "Mastering
Regular Expressions" by Jeffrey Friedl is fantastic. In practice, however,
you don't need to be an expert on regular expressions, as you really only need
to know how to capture simple patterns. In fact, complex regexes can have poor
lookup performance, so you probably shouldn't rely on the full power of regexes.

Finally, a performance note: these regular expressions are compiled the first
time the URLconf module is loaded. They're super fast (as long as the lookups
aren't too complex as noted above).

.. _Wikipedia's entry: https://en.wikipedia.org/wiki/Regular_expression

:func:`~django.conf.urls.url` argument: view
--------------------------------------------

When Django finds a regular expression match, Django calls the specified view
function, with an :class:`~django.http.HttpRequest` object as the first
argument and any “captured” values from the regular expression as other
arguments. If the regex uses simple captures, values are passed as positional
arguments; if it uses named captures, values are passed as keyword arguments.
We'll give an example of this in a bit.

:func:`~django.conf.urls.url` argument: kwargs
----------------------------------------------

Arbitrary keyword arguments can be passed in a dictionary to the target view. We
aren't going to use this feature of Django in the tutorial.

:func:`~django.conf.urls.url` argument: name
---------------------------------------------

Naming your URL lets you refer to it unambiguously from elsewhere in Django,
especially from within templates. This powerful feature allows you to make
global changes to the URL patterns of your project while only touching a single
file.

When you're comfortable with the basic request and response flow, read
:doc:`part 2 of this tutorial </intro/tutorial02>` to start working with the
database.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Intro Tutorial02 (`大一小学期/Week_3-Python/exam/2016/docs/intro/tutorial02.txt`)

=====================================
Writing your first Django app, part 2
=====================================

This tutorial begins where :doc:`Tutorial 1 </intro/tutorial01>` left off.
We'll setup the database, create your first model, and get a quick introduction
to Django's automatically-generated admin site.

Database setup
==============

Now, open up :file:`mysite/settings.py`. It's a normal Python module with
module-level variables representing Django settings.

By default, the configuration uses SQLite. If you're new to databases, or
you're just interested in trying Django, this is the easiest choice. SQLite is
included in Python, so you won't need to install anything else to support your
database. When starting your first real project, however, you may want to use a
more robust database like PostgreSQL, to avoid database-switching headaches
down the road.

If you wish to use another database, install the appropriate :ref:`database
bindings <database-installation>` and change the following keys in the
:setting:`DATABASES` ``'default'`` item to match your database connection
settings:

* :setting:`ENGINE <DATABASE-ENGINE>` -- Either
  ``'django.db.backends.sqlite3'``,
  ``'django.db.backends.postgresql'``,
  ``'django.db.backends.mysql'``, or
  ``'django.db.backends.oracle'``. Other backends are :ref:`also available
  <third-party-notes>`.

* :setting:`NAME` -- The name of your database. If you're using SQLite, the
  database will be a file on your computer; in that case, :setting:`NAME`
  should be the full absolute path, including filename, of that file. The
  default value, ``os.path.join(BASE_DIR, 'db.sqlite3')``, will store the file
  in your project directory.

If you are not using SQLite as your database, additional settings such as
:setting:`USER`, :setting:`PASSWORD`, and :setting:`HOST` must be added.
For more details, see the reference documentation for :setting:`DATABASES`.

.. admonition:: For databases other than SQLite

    If you're using a database besides SQLite, make sure you've created a
    database by this point. Do that with "``CREATE DATABASE database_name;``"
    within your database's interactive prompt.

    Also make sure that the database user provided in :file:`mysite/settings.py`
    has "create database" privileges. This allows automatic creation of a
    :ref:`test database <the-test-database>` which will be needed in a later
    tutorial.

    If you're using SQLite, you don't need to create anything beforehand - the
    database file will be created automatically when it is needed.

While you're editing :file:`mysite/settings.py`, set :setting:`TIME_ZONE` to
your time zone.

Also, note the :setting:`INSTALLED_APPS` setting at the top of the file. That
holds the names of all Django applications that are activated in this Django
instance. Apps can be used in multiple projects, and you can package and
distribute them for use by others in their projects.

By default, :setting:`INSTALLED_APPS` contains the following apps, all of which
come with Django:

* :mod:`django.contrib.admin` -- The admin site. You'll use it shortly.

* :mod:`django.contrib.auth` -- An authentication system.

* :mod:`django.contrib.contenttypes` -- A framework for content types.

* :mod:`django.contrib.sessions` -- A session framework.

* :mod:`django.contrib.messages` -- A messaging framework.

* :mod:`django.contrib.staticfiles` -- A framework for managing
  static files.

These applications are included by default as a convenience for the common case.

Some of these applications make use of at least one database table, though,
so we need to create the tables in the database before we can use them. To do
that, run the following command:

.. code-block:: console

    $ python manage.py migrate

The :djadmin:`migrate` command looks at the :setting:`INSTALLED_APPS` setting
and creates any necessary database tables according to the database settings
in your :file:`mysite/settings.py` file and the database migrations shipped
with the app (we'll cover those later). You'll see a message for each
migration it applies. If you're interested, run the command-line client for your
database and type ``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), ``.schema``
(SQLite), or ``SELECT TABLE_NAME FROM USER_TABLES;`` (Oracle) to display the
tables Django created.

.. admonition:: For the minimalists

    Like we said above, the default applications are included for the common
    case, but not everybody needs them. If you don't need any or all of them,
    feel free to comment-out or delete the appropriate line(s) from
    :setting:`INSTALLED_APPS` before running :djadmin:`migrate`. The
    :djadmin:`migrate` command will only run migrations for apps in
    :setting:`INSTALLED_APPS`.

.. _creating-models:

Creating models
===============

Now we'll define your models -- essentially, your database layout, with
additional metadata.

.. admonition:: Philosophy

   A model is the single, definitive source of truth about your data. It contains
   the essential fields and behaviors of the data you're storing. Django follows
   the :ref:`DRY Principle <dry>`. The goal is to define your data model in one
   place and automatically derive things from it.

   This includes the migrations - unlike in Ruby On Rails, for example, migrations
   are entirely derived from your models file, and are essentially just a
   history that Django can roll through to update your database schema to
   match your current models.

In our simple poll app, we'll create two models: ``Question`` and ``Choice``.
A ``Question`` has a question and a publication date. A ``Choice`` has two
fields: the text of the choice and a vote tally. Each ``Choice`` is associated
with a ``Question``.

These concepts are represented by simple Python classes. Edit the
:file:`polls/models.py` file so it looks like this:

.. snippet::
    :filename: polls/models.py

    from django.db import models


    class Question(models.Model):
        question_text = models.CharField(max_length=200)
        pub_date = models.DateTimeField('date published')


    class Choice(models.Model):
        question = models.ForeignKey(Question, on_delete=models.CASCADE)
        choice_text = models.CharField(max_length=200)
        votes = models.IntegerField(default=0)

The code is straightforward. Each model is represented by a class that
subclasses :class:`django.db.models.Model`. Each model has a number of class
variables, each of which represents a database field in the model.

Each field is represented by an instance of a :class:`~django.db.models.Field`
class -- e.g., :class:`~django.db.models.CharField` for character fields and
:class:`~django.db.models.DateTimeField` for datetimes. This tells Django what
type of data each field holds.

The name of each :class:`~django.db.models.Field` instance (e.g.
``question_text`` or ``pub_date``) is the field's name, in machine-friendly
format. You'll use this value in your Python code, and your database will use
it as the column name.

You can use an optional first positional argument to a
:class:`~django.db.models.Field` to designate a human-readable name. That's used
in a couple of introspective parts of Django, and it doubles as documentation.
If this field isn't provided, Django will use the machine-readable name. In this
example, we've only defined a human-readable name for ``Question.pub_date``.
For all other fields in this model, the field's machine-readable name will
suffice as its human-readable name.

Some :class:`~django.db.models.Field` classes have required arguments.
:class:`~django.db.models.CharField`, for example, requires that you give it a
:attr:`~django.db.models.CharField.max_length`. That's used not only in the
database schema, but in validation, as we'll soon see.

A :class:`~django.db.models.Field` can also have various optional arguments; in
this case, we've set the :attr:`~django.db.models.Field.default` value of
``votes`` to 0.

Finally, note a relationship is defined, using
:class:`~django.db.models.ForeignKey`. That tells Django each ``Choice`` is
related to a single ``Question``. Django supports all the common database
relationships: many-to-one, many-to-many, and one-to-one.

Activating models
=================

That small bit of model code gives Django a lot of information. With it, Django
is able to:

* Create a database schema (``CREATE TABLE`` statements) for this app.
* Create a Python database-access API for accessing ``Question`` and ``Choice`` objects.

But first we need to tell our project that the ``polls`` app is installed.

.. admonition:: Philosophy

    Django apps are "pluggable": You can use an app in multiple projects, and
    you can distribute apps, because they don't have to be tied to a given
    Django installation.

Edit the :file:`mysite/settings.py` file again, and change the
:setting:`INSTALLED_APPS` setting to include the string
``'polls.apps.PollsConfig'``. It'll look like this:

.. snippet::
    :filename: mysite/settings.py

    INSTALLED_APPS = [
        'polls.apps.PollsConfig',
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    ]

Now Django knows to include the ``polls`` app. Let's run another command:

.. code-block:: console

    $ python manage.py makemigrations polls

You should see something similar to the following:

.. code-block:: text

    Migrations for 'polls':
      polls/migrations/0001_initial.py:
        - Create model Choice
        - Create model Question
        - Add field question to choice

By running ``makemigrations``, you're telling Django that you've made
some changes to your models (in this case, you've made new ones) and that
you'd like the changes to be stored as a *migration*.

Migrations are how Django stores changes to your models (and thus your
database schema) - they're just files on disk. You can read the migration
for your new model if you like; it's the file
``polls/migrations/0001_initial.py``. Don't worry, you're not expected to read
them every time Django makes one, but they're designed to be human-editable
in case you want to manually tweak how Django changes things.

There's a command that will run the migrations for you and manage your database
schema automatically - that's called :djadmin:`migrate`, and we'll come to it in a
moment - but first, let's see what SQL that migration would run. The
:djadmin:`sqlmigrate` command takes migration names and returns their SQL:

.. code-block:: console

    $ python manage.py sqlmigrate polls 0001

You should see something similar to the following (we've reformatted it for
readability):

.. code-block:: sql

    BEGIN;
    --
    -- Create model Choice
    --
    CREATE TABLE "polls_choice" (
        "id" serial NOT NULL PRIMARY KEY,
        "choice_text" varchar(200) NOT NULL,
        "votes" integer NOT NULL
    );
    --
    -- Create model Question
    --
    CREATE TABLE "polls_question" (
        "id" serial NOT NULL PRIMARY KEY,
        "question_text" varchar(200) NOT NULL,
        "pub_date" timestamp with time zone NOT NULL
    );
    --
    -- Add field question to choice
    --
    ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
    ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
    CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
    ALTER TABLE "polls_choice"
      ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
        FOREIGN KEY ("question_id")
        REFERENCES "polls_question" ("id")
        DEFERRABLE INITIALLY DEFERRED;

    COMMIT;

Note the following:

* The exact output will vary depending on the database you are using. The
  example above is generated for PostgreSQL.

* Table names are automatically generated by combining the name of the app
  (``polls``) and the lowercase name of the model -- ``question`` and
  ``choice``. (You can override this behavior.)

* Primary keys (IDs) are added automatically. (You can override this, too.)

* By convention, Django appends ``"_id"`` to the foreign key field name.
  (Yes, you can override this, as well.)

* The foreign key relationship is made explicit by a ``FOREIGN KEY``
  constraint. Don't worry about the ``DEFERRABLE`` parts; that's just telling
  PostgreSQL to not enforce the foreign key until the end of the transaction.

* It's tailored to the database you're using, so database-specific field types
  such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or ``integer
  primary key autoincrement`` (SQLite) are handled for you automatically. Same
  goes for the quoting of field names -- e.g., using double quotes or
  single quotes.

* The :djadmin:`sqlmigrate` command doesn't actually run the migration on your
  database - it just prints it to the screen so that you can see what SQL
  Django thinks is required. It's useful for checking what Django is going to
  do or if you have database administrators who require SQL scripts for
  changes.

If you're interested, you can also run
:djadmin:`python manage.py check <check>`; this checks for any problems in
your project without making migrations or touching the database.

Now, run :djadmin:`migrate` again to create those model tables in your database:

.. code-block:: console

    $ python manage.py migrate
    Operations to perform:
      Apply all migrations: admin, auth, contenttypes, polls, sessions
    Running migrations:
      Rendering model states... DONE
      Applying polls.0001_initial... OK

The :djadmin:`migrate` command takes all the migrations that haven't been
applied (Django tracks which ones are applied using a special table in your
database called ``django_migrations``) and runs them against your database -
essentially, synchronizing the changes you made to your models with the schema
in the database.

Migrations are very powerful and let you change your models over time, as you
develop your project, without the need to delete your database or tables and
make new ones - it specializes in upgrading your database live, without
losing data. We'll cover them in more depth in a later part of the tutorial,
but for now, remember the three-step guide to making model changes:

* Change your models (in ``models.py``).
* Run :djadmin:`python manage.py makemigrations <makemigrations>` to create
  migrations for those changes
* Run :djadmin:`python manage.py migrate <migrate>` to apply those changes to
  the database.

The reason that there are separate commands to make and apply migrations is
because you'll commit migrations to your version control system and ship them
with your app; they not only make your development easier, they're also
useable by other developers and in production.

Read the :doc:`django-admin documentation </ref/django-admin>` for full
information on what the ``manage.py`` utility can do.

Playing with the API
====================

Now, let's hop into the interactive Python shell and play around with the free
API Django gives you. To invoke the Python shell, use this command:

.. code-block:: console

    $ python manage.py shell

We're using this instead of simply typing "python", because :file:`manage.py`
sets the ``DJANGO_SETTINGS_MODULE`` environment variable, which gives Django
the Python import path to your :file:`mysite/settings.py` file.

.. admonition:: Bypassing manage.py

    If you'd rather not use :file:`manage.py`, no problem. Just set the
    :envvar:`DJANGO_SETTINGS_MODULE` environment variable to
    ``mysite.settings``, start a plain Python shell, and set up Django:

    .. code-block:: pycon

        >>> import django
        >>> django.setup()

    If this raises an :exc:`AttributeError`, you're probably using
    a version of Django that doesn't match this tutorial version. You'll want
    to either switch to the older tutorial or the newer Django version.

    You must run ``python`` from the same directory :file:`manage.py` is in,
    or ensure that directory is on the Python path, so that ``import mysite``
    works.

    For more information on all of this, see the :doc:`django-admin
    documentation </ref/django-admin>`.

Once you're in the shell, explore the :doc:`database API </topics/db/queries>`::

    >>> from polls.models import Question, Choice   # Import the model classes we just wrote.

    # No questions are in the system yet.
    >>> Question.objects.all()
    <QuerySet []>

    # Create a new Question.
    # Support for time zones is enabled in the default settings file, so
    # Django expects a datetime with tzinfo for pub_date. Use timezone.now()
    # instead of datetime.datetime.now() and it will do the right thing.
    >>> from django.utils import timezone
    >>> q = Question(question_text="What's new?", pub_date=timezone.now())

    # Save the object into the database. You have to call save() explicitly.
    >>> q.save()

    # Now it has an ID. Note that this might say "1L" instead of "1", depending
    # on which database you're using. That's no biggie; it just means your
    # database backend prefers to return integers as Python long integer
    # objects.
    >>> q.id
    1

    # Access model field values via Python attributes.
    >>> q.question_text
    "What's new?"
    >>> q.pub_date
    datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

    # Change values by changing the attributes, then calling save().
    >>> q.question_text = "What's up?"
    >>> q.save()

    # objects.all() displays all the questions in the database.
    >>> Question.objects.all()
    <QuerySet [<Question: Question object>]>

Wait a minute. ``<Question: Question object>`` is, utterly, an unhelpful representation
of this object. Let's fix that by editing the ``Question`` model (in the
``polls/models.py`` file) and adding a
:meth:`~django.db.models.Model.__str__` method to both ``Question`` and
``Choice``:

.. snippet::
    :filename: polls/models.py

    from django.db import models
    from django.utils.encoding import python_2_unicode_compatible

    @python_2_unicode_compatible  # only if you need to support Python 2
    class Question(models.Model):
        # ...
        def __str__(self):
            return self.question_text

    @python_2_unicode_compatible  # only if you need to support Python 2
    class Choice(models.Model):
        # ...
        def __str__(self):
            return self.choice_text

It's important to add :meth:`~django.db.models.Model.__str__` methods to your
models, not only for your own convenience when dealing with the interactive
prompt, but also because objects' representations are used throughout Django's
automatically-generated admin.

Note these are normal Python methods. Let's add a custom method, just for
demonstration:

.. snippet::
    :filename: polls/models.py

    import datetime

    from django.db import models
    from django.utils import timezone


    class Question(models.Model):
        # ...
        def was_published_recently(self):
            return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

Note the addition of ``import datetime`` and ``from django.utils import
timezone``, to reference Python's standard :mod:`datetime` module and Django's
time-zone-related utilities in :mod:`django.utils.timezone`, respectively. If
you aren't familiar with time zone handling in Python, you can learn more in
the :doc:`time zone support docs </topics/i18n/timezones>`.

Save these changes and start a new Python interactive shell by running
``python manage.py shell`` again::

    >>> from polls.models import Question, Choice

    # Make sure our __str__() addition worked.
    >>> Question.objects.all()
    <QuerySet [<Question: What's up?>]>

    # Django provides a rich database lookup API that's entirely driven by
    # keyword arguments.
    >>> Question.objects.filter(id=1)
    <QuerySet [<Question: What's up?>]>
    >>> Question.objects.filter(question_text__startswith='What')
    <QuerySet [<Question: What's up?>]>

    # Get the question that was published this year.
    >>> from django.utils import timezone
    >>> current_year = timezone.now().year
    >>> Question.objects.get(pub_date__year=current_year)
    <Question: What's up?>

    # Request an ID that doesn't exist, this will raise an exception.
    >>> Question.objects.get(id=2)
    Traceback (most recent call last):
        ...
    DoesNotExist: Question matching query does not exist.

    # Lookup by a primary key is the most common case, so Django provides a
    # shortcut for primary-key exact lookups.
    # The following is identical to Question.objects.get(id=1).
    >>> Question.objects.get(pk=1)
    <Question: What's up?>

    # Make sure our custom method worked.
    >>> q = Question.objects.get(pk=1)
    >>> q.was_published_recently()
    True

    # Give the Question a couple of Choices. The create call constructs a new
    # Choice object, does the INSERT statement, adds the choice to the set
    # of available choices and returns the new Choice object. Django creates
    # a set to hold the "other side" of a ForeignKey relation
    # (e.g. a question's choice) which can be accessed via the API.
    >>> q = Question.objects.get(pk=1)

    # Display any choices from the related object set -- none so far.
    >>> q.choice_set.all()
    <QuerySet []>

    # Create three choices.
    >>> q.choice_set.create(choice_text='Not much', votes=0)
    <Choice: Not much>
    >>> q.choice_set.create(choice_text='The sky', votes=0)
    <Choice: The sky>
    >>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)

    # Choice objects have API access to their related Question objects.
    >>> c.question
    <Question: What's up?>

    # And vice versa: Question objects get access to Choice objects.
    >>> q.choice_set.all()
    <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
    >>> q.choice_set.count()
    3

    # The API automatically follows relationships as far as you need.
    # Use double underscores to separate relationships.
    # This works as many levels deep as you want; there's no limit.
    # Find all Choices for any question whose pub_date is in this year
    # (reusing the 'current_year' variable we created above).
    >>> Choice.objects.filter(question__pub_date__year=current_year)
    <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

    # Let's delete one of the choices. Use delete() for that.
    >>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
    >>> c.delete()

For more information on model relations, see :doc:`Accessing related objects
</ref/models/relations>`. For more on how to use double underscores to perform
field lookups via the API, see :ref:`Field lookups <field-lookups-intro>`. For
full details on the database API, see our :doc:`Database API reference
</topics/db/queries>`.

Introducing the Django Admin
============================

.. admonition:: Philosophy

    Generating admin sites for your staff or clients to add, change, and delete
    content is tedious work that doesn't require much creativity. For that
    reason, Django entirely automates creation of admin interfaces for models.

    Django was written in a newsroom environment, with a very clear separation
    between "content publishers" and the "public" site. Site managers use the
    system to add news stories, events, sports scores, etc., and that content is
    displayed on the public site. Django solves the problem of creating a
    unified interface for site administrators to edit content.

    The admin isn't intended to be used by site visitors. It's for site
    managers.

Creating an admin user
----------------------

First we'll need to create a user who can login to the admin site. Run the
following command:

.. code-block:: console

    $ python manage.py createsuperuser

Enter your desired username and press enter.

.. code-block:: text

    Username: admin

You will then be prompted for your desired email address:

.. code-block:: text

    Email address: admin@example.com

The final step is to enter your password. You will be asked to enter your
password twice, the second time as a confirmation of the first.

.. code-block:: text

    Password: **********
    Password (again): *********
    Superuser created successfully.

Start the development server
----------------------------

The Django admin site is activated by default. Let's start the development
server and explore it.

If the server is not running start it like so:

.. code-block:: console

    $ python manage.py runserver

Now, open a Web browser and go to "/admin/" on your local domain -- e.g.,
http://127.0.0.1:8000/admin/. You should see the admin's login screen:

.. image:: _images/admin01.png
   :alt: Django admin login screen

Since :doc:`translation </topics/i18n/translation>` is turned on by default,
the login screen may be displayed in your own language, depending on your
browser's settings and if Django has a translation for this language.

Enter the admin site
--------------------

Now, try logging in with the superuser account you created in the previous step.
You should see the Django admin index page:

.. image:: _images/admin02.png
   :alt: Django admin index page

You should see a few types of editable content: groups and users. They are
provided by :mod:`django.contrib.auth`, the authentication framework shipped
by Django.

Make the poll app modifiable in the admin
-----------------------------------------

But where's our poll app? It's not displayed on the admin index page.

Just one thing to do: we need to tell the admin that ``Question``
objects have an admin interface. To do this, open the :file:`polls/admin.py`
file, and edit it to look like this:

.. snippet::
    :filename: polls/admin.py

    from django.contrib import admin

    from .models import Question

    admin.site.register(Question)

Explore the free admin functionality
------------------------------------

Now that we've registered ``Question``, Django knows that it should be displayed on
the admin index page:

.. image:: _images/admin03t.png
   :alt: Django admin index page, now with polls displayed

Click "Questions". Now you're at the "change list" page for questions. This page
displays all the questions in the database and lets you choose one to change it.
There's the "What's up?" question we created earlier:

.. image:: _images/admin04t.png
   :alt: Polls change list page

Click the "What's up?" question to edit it:

.. image:: _images/admin05t.png
   :alt: Editing form for question object

Things to note here:

* The form is automatically generated from the ``Question`` model.

* The different model field types (:class:`~django.db.models.DateTimeField`,
  :class:`~django.db.models.CharField`) correspond to the appropriate HTML
  input widget. Each type of field knows how to display itself in the Django
  admin.

* Each :class:`~django.db.models.DateTimeField` gets free JavaScript
  shortcuts. Dates get a "Today" shortcut and calendar popup, and times get
  a "Now" shortcut and a convenient popup that lists commonly entered times.

The bottom part of the page gives you a couple of options:

* Save -- Saves changes and returns to the change-list page for this type of
  object.

* Save and continue editing -- Saves changes and reloads the admin page for
  this object.

* Save and add another -- Saves changes and loads a new, blank form for this
  type of object.

* Delete -- Displays a delete confirmation page.

If the value of "Date published" doesn't match the time when you created the
question in :doc:`Tutorial 1</intro/tutorial01>`, it probably
means you forgot to set the correct value for the :setting:`TIME_ZONE` setting.
Change it, reload the page and check that the correct value appears.

Change the "Date published" by clicking the "Today" and "Now" shortcuts. Then
click "Save and continue editing." Then click "History" in the upper right.
You'll see a page listing all changes made to this object via the Django admin,
with the timestamp and username of the person who made the change:

.. image:: _images/admin06t.png
   :alt: History page for question object

When you're comfortable with the models API and have familiarized yourself with
the admin site, read :doc:`part 3 of this tutorial</intro/tutorial03>` to learn
about how to add more views to our polls app.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Intro Tutorial03 (`大一小学期/Week_3-Python/exam/2016/docs/intro/tutorial03.txt`)

=====================================
Writing your first Django app, part 3
=====================================

This tutorial begins where :doc:`Tutorial 2 </intro/tutorial02>` left off. We're
continuing the Web-poll application and will focus on creating the public
interface -- "views."

Overview
========

A view is a "type" of Web page in your Django application that generally serves
a specific function and has a specific template. For example, in a blog
application, you might have the following views:

* Blog homepage -- displays the latest few entries.

* Entry "detail" page -- permalink page for a single entry.

* Year-based archive page -- displays all months with entries in the
  given year.

* Month-based archive page -- displays all days with entries in the
  given month.

* Day-based archive page -- displays all entries in the given day.

* Comment action -- handles posting comments to a given entry.

In our poll application, we'll have the following four views:

* Question "index" page -- displays the latest few questions.

* Question "detail" page -- displays a question text, with no results but
  with a form to vote.

* Question "results" page -- displays results for a particular question.

* Vote action -- handles voting for a particular choice in a particular
  question.

In Django, web pages and other content are delivered by views. Each view is
represented by a simple Python function (or method, in the case of class-based
views). Django will choose a view by examining the URL that's requested (to be
precise, the part of the URL after the domain name).

Now in your time on the web you may have come across such beauties as
"ME2/Sites/dirmod.asp?sid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B".
You will be pleased to know that Django allows us much more elegant
*URL patterns* than that.

A URL pattern is simply the general form of a URL - for example:
``/newsarchive/<year>/<month>/``.

To get from a URL to a view, Django uses what are known as 'URLconfs'. A
URLconf maps URL patterns (described as regular expressions) to views.

This tutorial provides basic instruction in the use of URLconfs, and you can
refer to :mod:`django.urls` for more information.

Writing more views
==================

Now let's add a few more views to ``polls/views.py``. These views are
slightly different, because they take an argument:

.. snippet::
    :filename: polls/views.py

    def detail(request, question_id):
        return HttpResponse("You're looking at question %s." % question_id)

    def results(request, question_id):
        response = "You're looking at the results of question %s."
        return HttpResponse(response % question_id)

    def vote(request, question_id):
        return HttpResponse("You're voting on question %s." % question_id)

Wire these new views into the ``polls.urls`` module by adding the following
:func:`~django.conf.urls.url` calls:

.. snippet::
    :filename: polls/urls.py

    from django.conf.urls import url

    from . import views

    urlpatterns = [
        # ex: /polls/
        url(r'^$', views.index, name='index'),
        # ex: /polls/5/
        url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
        # ex: /polls/5/results/
        url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
        # ex: /polls/5/vote/
        url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
    ]

Take a look in your browser, at "/polls/34/". It'll run the ``detail()``
method and display whatever ID you provide in the URL. Try
"/polls/34/results/" and "/polls/34/vote/" too -- these will display the
placeholder results and voting pages.

When somebody requests a page from your website -- say, "/polls/34/", Django
will load the ``mysite.urls`` Python module because it's pointed to by the
:setting:`ROOT_URLCONF` setting. It finds the variable named ``urlpatterns``
and traverses the regular expressions in order. After finding the match at
``'^polls/'``, it strips off the matching text (``"polls/"``) and sends the
remaining text -- ``"34/"`` -- to the 'polls.urls' URLconf for further
processing. There it matches ``r'^(?P<question_id>[0-9]+)/$'``, resulting in a
call to the ``detail()`` view like so::

    detail(request=<HttpRequest object>, question_id='34')

The ``question_id='34'`` part comes from ``(?P<question_id>[0-9]+)``. Using parentheses
around a pattern "captures" the text matched by that pattern and sends it as an
argument to the view function; ``?P<question_id>`` defines the name that will
be used to identify the matched pattern; and ``[0-9]+`` is a regular expression to
match a sequence of digits (i.e., a number).

Because the URL patterns are regular expressions, there really is no limit on
what you can do with them. And there's no need to add URL cruft such as
``.html`` -- unless you want to, in which case you can do something like
this::

    url(r'^polls/latest\.html$', views.index),

But, don't do that. It's silly.

Write views that actually do something
======================================

Each view is responsible for doing one of two things: returning an
:class:`~django.http.HttpResponse` object containing the content for the
requested page, or raising an exception such as :exc:`~django.http.Http404`. The
rest is up to you.

Your view can read records from a database, or not. It can use a template
system such as Django's -- or a third-party Python template system -- or not.
It can generate a PDF file, output XML, create a ZIP file on the fly, anything
you want, using whatever Python libraries you want.

All Django wants is that :class:`~django.http.HttpResponse`. Or an exception.

Because it's convenient, let's use Django's own database API, which we covered
in :doc:`Tutorial 2 </intro/tutorial02>`. Here's one stab at a new ``index()``
view, which displays the latest 5 poll questions in the system, separated by
commas, according to publication date:

.. snippet::
    :filename: polls/views.py

    from django.http import HttpResponse

    from .models import Question


    def index(request):
        latest_question_list = Question.objects.order_by('-pub_date')[:5]
        output = ', '.join([q.question_text for q in latest_question_list])
        return HttpResponse(output)

    # Leave the rest of the views (detail, results, vote) unchanged

There's a problem here, though: the page's design is hard-coded in the view. If
you want to change the way the page looks, you'll have to edit this Python code.
So let's use Django's template system to separate the design from Python by
creating a template that the view can use.

First, create a directory called ``templates`` in your ``polls`` directory.
Django will look for templates in there.

Your project's :setting:`TEMPLATES` setting describes how Django will load and
render templates. The default settings file configures a ``DjangoTemplates``
backend whose :setting:`APP_DIRS <TEMPLATES-APP_DIRS>` option is set to
``True``. By convention ``DjangoTemplates`` looks for a "templates"
subdirectory in each of the :setting:`INSTALLED_APPS`.

Within the ``templates`` directory you have just created, create another
directory called ``polls``, and within that create a file called
``index.html``. In other words, your template should be at
``polls/templates/polls/index.html``. Because of how the ``app_directories``
template loader works as described above, you can refer to this template within
Django simply as ``polls/index.html``.

.. admonition:: Template namespacing

    Now we *might* be able to get away with putting our templates directly in
    ``polls/templates`` (rather than creating another ``polls`` subdirectory),
    but it would actually be a bad idea. Django will choose the first template
    it finds whose name matches, and if you had a template with the same name
    in a *different* application, Django would be unable to distinguish between
    them. We need to be able to point Django at the right one, and the easiest
    way to ensure this is by *namespacing* them. That is, by putting those
    templates inside *another* directory named for the application itself.

Put the following code in that template:

.. snippet:: html+django
    :filename: polls/templates/polls/index.html

    {% if latest_question_list %}
        <ul>
        {% for question in latest_question_list %}
            <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
        {% endfor %}
        </ul>
    {% else %}
        <p>No polls are available.</p>
    {% endif %}

Now let's update our ``index`` view in ``polls/views.py`` to use the template:

.. snippet::
    :filename: polls/views.py

    from django.http import HttpResponse
    from django.template import loader

    from .models import Question


    def index(request):
        latest_question_list = Question.objects.order_by('-pub_date')[:5]
        template = loader.get_template('polls/index.html')
        context = {
            'latest_question_list': latest_question_list,
        }
        return HttpResponse(template.render(context, request))

That code loads the template called  ``polls/index.html`` and passes it a
context. The context is a dictionary mapping template variable names to Python
objects.

Load the page by pointing your browser at "/polls/", and you should see a
bulleted-list containing the "What's up" question from :doc:`Tutorial 2
</intro/tutorial02>`. The link points to the question's detail page.

A shortcut: :func:`~django.shortcuts.render`
--------------------------------------------

It's a very common idiom to load a template, fill a context and return an
:class:`~django.http.HttpResponse` object with the result of the rendered
template. Django provides a shortcut. Here's the full ``index()`` view,
rewritten:

.. snippet::
    :filename: polls/views.py

    from django.shortcuts import render

    from .models import Question


    def index(request):
        latest_question_list = Question.objects.order_by('-pub_date')[:5]
        context = {'latest_question_list': latest_question_list}
        return render(request, 'polls/index.html', context)

Note that once we've done this in all these views, we no longer need to import
:mod:`~django.template.loader` and :class:`~django.http.HttpResponse` (you'll
want to keep ``HttpResponse`` if you still have the stub methods for ``detail``,
``results``, and ``vote``).

The :func:`~django.shortcuts.render` function takes the request object as its
first argument, a template name as its second argument and a dictionary as its
optional third argument. It returns an :class:`~django.http.HttpResponse`
object of the given template rendered with the given context.

Raising a 404 error
===================

Now, let's tackle the question detail view -- the page that displays the question text
for a given poll. Here's the view:

.. snippet::
    :filename: polls/views.py

    from django.http import Http404
    from django.shortcuts import render

    from .models import Question
    # ...
    def detail(request, question_id):
        try:
            question = Question.objects.get(pk=question_id)
        except Question.DoesNotExist:
            raise Http404("Question does not exist")
        return render(request, 'polls/detail.html', {'question': question})

The new concept here: The view raises the :exc:`~django.http.Http404` exception
if a question with the requested ID doesn't exist.

We'll discuss what you could put in that ``polls/detail.html`` template a bit
later, but if you'd like to quickly get the above example working, a file
containing just:

.. snippet:: html+django
    :filename: polls/templates/polls/detail.html

    {{ question }}

will get you started for now.

A shortcut: :func:`~django.shortcuts.get_object_or_404`
-------------------------------------------------------

It's a very common idiom to use :meth:`~django.db.models.query.QuerySet.get`
and raise :exc:`~django.http.Http404` if the object doesn't exist. Django
provides a shortcut. Here's the ``detail()`` view, rewritten:

.. snippet::
    :filename: polls/views.py

    from django.shortcuts import get_object_or_404, render

    from .models import Question
    # ...
    def detail(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        return render(request, 'polls/detail.html', {'question': question})

The :func:`~django.shortcuts.get_object_or_404` function takes a Django model
as its first argument and an arbitrary number of keyword arguments, which it
passes to the :meth:`~django.db.models.query.QuerySet.get` function of the
model's manager. It raises :exc:`~django.http.Http404` if the object doesn't
exist.

.. admonition:: Philosophy

    Why do we use a helper function :func:`~django.shortcuts.get_object_or_404`
    instead of automatically catching the
    :exc:`~django.core.exceptions.ObjectDoesNotExist` exceptions at a higher
    level, or having the model API raise :exc:`~django.http.Http404` instead of
    :exc:`~django.core.exceptions.ObjectDoesNotExist`?

    Because that would couple the model layer to the view layer. One of the
    foremost design goals of Django is to maintain loose coupling. Some
    controlled coupling is introduced in the :mod:`django.shortcuts` module.

There's also a :func:`~django.shortcuts.get_list_or_404` function, which works
just as :func:`~django.shortcuts.get_object_or_404` -- except using
:meth:`~django.db.models.query.QuerySet.filter` instead of
:meth:`~django.db.models.query.QuerySet.get`. It raises
:exc:`~django.http.Http404` if the list is empty.

Use the template system
=======================

Back to the ``detail()`` view for our poll application. Given the context
variable ``question``, here's what the ``polls/detail.html`` template might look
like:

.. snippet:: html+django
    :filename: polls/templates/polls/detail.html

    <h1>{{ question.question_text }}</h1>
    <ul>
    {% for choice in question.choice_set.all %}
        <li>{{ choice.choice_text }}</li>
    {% endfor %}
    </ul>

The template system uses dot-lookup syntax to access variable attributes. In
the example of ``{{ question.question_text }}``, first Django does a dictionary lookup
on the object ``question``. Failing that, it tries an attribute lookup -- which
works, in this case. If attribute lookup had failed, it would've tried a
list-index lookup.

Method-calling happens in the :ttag:`{% for %}<for>` loop:
``question.choice_set.all`` is interpreted as the Python code
``question.choice_set.all()``, which returns an iterable of ``Choice`` objects and is
suitable for use in the :ttag:`{% for %}<for>` tag.

See the :doc:`template guide </topics/templates>` for more about templates.

Removing hardcoded URLs in templates
====================================

Remember, when we wrote the link to a question in the ``polls/index.html``
template, the link was partially hardcoded like this:

.. code-block:: html+django

    <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

The problem with this hardcoded, tightly-coupled approach is that it becomes
challenging to change URLs on projects with a lot of templates. However, since
you defined the name argument in the :func:`~django.conf.urls.url` functions in
the ``polls.urls`` module, you can remove a reliance on specific URL paths
defined in your url configurations by using the ``{% url %}`` template tag:

.. code-block:: html+django

    <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

The way this works is by looking up the URL definition as specified in the
``polls.urls`` module. You can see exactly where the URL name of 'detail' is
defined below::

    ...
    # the 'name' value as called by the {% url %} template tag
    url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
    ...

If you want to change the URL of the polls detail view to something else,
perhaps to something like ``polls/specifics/12/`` instead of doing it in the
template (or templates) you would change it in ``polls/urls.py``::

    ...
    # added the word 'specifics'
    url(r'^specifics/(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
    ...

Namespacing URL names
======================

The tutorial project has just one app, ``polls``. In real Django projects,
there might be five, ten, twenty apps or more. How does Django differentiate
the URL names between them? For example, the ``polls`` app has a ``detail``
view, and so might an app on the same project that is for a blog. How does one
make it so that Django knows which app view to create for a url when using the
``{% url %}`` template tag?

The answer is to add namespaces to your  URLconf. In the ``polls/urls.py``
file, go ahead and add an ``app_name`` to set the application namespace:

.. snippet::
    :filename: polls/urls.py

    from django.conf.urls import url

    from . import views

    app_name = 'polls'
    urlpatterns = [
        url(r'^$', views.index, name='index'),
        url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
        url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
        url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
    ]

Now change your ``polls/index.html`` template from:

.. snippet:: html+django
    :filename: polls/templates/polls/index.html

    <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

to point at the namespaced detail view:

.. snippet:: html+django
    :filename: polls/templates/polls/index.html

    <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

When you're comfortable with writing views, read :doc:`part 4 of this tutorial
</intro/tutorial04>` to learn about simple form processing and generic views.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Intro Tutorial04 (`大一小学期/Week_3-Python/exam/2016/docs/intro/tutorial04.txt`)

=====================================
Writing your first Django app, part 4
=====================================

This tutorial begins where :doc:`Tutorial 3 </intro/tutorial03>` left off. We're
continuing the Web-poll application and will focus on simple form processing and
cutting down our code.

Write a simple form
===================

Let's update our poll detail template ("polls/detail.html") from the last
tutorial, so that the template contains an HTML ``<form>`` element:

.. snippet:: html+django
    :filename: polls/templates/polls/detail.html

    <h1>{{ question.question_text }}</h1>

    {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

    <form action="{% url 'polls:vote' question.id %}" method="post">
    {% csrf_token %}
    {% for choice in question.choice_set.all %}
        <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
        <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
    {% endfor %}
    <input type="submit" value="Vote" />
    </form>

A quick rundown:

* The above template displays a radio button for each question choice. The
  ``value`` of each radio button is the associated question choice's ID. The
  ``name`` of each radio button is ``"choice"``. That means, when somebody
  selects one of the radio buttons and submits the form, it'll send the
  POST data ``choice=#`` where # is the ID of the selected choice. This is the
  basic concept of HTML forms.

* We set the form's ``action`` to ``{% url 'polls:vote' question.id %}``, and we
  set ``method="post"``. Using ``method="post"`` (as opposed to
  ``method="get"``) is very important, because the act of submitting this
  form will alter data server-side. Whenever you create a form that alters
  data server-side, use ``method="post"``. This tip isn't specific to
  Django; it's just good Web development practice.

* ``forloop.counter`` indicates how many times the :ttag:`for` tag has gone
  through its loop

* Since we're creating a POST form (which can have the effect of modifying
  data), we need to worry about Cross Site Request Forgeries.
  Thankfully, you don't have to worry too hard, because Django comes with
  a very easy-to-use system for protecting against it. In short, all POST
  forms that are targeted at internal URLs should use the
  :ttag:`{% csrf_token %}<csrf_token>` template tag.

Now, let's create a Django view that handles the submitted data and does
something with it. Remember, in :doc:`Tutorial 3 </intro/tutorial03>`, we
created a URLconf for the polls application that includes this line:

.. snippet::
    :filename: polls/urls.py

    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),

We also created a dummy implementation of the ``vote()`` function. Let's
create a real version. Add the following to ``polls/views.py``:

.. snippet::
    :filename: polls/views.py

    from django.shortcuts import get_object_or_404, render
    from django.http import HttpResponseRedirect, HttpResponse
    from django.urls import reverse

    from .models import Choice, Question
    # ...
    def vote(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        try:
            selected_choice = question.choice_set.get(pk=request.POST['choice'])
        except (KeyError, Choice.DoesNotExist):
            # Redisplay the question voting form.
            return render(request, 'polls/detail.html', {
                'question': question,
                'error_message': "You didn't select a choice.",
            })
        else:
            selected_choice.votes += 1
            selected_choice.save()
            # Always return an HttpResponseRedirect after successfully dealing
            # with POST data. This prevents data from being posted twice if a
            # user hits the Back button.
            return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

This code includes a few things we haven't covered yet in this tutorial:

* :attr:`request.POST <django.http.HttpRequest.POST>` is a dictionary-like
  object that lets you access submitted data by key name. In this case,
  ``request.POST['choice']`` returns the ID of the selected choice, as a
  string. :attr:`request.POST <django.http.HttpRequest.POST>` values are
  always strings.

  Note that Django also provides :attr:`request.GET
  <django.http.HttpRequest.GET>` for accessing GET data in the same way --
  but we're explicitly using :attr:`request.POST
  <django.http.HttpRequest.POST>` in our code, to ensure that data is only
  altered via a POST call.

* ``request.POST['choice']`` will raise :exc:`KeyError` if
  ``choice`` wasn't provided in POST data. The above code checks for
  :exc:`KeyError` and redisplays the question form with an error
  message if ``choice`` isn't given.

* After incrementing the choice count, the code returns an
  :class:`~django.http.HttpResponseRedirect` rather than a normal
  :class:`~django.http.HttpResponse`.
  :class:`~django.http.HttpResponseRedirect` takes a single argument: the
  URL to which the user will be redirected (see the following point for how
  we construct the URL in this case).

  As the Python comment above points out, you should always return an
  :class:`~django.http.HttpResponseRedirect` after successfully dealing with
  POST data. This tip isn't specific to Django; it's just good Web
  development practice.

* We are using the :func:`~django.urls.reverse` function in the
  :class:`~django.http.HttpResponseRedirect` constructor in this example.
  This function helps avoid having to hardcode a URL in the view function.
  It is given the name of the view that we want to pass control to and the
  variable portion of the URL pattern that points to that view. In this
  case, using the URLconf we set up in :doc:`Tutorial 3 </intro/tutorial03>`,
  this :func:`~django.urls.reverse` call will return a string like
  ::

    '/polls/3/results/'

  where the ``3`` is the value of ``question.id``. This redirected URL will
  then call the ``'results'`` view to display the final page.

As mentioned in :doc:`Tutorial 3 </intro/tutorial03>`, ``request`` is an
:class:`~django.http.HttpRequest` object. For more on
:class:`~django.http.HttpRequest` objects, see the :doc:`request and
response documentation </ref/request-response>`.

After somebody votes in a question, the ``vote()`` view redirects to the results
page for the question. Let's write that view:

.. snippet::
    :filename: polls/views.py

    from django.shortcuts import get_object_or_404, render


    def results(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        return render(request, 'polls/results.html', {'question': question})

This is almost exactly the same as the ``detail()`` view from :doc:`Tutorial 3
</intro/tutorial03>`. The only difference is the template name. We'll fix this
redundancy later.

Now, create a ``polls/results.html`` template:

.. snippet:: html+django
    :filename: polls/templates/polls/results.html

    <h1>{{ question.question_text }}</h1>

    <ul>
    {% for choice in question.choice_set.all %}
        <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
    {% endfor %}
    </ul>

    <a href="{% url 'polls:detail' question.id %}">Vote again?</a>

Now, go to ``/polls/1/`` in your browser and vote in the question. You should see a
results page that gets updated each time you vote. If you submit the form
without having chosen a choice, you should see the error message.

.. note::
    The code for our ``vote()`` view does have a small problem. It first gets
    the ``selected_choice`` object from the database, then computes the new
    value of ``votes``, and then saves it back to the database. If two users of
    your website try to vote at *exactly the same time*, this might go wrong:
    The same value, let's say 42, will be retrieved for ``votes``. Then, for
    both users the new value of 43 is computed and saved, but 44 would be the
    expected value.

    This is called a *race condition*. If you are interested, you can read
    :ref:`avoiding-race-conditions-using-f` to learn how you can solve this
    issue.

Use generic views: Less code is better
======================================

The ``detail()`` (from :doc:`Tutorial 3 </intro/tutorial03>`) and ``results()``
views are very simple -- and, as mentioned above, redundant. The ``index()``
view, which displays a list of polls, is similar.

These views represent a common case of basic Web development: getting data from
the database according to a parameter passed in the URL, loading a template and
returning the rendered template. Because this is so common, Django provides a
shortcut, called the "generic views" system.

Generic views abstract common patterns to the point where you don't even need
to write Python code to write an app.

Let's convert our poll app to use the generic views system, so we can delete a
bunch of our own code. We'll just have to take a few steps to make the
conversion. We will:

1. Convert the URLconf.

2. Delete some of the old, unneeded views.

3. Introduce new views based on Django's generic views.

Read on for details.

.. admonition:: Why the code-shuffle?

    Generally, when writing a Django app, you'll evaluate whether generic views
    are a good fit for your problem, and you'll use them from the beginning,
    rather than refactoring your code halfway through. But this tutorial
    intentionally has focused on writing the views "the hard way" until now, to
    focus on core concepts.

    You should know basic math before you start using a calculator.

Amend URLconf
-------------

First, open the ``polls/urls.py`` URLconf and change it like so:

.. snippet::
    :filename: polls/urls.py

    from django.conf.urls import url

    from . import views

    app_name = 'polls'
    urlpatterns = [
        url(r'^$', views.IndexView.as_view(), name='index'),
        url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
        url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
        url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
    ]

Note that the name of the matched pattern in the regexes of the second and third
patterns has changed from ``<question_id>`` to ``<pk>``.

Amend views
-----------

Next, we're going to remove our old ``index``, ``detail``, and ``results``
views and use Django's generic views instead. To do so, open the
``polls/views.py`` file and change it like so:

.. snippet::
    :filename: polls/views.py

    from django.shortcuts import get_object_or_404, render
    from django.http import HttpResponseRedirect
    from django.urls import reverse
    from django.views import generic

    from .models import Choice, Question


    class IndexView(generic.ListView):
        template_name = 'polls/index.html'
        context_object_name = 'latest_question_list'

        def get_queryset(self):
            """Return the last five published questions."""
            return Question.objects.order_by('-pub_date')[:5]


    class DetailView(generic.DetailView):
        model = Question
        template_name = 'polls/detail.html'


    class ResultsView(generic.DetailView):
        model = Question
        template_name = 'polls/results.html'


    def vote(request, question_id):
        ... # same as above, no changes needed.

We're using two generic views here:
:class:`~django.views.generic.list.ListView` and
:class:`~django.views.generic.detail.DetailView`. Respectively, those
two views abstract the concepts of "display a list of objects" and
"display a detail page for a particular type of object."

* Each generic view needs to know what model it will be acting
  upon. This is provided using the ``model`` attribute.

* The :class:`~django.views.generic.detail.DetailView` generic view
  expects the primary key value captured from the URL to be called
  ``"pk"``, so we've changed ``question_id`` to ``pk`` for the generic
  views.

By default, the :class:`~django.views.generic.detail.DetailView` generic
view uses a template called ``<app name>/<model name>_detail.html``.
In our case, it would use the template ``"polls/question_detail.html"``. The
``template_name`` attribute is used to tell Django to use a specific
template name instead of the autogenerated default template name. We
also specify the ``template_name`` for the ``results`` list view --
this ensures that the results view and the detail view have a
different appearance when rendered, even though they're both a
:class:`~django.views.generic.detail.DetailView` behind the scenes.

Similarly, the :class:`~django.views.generic.list.ListView` generic
view uses a default template called ``<app name>/<model
name>_list.html``; we use ``template_name`` to tell
:class:`~django.views.generic.list.ListView` to use our existing
``"polls/index.html"`` template.

In previous parts of the tutorial, the templates have been provided
with a context that contains the ``question`` and ``latest_question_list``
context variables. For ``DetailView`` the ``question`` variable is provided
automatically -- since we're using a Django model (``Question``), Django
is able to determine an appropriate name for the context variable.
However, for ListView, the automatically generated context variable is
``question_list``. To override this we provide the ``context_object_name``
attribute, specifying that we want to use ``latest_question_list`` instead.
As an alternative approach, you could change your templates to match
the new default context variables -- but it's a lot easier to just
tell Django to use the variable you want.

Run the server, and use your new polling app based on generic views.

For full details on generic views, see the :doc:`generic views documentation
</topics/class-based-views/index>`.

When you're comfortable with forms and generic views, read :doc:`part 5 of this
tutorial</intro/tutorial05>` to learn about testing our polls app.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Intro Tutorial05 (`大一小学期/Week_3-Python/exam/2016/docs/intro/tutorial05.txt`)

=====================================
Writing your first Django app, part 5
=====================================

This tutorial begins where :doc:`Tutorial 4 </intro/tutorial04>` left off.
We've built a Web-poll application, and we'll now create some automated tests
for it.

Introducing automated testing
=============================

What are automated tests?
-------------------------

Tests are simple routines that check the operation of your code.

Testing operates at different levels. Some tests might apply to a tiny detail
(*does a particular model method return values as expected?*) while others
examine the overall operation of the software (*does a sequence of user inputs
on the site produce the desired result?*). That's no different from the kind of
testing you did earlier in :doc:`Tutorial 2 </intro/tutorial02>`, using the
:djadmin:`shell` to examine the behavior of a method, or running the
application and entering data to check how it behaves.

What's different in *automated* tests is that the testing work is done for
you by the system. You create a set of tests once, and then as you make changes
to your app, you can check that your code still works as you originally
intended, without having to perform time consuming manual testing.

Why you need to create tests
----------------------------

So why create tests, and why now?

You may feel that you have quite enough on your plate just learning
Python/Django, and having yet another thing to learn and do may seem
overwhelming and perhaps unnecessary. After all, our polls application is
working quite happily now; going through the trouble of creating automated
tests is not going to make it work any better. If creating the polls
application is the last bit of Django programming you will ever do, then true,
you don't need to know how to create automated tests. But, if that's not the
case, now is an excellent time to learn.

Tests will save you time
~~~~~~~~~~~~~~~~~~~~~~~~

Up to a certain point, 'checking that it seems to work' will be a satisfactory
test. In a more sophisticated application, you might have dozens of complex
interactions between components.

A change in any of those components could have unexpected consequences on the
application's behavior. Checking that it still 'seems to work' could mean
running through your code's functionality with twenty different variations of
your test data just to make sure you haven't broken something - not a good use
of your time.

That's especially true when automated tests could do this for you in seconds.
If something's gone wrong, tests will also assist in identifying the code
that's causing the unexpected behavior.

Sometimes it may seem a chore to tear yourself away from your productive,
creative programming work to face the unglamorous and unexciting business
of writing tests, particularly when you know your code is working properly.

However, the task of writing tests is a lot more fulfilling than spending hours
testing your application manually or trying to identify the cause of a
newly-introduced problem.

Tests don't just identify problems, they prevent them
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It's a mistake to think of tests merely as a negative aspect of development.

Without tests, the purpose or intended behavior of an application might be
rather opaque. Even when it's your own code, you will sometimes find yourself
poking around in it trying to find out what exactly it's doing.

Tests change that; they light up your code from the inside, and when something
goes wrong, they focus light on the part that has gone wrong - *even if you
hadn't even realized it had gone wrong*.

Tests make your code more attractive
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You might have created a brilliant piece of software, but you will find that
many other developers will simply refuse to look at it because it lacks tests;
without tests, they won't trust it. Jacob Kaplan-Moss, one of Django's
original developers, says "Code without tests is broken by design."

That other developers want to see tests in your software before they take it
seriously is yet another reason for you to start writing tests.

Tests help teams work together
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The previous points are written from the point of view of a single developer
maintaining an application. Complex applications will be maintained by teams.
Tests guarantee that colleagues don't inadvertently break your code (and that
you don't break theirs without knowing). If you want to make a living as a
Django programmer, you must be good at writing tests!

Basic testing strategies
========================

There are many ways to approach writing tests.

Some programmers follow a discipline called "`test-driven development`_"; they
actually write their tests before they write their code. This might seem
counter-intuitive, but in fact it's similar to what most people will often do
anyway: they describe a problem, then create some code to solve it. Test-driven
development simply formalizes the problem in a Python test case.

More often, a newcomer to testing will create some code and later decide that
it should have some tests. Perhaps it would have been better to write some
tests earlier, but it's never too late to get started.

Sometimes it's difficult to figure out where to get started with writing tests.
If you have written several thousand lines of Python, choosing something to
test might not be easy. In such a case, it's fruitful to write your first test
the next time you make a change, either when you add a new feature or fix a bug.

So let's do that right away.

.. _test-driven development: https://en.wikipedia.org/wiki/Test-driven_development

Writing our first test
======================

We identify a bug
-----------------

Fortunately, there's a little bug in the ``polls`` application for us to fix
right away: the ``Question.was_published_recently()`` method returns ``True`` if
the ``Question`` was published within the last day (which is correct) but also if
the ``Question``’s ``pub_date`` field is in the future (which certainly isn't).

To check if the bug really exists, using the Admin create a question whose date
lies in the future and check the method using the :djadmin:`shell`::

    >>> import datetime
    >>> from django.utils import timezone
    >>> from polls.models import Question
    >>> # create a Question instance with pub_date 30 days in the future
    >>> future_question = Question(pub_date=timezone.now() + datetime.timedelta(days=30))
    >>> # was it published recently?
    >>> future_question.was_published_recently()
    True

Since things in the future are not 'recent', this is clearly wrong.

Create a test to expose the bug
-------------------------------

What we've just done in the :djadmin:`shell` to test for the problem is exactly
what we can do in an automated test, so let's turn that into an automated test.

A conventional place for an application's tests is in the application's
``tests.py`` file; the testing system will automatically find tests in any file
whose name begins with ``test``.

Put the following in the ``tests.py`` file in the ``polls`` application:

.. snippet::
    :filename: polls/tests.py

    import datetime

    from django.utils import timezone
    from django.test import TestCase

    from .models import Question


    class QuestionMethodTests(TestCase):

        def test_was_published_recently_with_future_question(self):
            """
            was_published_recently() should return False for questions whose
            pub_date is in the future.
            """
            time = timezone.now() + datetime.timedelta(days=30)
            future_question = Question(pub_date=time)
            self.assertIs(future_question.was_published_recently(), False)

What we have done here is created a :class:`django.test.TestCase` subclass
with a method that creates a ``Question`` instance with a ``pub_date`` in the
future. We then check the output of ``was_published_recently()`` - which
*ought* to be False.

Running tests
-------------

In the terminal, we can run our test::

    $ python manage.py test polls

and you'll see something like::

    Creating test database for alias 'default'...
    F
    ======================================================================
    FAIL: test_was_published_recently_with_future_question (polls.tests.QuestionMethodTests)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/path/to/mysite/polls/tests.py", line 16, in test_was_published_recently_with_future_question
        self.assertIs(future_question.was_published_recently(), False)
    AssertionError: True is not False

    ----------------------------------------------------------------------
    Ran 1 test in 0.001s

    FAILED (failures=1)
    Destroying test database for alias 'default'...

What happened is this:

* ``python manage.py test polls`` looked for tests in the ``polls`` application

* it found a subclass of the :class:`django.test.TestCase` class

* it created a special database for the purpose of testing

* it looked for test methods - ones whose names begin with ``test``

* in ``test_was_published_recently_with_future_question`` it created a ``Question``
  instance whose ``pub_date`` field is 30 days in the future

* ... and using the ``assertIs()`` method, it discovered that its
  ``was_published_recently()`` returns ``True``, though we wanted it to return
  ``False``

The test informs us which test failed and even the line on which the failure
occurred.

Fixing the bug
--------------

We already know what the problem is: ``Question.was_published_recently()`` should
return ``False`` if its ``pub_date`` is in the future. Amend the method in
``models.py``, so that it will only return ``True`` if the date is also in the
past:

.. snippet::
    :filename: polls/models.py

    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now

and run the test again::

    Creating test database for alias 'default'...
    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.001s

    OK
    Destroying test database for alias 'default'...

After identifying a bug, we wrote a test that exposes it and corrected the bug
in the code so our test passes.

Many other things might go wrong with our application in the future, but we can
be sure that we won't inadvertently reintroduce this bug, because simply
running the test will warn us immediately. We can consider this little portion
of the application pinned down safely forever.

More comprehensive tests
------------------------

While we're here, we can further pin down the ``was_published_recently()``
method; in fact, it would be positively embarrassing if in fixing one bug we had
introduced another.

Add two more test methods to the same class, to test the behavior of the method
more comprehensively:

.. snippet::
    :filename: polls/tests.py

    def test_was_published_recently_with_old_question(self):
        """
        was_published_recently() should return False for questions whose
        pub_date is older than 1 day.
        """
        time = timezone.now() - datetime.timedelta(days=30)
        old_question = Question(pub_date=time)
        self.assertIs(old_question.was_published_recently(), False)

    def test_was_published_recently_with_recent_question(self):
        """
        was_published_recently() should return True for questions whose
        pub_date is within the last day.
        """
        time = timezone.now() - datetime.timedelta(hours=1)
        recent_question = Question(pub_date=time)
        self.assertIs(recent_question.was_published_recently(), True)

And now we have three tests that confirm that ``Question.was_published_recently()``
returns sensible values for past, recent, and future questions.

Again, ``polls`` is a simple application, but however complex it grows in the
future and whatever other code it interacts with, we now have some guarantee
that the method we have written tests for will behave in expected ways.

Test a view
===========

The polls application is fairly undiscriminating: it will publish any question,
including ones whose ``pub_date`` field lies in the future. We should improve
this. Setting a ``pub_date`` in the future should mean that the Question is
published at that moment, but invisible until then.

A test for a view
-----------------

When we fixed the bug above, we wrote the test first and then the code to fix
it. In fact that was a simple example of test-driven development, but it
doesn't really matter in which order we do the work.

In our first test, we focused closely on the internal behavior of the code. For
this test, we want to check its behavior as it would be experienced by a user
through a web browser.

Before we try to fix anything, let's have a look at the tools at our disposal.

The Django test client
----------------------

Django provides a test :class:`~django.test.Client` to simulate a user
interacting with the code at the view level.  We can use it in ``tests.py``
or even in the :djadmin:`shell`.

We will start again with the :djadmin:`shell`, where we need to do a couple of
things that won't be necessary in ``tests.py``. The first is to set up the test
environment in the :djadmin:`shell`::

    >>> from django.test.utils import setup_test_environment
    >>> setup_test_environment()

:meth:`~django.test.utils.setup_test_environment` installs a template renderer
which will allow us to examine some additional attributes on responses such as
``response.context`` that otherwise wouldn't be available. Note that this
method *does not* setup a test database, so the following will be run against
the existing database and the output may differ slightly depending on what
questions you already created. You might get unexpected results if your
``TIME_ZONE`` in ``settings.py`` isn't correct. If you don't remember setting
it earlier, check it before continuing.

Next we need to import the test client class (later in ``tests.py`` we will use
the :class:`django.test.TestCase` class, which comes with its own client, so
this won't be required)::

    >>> from django.test import Client
    >>> # create an instance of the client for our use
    >>> client = Client()

With that ready, we can ask the client to do some work for us::

    >>> # get a response from '/'
    >>> response = client.get('/')
    >>> # we should expect a 404 from that address
    >>> response.status_code
    404
    >>> # on the other hand we should expect to find something at '/polls/'
    >>> # we'll use 'reverse()' rather than a hardcoded URL
    >>> from django.urls import reverse
    >>> response = client.get(reverse('polls:index'))
    >>> response.status_code
    200
    >>> response.content
    b'\n    <ul>\n    \n        <li><a href="/polls/1/">What&#39;s up?</a></li>\n    \n    </ul>\n\n'
    >>> # If the following doesn't work, you probably omitted the call to
    >>> # setup_test_environment() described above
    >>> response.context['latest_question_list']
    <QuerySet [<Question: What's up?>]>

Improving our view
------------------

The list of polls shows polls that aren't published yet (i.e. those that have a
``pub_date`` in the future). Let's fix that.

In :doc:`Tutorial 4 </intro/tutorial04>` we introduced a class-based view,
based on :class:`~django.views.generic.list.ListView`:

.. snippet::
    :filename: polls/views.py

    class IndexView(generic.ListView):
        template_name = 'polls/index.html'
        context_object_name = 'latest_question_list'

        def get_queryset(self):
            """Return the last five published questions."""
            return Question.objects.order_by('-pub_date')[:5]

We need to amend the ``get_queryset()`` method and change it so that it also
checks the date by comparing it with ``timezone.now()``. First we need to add
an import:

.. snippet::
    :filename: polls/views.py

    from django.utils import timezone

and then we must amend the ``get_queryset`` method like so:

.. snippet::
    :filename: polls/views.py

    def get_queryset(self):
        """
        Return the last five published questions (not including those set to be
        published in the future).
        """
        return Question.objects.filter(
            pub_date__lte=timezone.now()
        ).order_by('-pub_date')[:5]

``Question.objects.filter(pub_date__lte=timezone.now())`` returns a queryset
containing ``Question``\s whose ``pub_date`` is less than or equal to - that
is, earlier than or equal to - ``timezone.now``.

Testing our new view
--------------------

Now you can satisfy yourself that this behaves as expected by firing up the
runserver, loading the site in your browser, creating ``Questions`` with dates
in the past and future, and checking that only those that have been published
are listed.  You don't want to have to do that *every single time you make any
change that might affect this* - so let's also create a test, based on our
:djadmin:`shell` session above.

Add the following to ``polls/tests.py``:

.. snippet::
    :filename: polls/tests.py

    from django.urls import reverse

and we'll create a shortcut function to create questions as well as a new test
class:

.. snippet::
    :filename: polls/tests.py

    def create_question(question_text, days):
        """
        Creates a question with the given `question_text` and published the
        given number of `days` offset to now (negative for questions published
        in the past, positive for questions that have yet to be published).
        """
        time = timezone.now() + datetime.timedelta(days=days)
        return Question.objects.create(question_text=question_text, pub_date=time)


    class QuestionViewTests(TestCase):
        def test_index_view_with_no_questions(self):
            """
            If no questions exist, an appropriate message should be displayed.
            """
            response = self.client.get(reverse('polls:index'))
            self.assertEqual(response.status_code, 200)
            self.assertContains(response, "No polls are available.")
            self.assertQuerysetEqual(response.context['latest_question_list'], [])

        def test_index_view_with_a_past_question(self):
            """
            Questions with a pub_date in the past should be displayed on the
            index page.
            """
            create_question(question_text="Past question.", days=-30)
            response = self.client.get(reverse('polls:index'))
            self.assertQuerysetEqual(
                response.context['latest_question_list'],
                ['<Question: Past question.>']
            )

        def test_index_view_with_a_future_question(self):
            """
            Questions with a pub_date in the future should not be displayed on
            the index page.
            """
            create_question(question_text="Future question.", days=30)
            response = self.client.get(reverse('polls:index'))
            self.assertContains(response, "No polls are available.")
            self.assertQuerysetEqual(response.context['latest_question_list'], [])

        def test_index_view_with_future_question_and_past_question(self):
            """
            Even if both past and future questions exist, only past questions
            should be displayed.
            """
            create_question(question_text="Past question.", days=-30)
            create_question(question_text="Future question.", days=30)
            response = self.client.get(reverse('polls:index'))
            self.assertQuerysetEqual(
                response.context['latest_question_list'],
                ['<Question: Past question.>']
            )

        def test_index_view_with_two_past_questions(self):
            """
            The questions index page may display multiple questions.
            """
            create_question(question_text="Past question 1.", days=-30)
            create_question(question_text="Past question 2.", days=-5)
            response = self.client.get(reverse('polls:index'))
            self.assertQuerysetEqual(
                response.context['latest_question_list'],
                ['<Question: Past question 2.>', '<Question: Past question 1.>']
            )


Let's look at some of these more closely.

First is a question shortcut function, ``create_question``, to take some
repetition out of the process of creating questions.

``test_index_view_with_no_questions`` doesn't create any questions, but checks
the message: "No polls are available." and verifies the ``latest_question_list``
is empty. Note that the :class:`django.test.TestCase` class provides some
additional assertion methods. In these examples, we use
:meth:`~django.test.SimpleTestCase.assertContains()` and
:meth:`~django.test.TransactionTestCase.assertQuerysetEqual()`.

In ``test_index_view_with_a_past_question``, we create a question and verify that it
appears in the list.

In ``test_index_view_with_a_future_question``, we create a question with a
``pub_date`` in the future. The database is reset for each test method, so the
first question is no longer there, and so again the index shouldn't have any
questions in it.

And so on. In effect, we are using the tests to tell a story of admin input
and user experience on the site, and checking that at every state and for every
new change in the state of the system, the expected results are published.

Testing the ``DetailView``
--------------------------

What we have works well; however, even though future questions don't appear in
the *index*, users can still reach them if they know or guess the right URL. So
we need to add a similar  constraint to ``DetailView``:

.. snippet::
    :filename: polls/views.py

    class DetailView(generic.DetailView):
        ...
        def get_queryset(self):
            """
            Excludes any questions that aren't published yet.
            """
            return Question.objects.filter(pub_date__lte=timezone.now())

And of course, we will add some tests, to check that a ``Question`` whose
``pub_date`` is in the past can be displayed, and that one with a ``pub_date``
in the future is not:

.. snippet::
    :filename: polls/tests.py

    class QuestionIndexDetailTests(TestCase):
        def test_detail_view_with_a_future_question(self):
            """
            The detail view of a question with a pub_date in the future should
            return a 404 not found.
            """
            future_question = create_question(question_text='Future question.', days=5)
            url = reverse('polls:detail', args=(future_question.id,))
            response = self.client.get(url)
            self.assertEqual(response.status_code, 404)

        def test_detail_view_with_a_past_question(self):
            """
            The detail view of a question with a pub_date in the past should
            display the question's text.
            """
            past_question = create_question(question_text='Past Question.', days=-5)
            url = reverse('polls:detail', args=(past_question.id,))
            response = self.client.get(url)
            self.assertContains(response, past_question.question_text)

Ideas for more tests
--------------------

We ought to add a similar ``get_queryset`` method to ``ResultsView`` and
create a new test class for that view. It'll be very similar to what we have
just created; in fact there will be a lot of repetition.

We could also improve our application in other ways, adding tests along the
way. For example, it's silly that ``Questions`` can be published on the site
that have no ``Choices``. So, our views could check for this, and exclude such
``Questions``. Our tests would create a ``Question`` without ``Choices`` and
then test that it's not published, as well as create a similar ``Question``
*with* ``Choices``, and test that it *is* published.

Perhaps logged-in admin users should be allowed to see unpublished
``Questions``, but not ordinary visitors. Again: whatever needs to be added to
the software to accomplish this should be accompanied by a test, whether you
write the test first and then make the code pass the test, or work out the
logic in your code first and then write a test to prove it.

At a certain point you are bound to look at your tests and wonder whether your
code is suffering from test bloat, which brings us to:

When testing, more is better
============================

It might seem that our tests are growing out of control. At this rate there will
soon be more code in our tests than in our application, and the repetition
is unaesthetic, compared to the elegant conciseness of the rest of our code.

**It doesn't matter**. Let them grow. For the most part, you can write a test
once and then forget about it. It will continue performing its useful function
as you continue to develop your program.

Sometimes tests will need to be updated. Suppose that we amend our views so that
only ``Questions`` with ``Choices`` are published. In that case, many of our
existing tests will fail - *telling us exactly which tests need to be amended to
bring them up to date*, so to that extent tests help look after themselves.

At worst, as you continue developing, you might find that you have some tests
that are now redundant. Even that's not a problem; in testing redundancy is
a *good* thing.

As long as your tests are sensibly arranged, they won't become unmanageable.
Good rules-of-thumb include having:

* a separate ``TestClass`` for each model or view
* a separate test method for each set of conditions you want to test
* test method names that describe their function

Further testing
===============

This tutorial only introduces some of the basics of testing. There's a great
deal more you can do, and a number of very useful tools at your disposal to
achieve some very clever things.

For example, while our tests here have covered some of the internal logic of a
model and the way our views publish information, you can use an "in-browser"
framework such as Selenium_ to test the way your HTML actually renders in a
browser. These tools allow you to check not just the behavior of your Django
code, but also, for example, of your JavaScript. It's quite something to see
the tests launch a browser, and start interacting with your site, as if a human
being were driving it! Django includes :class:`~django.test.LiveServerTestCase`
to facilitate integration with tools like Selenium.

If you have a complex application, you may want to run tests automatically
with every commit for the purposes of `continuous integration`_, so that
quality control is itself - at least partially - automated.

A good way to spot untested parts of your application is to check code
coverage. This also helps identify fragile or even dead code. If you can't test
a piece of code, it usually means that code should be refactored or removed.
Coverage will help to identify dead code. See
:ref:`topics-testing-code-coverage` for details.

:doc:`Testing in Django </topics/testing/index>` has comprehensive
information about testing.

.. _Selenium: http://seleniumhq.org/
.. _continuous integration: https://en.wikipedia.org/wiki/Continuous_integration

What's next?
============

For full details on testing, see :doc:`Testing in Django
</topics/testing/index>`.

When you're comfortable with testing Django views, read
:doc:`part 6 of this tutorial</intro/tutorial06>` to learn about
static files management.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Intro Tutorial06 (`大一小学期/Week_3-Python/exam/2016/docs/intro/tutorial06.txt`)

=====================================
Writing your first Django app, part 6
=====================================

This tutorial begins where :doc:`Tutorial 5 </intro/tutorial05>` left off.
We've built a tested Web-poll application, and we'll now add a stylesheet and
an image.

Aside from the HTML generated by the server, web applications generally need
to serve additional files — such as images, JavaScript, or CSS — necessary to
render the complete web page. In Django, we refer to these files as "static
files".

For small projects, this isn't a big deal, because you can just keep the
static files somewhere your web server can find it. However, in bigger
projects -- especially those comprised of multiple apps -- dealing with the
multiple sets of static files provided by each application starts to get
tricky.

That's what ``django.contrib.staticfiles`` is for: it collects static files
from each of your applications (and any other places you specify) into a
single location that can easily be served in production.

Customize your *app's* look and feel
====================================

First, create a directory called ``static`` in your ``polls`` directory. Django
will look for static files there, similarly to how Django finds templates
inside ``polls/templates/``.

Django's :setting:`STATICFILES_FINDERS` setting contains a list
of finders that know how to discover static files from various
sources. One of the defaults is ``AppDirectoriesFinder`` which
looks for a "static" subdirectory in each of the
:setting:`INSTALLED_APPS`, like the one in ``polls`` we just created. The admin
site uses the same directory structure for its static files.

Within the ``static`` directory you have just created, create another directory
called ``polls`` and within that create a file called ``style.css``. In other
words, your stylesheet should be at ``polls/static/polls/style.css``. Because
of how the ``AppDirectoriesFinder`` staticfile finder works, you can refer to
this static file in Django simply as ``polls/style.css``, similar to how you
reference the path for templates.

.. admonition:: Static file namespacing

    Just like templates, we *might* be able to get away with putting our static
    files directly in ``polls/static`` (rather than creating another ``polls``
    subdirectory), but it would actually be a bad idea. Django will choose the
    first static file it finds whose name matches, and if you had a static file
    with the same name in a *different* application, Django would be unable to
    distinguish between them. We need to be able to point Django at the right
    one, and the easiest way to ensure this is by *namespacing* them. That is,
    by putting those static files inside *another* directory named for the
    application itself.

Put the following code in that stylesheet (``polls/static/polls/style.css``):

.. snippet:: css
    :filename: polls/static/polls/style.css

    li a {
        color: green;
    }

Next, add the following at the top of ``polls/templates/polls/index.html``:

.. snippet:: html+django
    :filename: polls/templates/polls/index.html

    {% load static %}

    <link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" />

The ``{% static %}`` template tag generates the absolute URL of static files.

That's all you need to do for development. Reload
``http://localhost:8000/polls/`` and you should see that the question links are
green (Django style!) which means that your stylesheet was properly loaded.

Adding a background-image
=========================

Next, we'll create a subdirectory for images. Create an ``images`` subdirectory
in the ``polls/static/polls/`` directory. Inside this directory, put an image
called ``background.gif``. In other words, put your image in
``polls/static/polls/images/background.gif``.

Then, add to your stylesheet (``polls/static/polls/style.css``):

.. snippet:: css
    :filename: polls/static/polls/style.css

    body {
        background: white url("images/background.gif") no-repeat right bottom;
    }

Reload ``http://localhost:8000/polls/`` and you should see the background
loaded in the bottom right of the screen.

.. warning::

    Of course the ``{% static %}`` template tag is not available for use in
    static files like your stylesheet which aren't generated by Django. You
    should always use **relative paths** to link your static files between each
    other, because then you can change :setting:`STATIC_URL` (used by the
    :ttag:`static` template tag to generate its URLs) without having to modify
    a bunch of paths in your static files as well.

These are the **basics**. For more details on settings and other bits included
with the framework see
:doc:`the static files howto </howto/static-files/index>` and
:doc:`the staticfiles reference </ref/contrib/staticfiles>`. :doc:`Deploying
static files </howto/static-files/deployment>` discusses how to use static
files on a real server.

When you're comfortable with the static files, read :doc:`part 7 of this
tutorial </intro/tutorial07>` to learn how to customize Django's
automatically-generated admin site.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Intro Tutorial07 (`大一小学期/Week_3-Python/exam/2016/docs/intro/tutorial07.txt`)

=====================================
Writing your first Django app, part 7
=====================================

This tutorial begins where :doc:`Tutorial 6 </intro/tutorial06>` left off. We're
continuing the Web-poll application and will focus on customizing Django's
automatically-generated admin site that we first explored in :doc:`Tutorial 2
</intro/tutorial02>`.

Customize the admin form
========================

By registering the ``Question`` model with ``admin.site.register(Question)``,
Django was able to construct a default form representation. Often, you'll want
to customize how the admin form looks and works. You'll do this by telling
Django the options you want when you register the object.

Let's see how this works by reordering the fields on the edit form. Replace
the ``admin.site.register(Question)`` line with:

.. snippet::
    :filename: polls/admin.py

    from django.contrib import admin

    from .models import Question


    class QuestionAdmin(admin.ModelAdmin):
        fields = ['pub_date', 'question_text']

    admin.site.register(Question, QuestionAdmin)

You'll follow this pattern -- create a model admin class, then pass it as the
second argument to ``admin.site.register()`` -- any time you need to change the
admin options for a model.

This particular change above makes the "Publication date" come before the
"Question" field:

.. image:: _images/admin07.png
   :alt: Fields have been reordered

This isn't impressive with only two fields, but for admin forms with dozens
of fields, choosing an intuitive order is an important usability detail.

And speaking of forms with dozens of fields, you might want to split the form
up into fieldsets:

.. snippet::
    :filename: polls/admin.py

    from django.contrib import admin

    from .models import Question


    class QuestionAdmin(admin.ModelAdmin):
        fieldsets = [
            (None,               {'fields': ['question_text']}),
            ('Date information', {'fields': ['pub_date']}),
        ]

    admin.site.register(Question, QuestionAdmin)

The first element of each tuple in
:attr:`~django.contrib.admin.ModelAdmin.fieldsets` is the title of the fieldset.
Here's what our form looks like now:

.. image:: _images/admin08t.png
   :alt: Form has fieldsets now

Adding related objects
======================

OK, we have our Question admin page, but a ``Question`` has multiple
``Choice``\s, and the admin page doesn't display choices.

Yet.

There are two ways to solve this problem. The first is to register ``Choice``
with the admin just as we did with ``Question``. That's easy:

.. snippet::
    :filename: polls/admin.py

    from django.contrib import admin

    from .models import Choice, Question
    # ...
    admin.site.register(Choice)

Now "Choices" is an available option in the Django admin. The "Add choice" form
looks like this:

.. image:: _images/admin09.png
   :alt: Choice admin page

In that form, the "Question" field is a select box containing every question in the
database. Django knows that a :class:`~django.db.models.ForeignKey` should be
represented in the admin as a ``<select>`` box. In our case, only one question
exists at this point.

Also note the "Add Another" link next to "Question." Every object with a
``ForeignKey`` relationship to another gets this for free. When you click "Add
Another", you'll get a popup window with the "Add question" form. If you add a question
in that window and click "Save", Django will save the question to the database and
dynamically add it as the selected choice on the "Add choice" form you're
looking at.

But, really, this is an inefficient way of adding ``Choice`` objects to the system.
It'd be better if you could add a bunch of Choices directly when you create the
``Question`` object. Let's make that happen.

Remove the ``register()`` call for the ``Choice`` model. Then, edit the ``Question``
registration code to read:

.. snippet::
    :filename: polls/admin.py

    from django.contrib import admin

    from .models import Choice, Question


    class ChoiceInline(admin.StackedInline):
        model = Choice
        extra = 3


    class QuestionAdmin(admin.ModelAdmin):
        fieldsets = [
            (None,               {'fields': ['question_text']}),
            ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
        ]
        inlines = [ChoiceInline]

    admin.site.register(Question, QuestionAdmin)

This tells Django: "``Choice`` objects are edited on the ``Question`` admin page. By
default, provide enough fields for 3 choices."

Load the "Add question" page to see how that looks:

.. image:: _images/admin10t.png
   :alt: Add question page now has choices on it

It works like this: There are three slots for related Choices -- as specified
by ``extra`` -- and each time you come back to the "Change" page for an
already-created object, you get another three extra slots.

At the end of the three current slots you will find an "Add another Choice"
link.  If you click on it, a new slot will be added. If you want to remove the
added slot, you can click on the X to the top right of the added slot. Note
that you can't remove the original three slots. This image shows an added slot:

.. image:: _images/admin14t.png
   :alt: Additional slot added dynamically

One small problem, though. It takes a lot of screen space to display all the
fields for entering related ``Choice`` objects. For that reason, Django offers a
tabular way of displaying inline related objects; you just need to change
the ``ChoiceInline`` declaration to read:

.. snippet::
    :filename: polls/admin.py

    class ChoiceInline(admin.TabularInline):
        #...

With that ``TabularInline`` (instead of ``StackedInline``), the
related objects are displayed in a more compact, table-based format:

.. image:: _images/admin11t.png
   :alt: Add question page now has more compact choices

Note that there is an extra "Delete?" column that allows removing rows added
using the "Add Another Choice" button and rows that have already been saved.

Customize the admin change list
===============================

Now that the Question admin page is looking good, let's make some tweaks to the
"change list" page -- the one that displays all the questions in the system.

Here's what it looks like at this point:

.. image:: _images/admin04t.png
   :alt: Polls change list page

By default, Django displays the ``str()`` of each object. But sometimes it'd be
more helpful if we could display individual fields. To do that, use the
:attr:`~django.contrib.admin.ModelAdmin.list_display` admin option, which is a
tuple of field names to display, as columns, on the change list page for the
object:

.. snippet::
    :filename: polls/admin.py

    class QuestionAdmin(admin.ModelAdmin):
        # ...
        list_display = ('question_text', 'pub_date')

Just for good measure, let's also include the ``was_published_recently()``
method from :doc:`Tutorial 2 </intro/tutorial02>`:

.. snippet::
    :filename: polls/admin.py

    class QuestionAdmin(admin.ModelAdmin):
        # ...
        list_display = ('question_text', 'pub_date', 'was_published_recently')

Now the question change list page looks like this:

.. image:: _images/admin12t.png
   :alt: Polls change list page, updated

You can click on the column headers to sort by those values -- except in the
case of the ``was_published_recently`` header, because sorting by the output
of an arbitrary method is not supported. Also note that the column header for
``was_published_recently`` is, by default, the name of the method (with
underscores replaced with spaces), and that each line contains the string
representation of the output.

You can improve that by giving that method (in :file:`polls/models.py`) a few
attributes, as follows:

.. snippet::
    :filename: polls/models.py

    class Question(models.Model):
        # ...
        def was_published_recently(self):
            now = timezone.now()
            return now - datetime.timedelta(days=1) <= self.pub_date <= now
        was_published_recently.admin_order_field = 'pub_date'
        was_published_recently.boolean = True
        was_published_recently.short_description = 'Published recently?'

For more information on these method properties, see
:attr:`~django.contrib.admin.ModelAdmin.list_display`.

Edit your :file:`polls/admin.py` file again and add an improvement to the
``Question`` change list page: filters using the
:attr:`~django.contrib.admin.ModelAdmin.list_filter`. Add the following line to
``QuestionAdmin``::

    list_filter = ['pub_date']

That adds a "Filter" sidebar that lets people filter the change list by the
``pub_date`` field:

.. image:: _images/admin13t.png
   :alt: Polls change list page, updated

The type of filter displayed depends on the type of field you're filtering on.
Because ``pub_date`` is a :class:`~django.db.models.DateTimeField`, Django
knows to give appropriate filter options: "Any date", "Today", "Past 7 days",
"This month", "This year".

This is shaping up well. Let's add some search capability::

    search_fields = ['question_text']

That adds a search box at the top of the change list. When somebody enters
search terms, Django will search the ``question_text`` field. You can use as many
fields as you'd like -- although because it uses a ``LIKE`` query behind the
scenes, limiting the number of search fields to a reasonable number will make
it easier for your database to do the search.

Now's also a good time to note that change lists give you free pagination. The
default is to display 100 items per page. :attr:`Change list pagination
<django.contrib.admin.ModelAdmin.list_per_page>`, :attr:`search boxes
<django.contrib.admin.ModelAdmin.search_fields>`, :attr:`filters
<django.contrib.admin.ModelAdmin.list_filter>`, :attr:`date-hierarchies
<django.contrib.admin.ModelAdmin.date_hierarchy>`, and
:attr:`column-header-ordering <django.contrib.admin.ModelAdmin.list_display>`
all work together like you think they should.

Customize the admin look and feel
=================================

Clearly, having "Django administration" at the top of each admin page is
ridiculous. It's just placeholder text.

That's easy to change, though, using Django's template system. The Django admin
is powered by Django itself, and its interfaces use Django's own template
system.

.. _ref-customizing-your-projects-templates:

Customizing your *project's* templates
--------------------------------------

Create a ``templates`` directory in your project directory (the one that
contains ``manage.py``). Templates can live anywhere on your filesystem that
Django can access. (Django runs as whatever user your server runs.) However,
keeping your templates within the project is a good convention to follow.

Open your settings file (:file:`mysite/settings.py`, remember) and add a
:setting:`DIRS <TEMPLATES-DIRS>` option in the :setting:`TEMPLATES` setting:

.. snippet::
    :filename: mysite/settings.py

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            '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',
                ],
            },
        },
    ]

:setting:`DIRS <TEMPLATES-DIRS>` is a list of filesystem directories to check
when loading Django templates; it's a search path.

.. admonition:: Organizing templates

    Just like the static files, we *could* have all our templates together, in
    one big templates directory, and it would work perfectly well. However,
    templates that belong to a particular application should be placed in that
    application’s template directory (e.g. ``polls/templates``) rather than the
    project’s (``templates``). We'll discuss in more detail in the
    :doc:`reusable apps tutorial </intro/reusable-apps>` *why* we do this.

Now create a directory called ``admin`` inside ``templates``, and copy the
template ``admin/base_site.html`` from within the default Django admin
template directory in the source code of Django itself
(``django/contrib/admin/templates``) into that directory.

.. admonition:: Where are the Django source files?

    If you have difficulty finding where the Django source files are located
    on your system, run the following command:

    .. code-block:: console

        $ python -c "import django; print(django.__path__)"

Then, just edit the file and replace
``{{ site_header|default:_('Django administration') }}`` (including the curly
braces) with your own site's name as you see fit. You should end up with
a section of code like:

.. code-block:: html+django

    {% block branding %}
    <h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
    {% endblock %}

We use this approach to teach you how to override templates. In an actual
project, you would probably use
the :attr:`django.contrib.admin.AdminSite.site_header` attribute to more easily
make this particular customization.

This template file contains lots of text like ``{% block branding %}``
and ``{{ title }}``. The ``{%`` and ``{{`` tags are part of Django's
template language. When Django renders ``admin/base_site.html``, this
template language will be evaluated to produce the final HTML page, just like
we saw in :doc:`Tutorial 3 </intro/tutorial03>`.

Note that any of Django's default admin templates can be overridden. To
override a template, just do the same thing you did with ``base_site.html`` --
copy it from the default directory into your custom directory, and make
changes.

Customizing your *application's* templates
------------------------------------------

Astute readers will ask: But if :setting:`DIRS <TEMPLATES-DIRS>` was empty by
default, how was Django finding the default admin templates? The answer is
that, since :setting:`APP_DIRS <TEMPLATES-APP_DIRS>` is set to ``True``,
Django automatically looks for a ``templates/`` subdirectory within each
application package, for use as a fallback (don't forget that
``django.contrib.admin`` is an application).

Our poll application is not very complex and doesn't need custom admin
templates. But if it grew more sophisticated and required modification of
Django's standard admin templates for some of its functionality, it would be
more sensible to modify the *application's* templates, rather than those in the
*project*. That way, you could include the polls application in any new project
and be assured that it would find the custom templates it needed.

See the :ref:`template loading documentation <template-loading>` for more
information about how Django finds its templates.

Customize the admin index page
==============================

On a similar note, you might want to customize the look and feel of the Django
admin index page.

By default, it displays all the apps in :setting:`INSTALLED_APPS` that have been
registered with the admin application, in alphabetical order. You may want to
make significant changes to the layout. After all, the index is probably the
most important page of the admin, and it should be easy to use.

The template to customize is ``admin/index.html``. (Do the same as with
``admin/base_site.html`` in the previous section -- copy it from the default
directory to your custom template directory). Edit the file, and you'll see it
uses a template variable called ``app_list``. That variable contains every
installed Django app. Instead of using that, you can hard-code links to
object-specific admin pages in whatever way you think is best.

What's next?
============

The beginner tutorial ends here. In the meantime, you might want to check out
some pointers on :doc:`where to go from here </intro/whatsnext>`.

If you are familiar with Python packaging and interested in learning how to
turn polls into a "reusable app", check out :doc:`Advanced tutorial: How to
write reusable apps</intro/reusable-apps>`.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Intro Whatsnext (`大一小学期/Week_3-Python/exam/2016/docs/intro/whatsnext.txt`)

=================
What to read next
=================

So you've read all the :doc:`introductory material </intro/index>` and have
decided you'd like to keep using Django. We've only just scratched the surface
with this intro (in fact, if you've read every single word, you've read about
5% of the overall documentation).

So what's next?

Well, we've always been big fans of learning by doing. At this point you should
know enough to start a project of your own and start fooling around. As you need
to learn new tricks, come back to the documentation.

We've put a lot of effort into making Django's documentation useful, easy to
read and as complete as possible. The rest of this document explains more about
how the documentation works so that you can get the most out of it.

(Yes, this is documentation about documentation. Rest assured we have no plans
to write a document about how to read the document about documentation.)

Finding documentation
=====================

Django's got a *lot* of documentation -- almost 450,000 words and counting --
so finding what you need can sometimes be tricky. A few good places to start
are the :ref:`search` and the :ref:`genindex`.

Or you can just browse around!

How the documentation is organized
==================================

Django's main documentation is broken up into "chunks" designed to fill
different needs:

* The :doc:`introductory material </intro/index>` is designed for people new
  to Django -- or to Web development in general. It doesn't cover anything
  in depth, but instead gives a high-level overview of how developing in
  Django "feels".

* The :doc:`topic guides </topics/index>`, on the other hand, dive deep into
  individual parts of Django. There are complete guides to Django's
  :doc:`model system </topics/db/index>`, :doc:`template engine
  </topics/templates>`, :doc:`forms framework </topics/forms/index>`, and much
  more.

  This is probably where you'll want to spend most of your time; if you work
  your way through these guides you should come out knowing pretty much
  everything there is to know about Django.

* Web development is often broad, not deep -- problems span many domains.
  We've written a set of :doc:`how-to guides </howto/index>` that answer
  common "How do I ...?" questions. Here you'll find information about
  :doc:`generating PDFs with Django </howto/outputting-pdf>`, :doc:`writing
  custom template tags </howto/custom-template-tags>`, and more.

  Answers to really common questions can also be found in the :doc:`FAQ
  </faq/index>`.

* The guides and how-to's don't cover every single class, function, and
  method available in Django -- that would be overwhelming when you're
  trying to learn. Instead, details about individual classes, functions,
  methods, and modules are kept in the :doc:`reference </ref/index>`. This is
  where you'll turn to find the details of a particular function or
  whatever you need.

* If you are interested in deploying a project for public use, our docs have
  :doc:`several guides</howto/deployment/index>` for various deployment
  setups as well as a :doc:`deployment checklist</howto/deployment/checklist>`
  for some things you'll need to think about.

* Finally, there's some "specialized" documentation not usually relevant to
  most developers. This includes the :doc:`release notes </releases/index>` and
  :doc:`internals documentation </internals/index>` for those who want to add
  code to Django itself, and a :doc:`few other things that simply don't fit
  elsewhere </misc/index>`.


How documentation is updated
============================

Just as the Django code base is developed and improved on a daily basis, our
documentation is consistently improving. We improve documentation for several
reasons:

* To make content fixes, such as grammar/typo corrections.

* To add information and/or examples to existing sections that need to be
  expanded.

* To document Django features that aren't yet documented. (The list of
  such features is shrinking but exists nonetheless.)

* To add documentation for new features as new features get added, or as
  Django APIs or behaviors change.

Django's documentation is kept in the same source control system as its code. It
lives in the `docs`_ directory of our Git repository. Each document online is a
separate text file in the repository.

.. _docs: https://github.com/django/django/tree/master/docs

Where to get it
===============

You can read Django documentation in several ways. They are, in order of
preference:

On the Web
----------

The most recent version of the Django documentation lives at
https://docs.djangoproject.com/en/dev/. These HTML pages are generated
automatically from the text files in source control. That means they reflect the
"latest and greatest" in Django -- they include the very latest corrections and
additions, and they discuss the latest Django features, which may only be
available to users of the Django development version. (See "Differences between
versions" below.)

We encourage you to help improve the docs by submitting changes, corrections and
suggestions in the `ticket system`_. The Django developers actively monitor the
ticket system and use your feedback to improve the documentation for everybody.

Note, however, that tickets should explicitly relate to the documentation,
rather than asking broad tech-support questions. If you need help with your
particular Django setup, try the |django-users| mailing list or the `#django
IRC channel`_ instead.

.. _ticket system: https://code.djangoproject.com/
.. _#django IRC channel: irc://irc.freenode.net/django

In plain text
-------------

For offline reading, or just for convenience, you can read the Django
documentation in plain text.

If you're using an official release of Django, note that the zipped package
(tarball) of the code includes a ``docs/`` directory, which contains all the
documentation for that release.

If you're using the development version of Django (aka "trunk"), note that the
``docs/`` directory contains all of the documentation. You can update your
Git checkout to get the latest changes.

One low-tech way of taking advantage of the text documentation is by using the
Unix ``grep`` utility to search for a phrase in all of the documentation. For
example, this will show you each mention of the phrase "max_length" in any
Django document:

.. code-block:: console

    $ grep -r max_length /path/to/django/docs/

As HTML, locally
----------------

You can get a local copy of the HTML documentation following a few easy steps:

* Django's documentation uses a system called Sphinx__ to convert from
  plain text to HTML. You'll need to install Sphinx by either downloading
  and installing the package from the Sphinx website, or with ``pip``:

  .. code-block:: console

        $ pip install Sphinx

* Then, just use the included ``Makefile`` to turn the documentation into
  HTML:

  .. code-block:: console

        $ cd path/to/django/docs
        $ make html

  You'll need `GNU Make`__ installed for this.

  If you're on Windows you can alternatively use the included batch file:

  .. code-block:: bat

        cd path\to\django\docs
        make.bat html

* The HTML documentation will be placed in ``docs/_build/html``.

__ http://sphinx-doc.org/
__ https://www.gnu.org/software/make/

.. _differences-between-doc-versions:

Differences between versions
============================

As previously mentioned, the text documentation in our Git repository
contains the "latest and greatest" changes and additions. These changes often
include documentation of new features added in the Django development version
-- the Git ("trunk") version of Django. For that reason, it's worth
pointing out our policy on keeping straight the documentation for various
versions of the framework.

We follow this policy:

* The primary documentation on djangoproject.com is an HTML version of the
  latest docs in Git. These docs always correspond to the latest
  official Django release, plus whatever features we've added/changed in
  the framework *since* the latest release.

* As we add features to Django's development version, we try to update the
  documentation in the same Git commit transaction.

* To distinguish feature changes/additions in the docs, we use the phrase:
  "New in version X.Y", being X.Y the next release version (hence, the one
  being developed).

* Documentation fixes and improvements may be backported to the last release
  branch, at the discretion of the committer, however, once a version of
  Django is :ref:`no longer supported<backwards-compatibility-policy>`, that
  version of the docs won't get any further updates.

* The `main documentation Web page`_ includes links to documentation for
  all previous versions. Be sure you are using the version of the docs
  corresponding to the version of Django you are using!

.. _main documentation Web page: https://docs.djangoproject.com/en/dev/

---

### 大一小学期 Week 3 Python Exam 2016 Docs Misc Api Stability (`大一小学期/Week_3-Python/exam/2016/docs/misc/api-stability.txt`)

=============
API stability
=============

Django promises API stability and forwards-compatibility since version 1.0. In
a nutshell, this means that code you develop against a version of Django will
continue to work with future releases. You may need to make minor changes when
upgrading the version of Django your project uses: see the "Backwards
incompatible changes" section of the :doc:`release note </releases/index>` for
the version or versions to which you are upgrading.

What "stable" means
===================

In this context, stable means:

- All the public APIs (everything in this documentation) will not be moved
  or renamed without providing backwards-compatible aliases.

- If new features are added to these APIs -- which is quite possible --
  they will not break or change the meaning of existing methods. In other
  words, "stable" does not (necessarily) mean "complete."

- If, for some reason, an API declared stable must be removed or replaced, it
  will be declared deprecated but will remain in the API for at least two
  feature releases. Warnings will be issued when the deprecated method is
  called.

  See :ref:`official-releases` for more details on how Django's version
  numbering scheme works, and how features will be deprecated.

- We'll only break backwards compatibility of these APIs if a bug or
  security hole makes it completely unavoidable.

Stable APIs
===========

In general, everything covered in the documentation -- with the exception of
anything in the :doc:`internals area </internals/index>` is considered stable.

Exceptions
==========

There are a few exceptions to this stability and backwards-compatibility
promise.

Security fixes
--------------

If we become aware of a security problem -- hopefully by someone following our
:ref:`security reporting policy <reporting-security-issues>` -- we'll do
everything necessary to fix it. This might mean breaking backwards
compatibility; security trumps the compatibility guarantee.

APIs marked as internal
-----------------------

Certain APIs are explicitly marked as "internal" in a couple of ways:

- Some documentation refers to internals and mentions them as such. If the
  documentation says that something is internal, we reserve the right to
  change it.

- Functions, methods, and other objects prefixed by a leading underscore
  (``_``). This is the standard Python way of indicating that something is
  private; if any method starts with a single ``_``, it's an internal API.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Misc Design Philosophies (`大一小学期/Week_3-Python/exam/2016/docs/misc/design-philosophies.txt`)

===================
Design philosophies
===================

This document explains some of the fundamental philosophies Django's developers
have used in creating the framework. Its goal is to explain the past and guide
the future.

Overall
=======

.. _loose-coupling:

Loose coupling
--------------

.. index:: coupling; loose

A fundamental goal of Django's stack is `loose coupling and tight cohesion`_.
The various layers of the framework shouldn't "know" about each other unless
absolutely necessary.

For example, the template system knows nothing about Web requests, the database
layer knows nothing about data display and the view system doesn't care which
template system a programmer uses.

Although Django comes with a full stack for convenience, the pieces of the
stack are independent of another wherever possible.

.. _`loose coupling and tight cohesion`: http://c2.com/cgi/wiki?CouplingAndCohesion

.. _less-code:

Less code
---------

Django apps should use as little code as possible; they should lack boilerplate.
Django should take full advantage of Python's dynamic capabilities, such as
introspection.

.. _quick-development:

Quick development
-----------------

The point of a Web framework in the 21st century is to make the tedious aspects
of Web development fast. Django should allow for incredibly quick Web
development.

.. _dry:

Don't repeat yourself (DRY)
---------------------------

.. index::
   single: DRY
   single: Don't repeat yourself

Every distinct concept and/or piece of data should live in one, and only one,
place. Redundancy is bad. Normalization is good.

The framework, within reason, should deduce as much as possible from as little
as possible.

.. seealso::

    The `discussion of DRY on the Portland Pattern Repository`__

    __ http://c2.com/cgi/wiki?DontRepeatYourself

.. _explicit-is-better-than-implicit:

Explicit is better than implicit
--------------------------------

This is a core Python principle listed in :pep:`20`, and it means Django
shouldn't do too much "magic." Magic shouldn't happen unless there's a really
good reason for it. Magic is worth using only if it creates a huge convenience
unattainable in other ways, and it isn't implemented in a way that confuses
developers who are trying to learn how to use the feature.

.. _consistency:

Consistency
-----------

The framework should be consistent at all levels. Consistency applies to
everything from low-level (the Python coding style used) to high-level (the
"experience" of using Django).

Models
======

Explicit is better than implicit
--------------------------------

Fields shouldn't assume certain behaviors based solely on the name of the
field. This requires too much knowledge of the system and is prone to errors.
Instead, behaviors should be based on keyword arguments and, in some cases, on
the type of the field.

Include all relevant domain logic
---------------------------------

Models should encapsulate every aspect of an "object," following Martin
Fowler's `Active Record`_ design pattern.

This is why both the data represented by a model and information about
it (its human-readable name, options like default ordering, etc.) are
defined in the model class; all the information needed to understand a
given model should be stored *in* the model.

.. _`Active Record`: http://www.martinfowler.com/eaaCatalog/activeRecord.html

Database API
============

The core goals of the database API are:

SQL efficiency
--------------

It should execute SQL statements as few times as possible, and it should
optimize statements internally.

This is why developers need to call ``save()`` explicitly, rather than the
framework saving things behind the scenes silently.

This is also why the ``select_related()`` ``QuerySet`` method exists. It's an
optional performance booster for the common case of selecting "every related
object."

Terse, powerful syntax
----------------------

The database API should allow rich, expressive statements in as little syntax
as possible. It should not rely on importing other modules or helper objects.

Joins should be performed automatically, behind the scenes, when necessary.

Every object should be able to access every related object, systemwide. This
access should work both ways.

Option to drop into raw SQL easily, when needed
-----------------------------------------------

The database API should realize it's a shortcut but not necessarily an
end-all-be-all. The framework should make it easy to write custom SQL -- entire
statements, or just custom ``WHERE`` clauses as custom parameters to API calls.

URL design
==========

Loose coupling
--------------

URLs in a Django app should not be coupled to the underlying Python code. Tying
URLs to Python function names is a Bad And Ugly Thing.

Along these lines, the Django URL system should allow URLs for the same app to
be different in different contexts. For example, one site may put stories at
``/stories/``, while another may use ``/news/``.

Infinite flexibility
--------------------

URLs should be as flexible as possible. Any conceivable URL design should be
allowed.

Encourage best practices
------------------------

The framework should make it just as easy (or even easier) for a developer to
design pretty URLs than ugly ones.

File extensions in Web-page URLs should be avoided.

Vignette-style commas in URLs deserve severe punishment.

.. _definitive-urls:

Definitive URLs
---------------

.. index:: urls; definitive

Technically, ``foo.com/bar`` and ``foo.com/bar/`` are two different URLs, and
search-engine robots (and some Web traffic-analyzing tools) would treat them as
separate pages. Django should make an effort to "normalize" URLs so that
search-engine robots don't get confused.

This is the reasoning behind the :setting:`APPEND_SLASH` setting.

Template system
===============

.. _separation-of-logic-and-presentation:

Separate logic from presentation
--------------------------------

We see a template system as a tool that controls presentation and
presentation-related logic -- and that's it. The template system shouldn't
support functionality that goes beyond this basic goal.

Discourage redundancy
---------------------

The majority of dynamic websites use some sort of common sitewide design --
a common header, footer, navigation bar, etc. The Django template system should
make it easy to store those elements in a single place, eliminating duplicate
code.

This is the philosophy behind :ref:`template inheritance
<template-inheritance>`.

Be decoupled from HTML
----------------------

The template system shouldn't be designed so that it only outputs HTML. It
should be equally good at generating other text-based formats, or just plain
text.

XML should not be used for template languages
---------------------------------------------

.. index:: xml; suckiness of

Using an XML engine to parse templates introduces a whole new world of human
error in editing templates -- and incurs an unacceptable level of overhead in
template processing.

Assume designer competence
--------------------------

The template system shouldn't be designed so that templates necessarily are
displayed nicely in WYSIWYG editors such as Dreamweaver. That is too severe of
a limitation and wouldn't allow the syntax to be as nice as it is. Django
expects template authors are comfortable editing HTML directly.

Treat whitespace obviously
--------------------------

The template system shouldn't do magic things with whitespace. If a template
includes whitespace, the system should treat the whitespace as it treats text
-- just display it. Any whitespace that's not in a template tag should be
displayed.

Don't invent a programming language
-----------------------------------

The goal is not to invent a programming language. The goal is to offer just
enough programming-esque functionality, such as branching and looping, that is
essential for making presentation-related decisions. The :ref:`Django Template
Language (DTL) <template-language-intro>` aims to avoid advanced logic.

The Django template system recognizes that templates are most often written by
*designers*, not *programmers*, and therefore should not assume Python
knowledge.

Safety and security
-------------------

The template system, out of the box, should forbid the inclusion of malicious
code -- such as commands that delete database records.

This is another reason the template system doesn't allow arbitrary Python code.

Extensibility
-------------

The template system should recognize that advanced template authors may want
to extend its technology.

This is the philosophy behind custom template tags and filters.

Views
=====

Simplicity
----------

Writing a view should be as simple as writing a Python function. Developers
shouldn't have to instantiate a class when a function will do.

Use request objects
-------------------

Views should have access to a request object -- an object that stores metadata
about the current request. The object should be passed directly to a view
function, rather than the view function having to access the request data from
a global variable. This makes it light, clean and easy to test views by passing
in "fake" request objects.

Loose coupling
--------------

A view shouldn't care about which template system the developer uses -- or even
whether a template system is used at all.

Differentiate between GET and POST
----------------------------------

GET and POST are distinct; developers should explicitly use one or the other.
The framework should make it easy to distinguish between GET and POST data.

.. _cache-design-philosophy:

Cache Framework
===============

The core goals of Django's :doc:`cache framework </topics/cache>` are:

Less code
---------

A cache should be as fast as possible.  Hence, all framework code surrounding
the cache backend should be kept to the absolute minimum, especially for
``get()`` operations.

Consistency
-----------

The cache API should provide a consistent interface across the different
cache backends.

Extensibility
-------------

The cache API should be extensible at the application level based on the
developer's needs (for example, see :ref:`cache_key_transformation`).

---

### 大一小学期 Week 3 Python Exam 2016 Docs Misc Distributions (`大一小学期/Week_3-Python/exam/2016/docs/misc/distributions.txt`)

===================================
Third-party distributions of Django
===================================

Many third-party distributors are now providing versions of Django integrated
with their package-management systems. These can make installation and upgrading
much easier for users of Django since the integration includes the ability to
automatically install dependencies (like database adapters) that Django
requires.

Typically, these packages are based on the latest stable release of Django, so
if you want to use the development version of Django you'll need to follow the
instructions for :ref:`installing the development version
<installing-development-version>` from our Git repository.

If you're using Linux or a Unix installation, such as OpenSolaris,
check with your distributor to see if they already package Django. If
you're using a Linux distro and don't know how to find out if a package
is available, then now is a good time to learn.  The Django Wiki contains
a list of `Third Party Distributions`_ to help you out.

.. _`Third Party Distributions`: https://code.djangoproject.com/wiki/Distributions


For distributors
================

If you'd like to package Django for distribution, we'd be happy to help out!
Please join the |django-developers| mailing list and introduce yourself.

We also encourage all distributors to subscribe to the |django-announce| mailing
list, which is a (very) low-traffic list for announcing new releases of Django
and important bugfixes.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Misc Index (`大一小学期/Week_3-Python/exam/2016/docs/misc/index.txt`)

=================================
Meta-documentation and miscellany
=================================

Documentation that we can't find a more organized place for. Like that drawer in
your kitchen with the scissors, batteries, duct tape, and other junk.

.. toctree::
   :maxdepth: 2

   api-stability
   design-philosophies
   distributions

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Applications (`大一小学期/Week_3-Python/exam/2016/docs/ref/applications.txt`)

============
Applications
============

.. module:: django.apps

Django contains a registry of installed applications that stores configuration
and provides introspection. It also maintains a list of available :doc:`models
</topics/db/models>`.

This registry is simply called :attr:`~django.apps.apps` and it's available in
:mod:`django.apps`::

    >>> from django.apps import apps
    >>> apps.get_app_config('admin').verbose_name
    'Admin'

Projects and applications
=========================

The term **project** describes a Django web application. The project Python
package is defined primarily by a settings module, but it usually contains
other things. For example, when you run  ``django-admin startproject mysite``
you'll get a ``mysite`` project directory that contains a ``mysite`` Python
package with ``settings.py``, ``urls.py``, and ``wsgi.py``. The project package
is often extended to include things like fixtures, CSS, and templates which
aren't tied to a particular application.

A **project's root directory** (the one that contains ``manage.py``) is usually
the container for all of a project's applications which aren't installed
separately.

The term **application** describes a Python package that provides some set of
features. Applications :doc:`may be reused </intro/reusable-apps/>` in various
projects.

Applications include some combination of models, views, templates, template
tags, static files, URLs, middleware, etc. They're generally wired into
projects with the :setting:`INSTALLED_APPS` setting and optionally with other
mechanisms such as URLconfs, the :setting:`MIDDLEWARE` setting, or template
inheritance.

It is important to understand that a Django application is just a set of code
that interacts with various parts of the framework. There's no such thing as
an ``Application`` object. However, there's a few places where Django needs to
interact with installed applications, mainly for configuration and also for
introspection. That's why the application registry maintains metadata in an
:class:`~django.apps.AppConfig` instance for each installed application.

There's no restriction that a project package can't also be considered an
application and have models, etc. (which would require adding it to
:setting:`INSTALLED_APPS`).

.. _configuring-applications-ref:

Configuring applications
========================

To configure an application, subclass :class:`~django.apps.AppConfig` and put
the dotted path to that subclass in :setting:`INSTALLED_APPS`.

When :setting:`INSTALLED_APPS` simply contains the dotted path to an
application module, Django checks for a ``default_app_config`` variable in
that module.

If it's defined, it's the dotted path to the :class:`~django.apps.AppConfig`
subclass for that application.

If there is no ``default_app_config``, Django uses the base
:class:`~django.apps.AppConfig` class.

``default_app_config`` allows applications that predate Django 1.7 such as
``django.contrib.admin`` to opt-in to :class:`~django.apps.AppConfig` features
without requiring users to update their :setting:`INSTALLED_APPS`.

New applications should avoid ``default_app_config``. Instead they should
require the dotted path to the appropriate :class:`~django.apps.AppConfig`
subclass to be configured explicitly in :setting:`INSTALLED_APPS`.

For application authors
-----------------------

If you're creating a pluggable app called "Rock ’n’ roll", here's how you
would provide a proper name for the admin::

    # rock_n_roll/apps.py

    from django.apps import AppConfig

    class RockNRollConfig(AppConfig):
        name = 'rock_n_roll'
        verbose_name = "Rock ’n’ roll"

You can make your application load this :class:`~django.apps.AppConfig`
subclass by default as follows::

    # rock_n_roll/__init__.py

    default_app_config = 'rock_n_roll.apps.RockNRollConfig'

That will cause ``RockNRollConfig`` to be used when :setting:`INSTALLED_APPS`
just contains ``'rock_n_roll'``. This allows you to make use of
:class:`~django.apps.AppConfig` features without requiring your users to
update their :setting:`INSTALLED_APPS` setting. Besides this use case, it's
best to avoid using ``default_app_config`` and instead specify the app config
class in :setting:`INSTALLED_APPS` as described next.

Of course, you can also tell your users to put
``'rock_n_roll.apps.RockNRollConfig'`` in their :setting:`INSTALLED_APPS`
setting. You can even provide several different
:class:`~django.apps.AppConfig` subclasses with different behaviors and allow
your users to choose one via their :setting:`INSTALLED_APPS` setting.

The recommended convention is to put the configuration class in a submodule of
the application called ``apps``. However, this isn't enforced by Django.

You must include the :attr:`~django.apps.AppConfig.name` attribute for Django
to determine which application this configuration applies to. You can define
any attributes documented in the :class:`~django.apps.AppConfig` API
reference.

.. note::

    If your code imports the application registry in an application's
    ``__init__.py``, the name ``apps`` will clash with the ``apps`` submodule.
    The best practice is to move that code to a submodule and import it. A
    workaround is to import the registry under a different name::

        from django.apps import apps as django_apps

For application users
---------------------

If you're using "Rock ’n’ roll" in a project called ``anthology``, but you
want it to show up as "Jazz Manouche" instead, you can provide your own
configuration::

    # anthology/apps.py

    from rock_n_roll.apps import RockNRollConfig

    class JazzManoucheConfig(RockNRollConfig):
        verbose_name = "Jazz Manouche"

    # anthology/settings.py

    INSTALLED_APPS = [
        'anthology.apps.JazzManoucheConfig',
        # ...
    ]

Again, defining project-specific configuration classes in a submodule called
``apps`` is a convention, not a requirement.

Application configuration
=========================

.. class:: AppConfig

    Application configuration objects store metadata for an application. Some
    attributes can be configured in :class:`~django.apps.AppConfig`
    subclasses. Others are set by Django and read-only.

Configurable attributes
-----------------------

.. attribute:: AppConfig.name

    Full Python path to the application, e.g. ``'django.contrib.admin'``.

    This attribute defines which application the configuration applies to. It
    must be set in all :class:`~django.apps.AppConfig` subclasses.

    It must be unique across a Django project.

.. attribute:: AppConfig.label

    Short name for the application, e.g. ``'admin'``

    This attribute allows relabeling an application when two applications
    have conflicting labels. It defaults to the last component of ``name``.
    It should be a valid Python identifier.

    It must be unique across a Django project.

.. attribute:: AppConfig.verbose_name

    Human-readable name for the application, e.g. "Administration".

    This attribute defaults to ``label.title()``.

.. attribute:: AppConfig.path

    Filesystem path to the application directory, e.g.
    ``'/usr/lib/python3.4/dist-packages/django/contrib/admin'``.

    In most cases, Django can automatically detect and set this, but you can
    also provide an explicit override as a class attribute on your
    :class:`~django.apps.AppConfig` subclass. In a few situations this is
    required; for instance if the app package is a `namespace package`_ with
    multiple paths.

Read-only attributes
--------------------

.. attribute:: AppConfig.module

    Root module for the application, e.g. ``<module 'django.contrib.admin' from
    'django/contrib/admin/__init__.pyc'>``.

.. attribute:: AppConfig.models_module

    Module containing the models, e.g. ``<module 'django.contrib.admin.models'
    from 'django/contrib/admin/models.pyc'>``.

    It may be ``None`` if the application doesn't contain a ``models`` module.
    Note that the database related signals such as
    :data:`~django.db.models.signals.pre_migrate` and
    :data:`~django.db.models.signals.post_migrate`
    are only emitted for applications that have a ``models`` module.

Methods
-------

.. method:: AppConfig.get_models()

    Returns an iterable of :class:`~django.db.models.Model` classes for this
    application.

.. method:: AppConfig.get_model(model_name)

    Returns the :class:`~django.db.models.Model` with the given
    ``model_name``. Raises :exc:`LookupError` if no such model exists in this
    application. ``model_name`` is case-insensitive.

.. method:: AppConfig.ready()

    Subclasses can override this method to perform initialization tasks such
    as registering signals. It is called as soon as the registry is fully
    populated.

    Although you can't import models at the module-level where
    :class:`~django.apps.AppConfig` classes are defined, you can import them in
    ``ready()``, using either an ``import`` statement or
    :meth:`~AppConfig.get_model`.

    If you're registering :mod:`model signals <django.db.models.signals>`, you
    can refer to the sender by its string label instead of using the model
    class itself.

    Example::

        from django.db.models.signals import pre_save

        def ready(self):
            # importing model classes
            from .models import MyModel  # or...
            MyModel = self.get_model('MyModel')

            # registering signals with the model's string label
            pre_save.connect(receiver, sender='app_label.MyModel')

    .. warning::

        Although you can access model classes as described above, avoid
        interacting with the database in your :meth:`ready()` implementation.
        This includes model methods that execute queries
        (:meth:`~django.db.models.Model.save()`,
        :meth:`~django.db.models.Model.delete()`, manager methods etc.), and
        also raw SQL queries via ``django.db.connection``. Your
        :meth:`ready()` method will run during startup of every management
        command. For example, even though the test database configuration is
        separate from the production settings, ``manage.py test`` would still
        execute some queries against your **production** database!

    .. note::

        In the usual initialization process, the ``ready`` method is only called
        once by Django. But in some corner cases, particularly in tests which
        are fiddling with installed applications, ``ready`` might be called more
        than once. In that case, either write idempotent methods, or put a flag
        on your ``AppConfig`` classes to prevent re-running code which should
        be executed exactly one time.

.. _namespace package:

Namespace packages as apps (Python 3.3+)
----------------------------------------

Python versions 3.3 and later support Python packages without an
``__init__.py`` file. These packages are known as "namespace packages" and may
be spread across multiple directories at different locations on ``sys.path``
(see :pep:`420`).

Django applications require a single base filesystem path where Django
(depending on configuration) will search for templates, static assets,
etc. Thus, namespace packages may only be Django applications if one of the
following is true:

1. The namespace package actually has only a single location (i.e. is not
   spread across more than one directory.)

2. The :class:`~django.apps.AppConfig` class used to configure the application
   has a :attr:`~django.apps.AppConfig.path` class attribute, which is the
   absolute directory path Django will use as the single base path for the
   application.

If neither of these conditions is met, Django will raise
:exc:`~django.core.exceptions.ImproperlyConfigured`.

Application registry
====================

.. data:: apps

    The application registry provides the following public API. Methods that
    aren't listed below are considered private and may change without notice.

.. attribute:: apps.ready

    Boolean attribute that is set to ``True`` after the registry is fully
    populated and all :meth:`AppConfig.ready` methods are called.

.. method:: apps.get_app_configs()

    Returns an iterable of :class:`~django.apps.AppConfig` instances.

.. method:: apps.get_app_config(app_label)

    Returns an :class:`~django.apps.AppConfig` for the application with the
    given ``app_label``. Raises :exc:`LookupError` if no such application
    exists.

.. method:: apps.is_installed(app_name)

    Checks whether an application with the given name exists in the registry.
    ``app_name`` is the full name of the app, e.g. ``'django.contrib.admin'``.

.. method:: apps.get_model(app_label, model_name)

    Returns the :class:`~django.db.models.Model` with the given ``app_label``
    and ``model_name``. As a shortcut, this method also accepts a single
    argument in the form ``app_label.model_name``. ``model_name`` is case-
    insensitive.

    Raises :exc:`LookupError` if no such application or model exists. Raises
    :exc:`ValueError` when called with a single argument that doesn't contain
    exactly one dot.

Initialization process
======================

How applications are loaded
---------------------------

When Django starts, :func:`django.setup()` is responsible for populating the
application registry.

.. currentmodule:: django

.. function:: setup(set_prefix=True)

    Configures Django by:

    * Loading the settings.
    * Setting up logging.
    * If ``set_prefix`` is True, setting the URL resolver script prefix to
      :setting:`FORCE_SCRIPT_NAME` if defined, or ``/`` otherwise.
    * Initializing the application registry.

    .. versionchanged:: 1.10

        The ability to set the URL resolver script prefix is new.

    This function is called automatically:

    * When running an HTTP server via Django's WSGI support.
    * When invoking a management command.

    It must be called explicitly in other cases, for instance in plain Python
    scripts.

.. currentmodule:: django.apps

The application registry is initialized in three stages. At each stage, Django
processes all applications in the order of :setting:`INSTALLED_APPS`.

#. First Django imports each item in :setting:`INSTALLED_APPS`.

   If it's an application configuration class, Django imports the root package
   of the application, defined by its :attr:`~AppConfig.name` attribute. If
   it's a Python package, Django creates a default application configuration.

   *At this stage, your code shouldn't import any models!*

   In other words, your applications' root packages and the modules that
   define your application configuration classes shouldn't import any models,
   even indirectly.

   Strictly speaking, Django allows importing models once their application
   configuration is loaded. However, in order to avoid needless constraints on
   the order of :setting:`INSTALLED_APPS`, it's strongly recommended not
   import any models at this stage.

   Once this stage completes, APIs that operate on application configurations
   such as :meth:`~apps.get_app_config()` become usable.

#. Then Django attempts to import the ``models`` submodule of each application,
   if there is one.

   You must define or import all models in your application's ``models.py`` or
   ``models/__init__.py``. Otherwise, the application registry may not be fully
   populated at this point, which could cause the ORM to malfunction.

   Once this stage completes, APIs that operate on models such as
   :meth:`~apps.get_model()` become usable.

#. Finally Django runs the :meth:`~AppConfig.ready()` method of each application
   configuration.

.. _applications-troubleshooting:

Troubleshooting
---------------

Here are some common problems that you may encounter during initialization:

* ``AppRegistryNotReady`` This happens when importing an application
  configuration or a models module triggers code that depends on the app
  registry.

  For example, :func:`~django.utils.translation.ugettext()` uses the app
  registry to look up translation catalogs in applications. To translate at
  import time, you need :func:`~django.utils.translation.ugettext_lazy()`
  instead. (Using :func:`~django.utils.translation.ugettext()` would be a bug,
  because the translation would happen at import time, rather than at each
  request depending on the active language.)

  Executing database queries with the ORM at import time in models modules
  will also trigger this exception. The ORM cannot function properly until all
  models are available.

  Another common culprit is :func:`django.contrib.auth.get_user_model()`. Use
  the :setting:`AUTH_USER_MODEL` setting to reference the User model at import
  time.

  This exception also happens if you forget to call :func:`django.setup()` in
  a standalone Python script.

* ``ImportError: cannot import name ...`` This happens if the import sequence
  ends up in a loop.

  To eliminate such problems, you should minimize dependencies between your
  models modules and do as little work as possible at import time. To avoid
  executing code at import time, you can move it into a function and cache its
  results. The code will be executed when you first need its results. This
  concept is known as "lazy evaluation".

* ``django.contrib.admin`` automatically performs autodiscovery of ``admin``
  modules in installed applications. To prevent it, change your
  :setting:`INSTALLED_APPS` to contain
  ``'django.contrib.admin.apps.SimpleAdminConfig'`` instead of
  ``'django.contrib.admin'``.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Checks (`大一小学期/Week_3-Python/exam/2016/docs/ref/checks.txt`)

======================
System check framework
======================

.. currentmodule:: django.core.checks

The system check framework is a set of static checks for validating Django
projects. It detects common problems and provides hints for how to fix them.
The framework is extensible so you can easily add your own checks.

For details on how to add your own checks and integrate them with Django's
system checks, see the :doc:`System check topic guide </topics/checks>`.

API Reference
=============

``CheckMessage``
-----------------

.. class:: CheckMessage(level, msg, hint=None, obj=None, id=None)

The warnings and errors raised by system checks must be instances of
``CheckMessage``. An instance encapsulates a single reportable error or
warning. It also provides context and hints applicable to the message, and a
unique identifier that is used for filtering purposes.

Constructor arguments are:

``level``
    The severity of the message. Use one of the predefined values: ``DEBUG``,
    ``INFO``, ``WARNING``, ``ERROR``, ``CRITICAL``. If the level is greater or
    equal to ``ERROR``, then Django will prevent management commands from
    executing. Messages with level lower than ``ERROR`` (i.e. warnings) are
    reported to the console, but can be silenced.

``msg``
    A short (less than 80 characters) string describing the problem. The string
    should *not* contain newlines.

``hint``
    A single-line string providing a hint for fixing the problem. If no hint
    can be provided, or the hint is self-evident from the error message, the
    hint can be omitted, or a value of ``None`` can be used.

``obj``
    Optional. An object providing context for the message (for example, the
    model where the problem was discovered). The object should be a model,
    field, or manager or any other object that defines ``__str__`` method (on
    Python 2 you need to define ``__unicode__`` method). The method is used
    while reporting all messages and its result precedes the message.

``id``
    Optional string. A unique identifier for the issue. Identifiers should
    follow the pattern ``applabel.X001``, where ``X`` is one of the letters
    ``CEWID``, indicating the message severity (``C`` for criticals, ``E`` for
    errors and so). The number can be allocated by the application, but should
    be unique within that application.

There are subclasses to make creating messages with common levels easier. When
using them you can omit the ``level`` argument because it is implied by the
class name.

.. class:: Debug(msg, hint=None, obj=None, id=None)
.. class:: Info(msg, hint=None, obj=None, id=None)
.. class:: Warning(msg, hint=None obj=None, id=None)
.. class:: Error(msg, hint=None, obj=None, id=None)
.. class:: Critical(msg, hint=None, obj=None, id=None)

Builtin checks
==============

.. _system-check-builtin-tags:

Builtin tags
------------

Django's system checks are organized using the following tags:

* ``models``: Checks governing model, field and manager definitions.
* ``signals``: Checks on signal declarations and handler registrations.
* ``admin``: Checks of any admin site declarations.
* ``compatibility``: Flagging potential problems with version upgrades.
* ``security``: Checks security related configuration.
* ``templates``: Checks template related configuration.
* ``caches``: Checks cache related configuration.
* ``urls``: Checks URL configuration.
* ``database``: Checks database-related configuration issues. Database checks
  are not run by default because they do more than static code analysis as
  regular checks do. They are only run by the :djadmin:`migrate` command or if
  you specify the ``database`` tag when calling the :djadmin:`check` command.

.. versionadded:: 1.10

    The ``database`` tag was added.

Some checks may be registered with multiple tags.

Core system checks
------------------

Models
~~~~~~

* **models.E001**: ``<swappable>`` is not of the form ``app_label.app_name``.
* **models.E002**: ``<SETTING>`` references ``<model>``, which has not been
  installed, or is abstract.
* **models.E003**: The model has two many-to-many relations through the
  intermediate model ``<app_label>.<model>``.
* **models.E004**: ``id`` can only be used as a field name if the field also
  sets ``primary_key=True``.
* **models.E005**: The field ``<field name>`` from parent model ``<model>``
  clashes with the field ``<field name>`` from parent model ``<model>``.
* **models.E006**: The field clashes with the field ``<field name>`` from model
  ``<model>``.
* **models.E007**: Field ``<field name>`` has column name ``<column name>``
  that is used by another field.
* **models.E008**: ``index_together`` must be a list or tuple.
* **models.E009**: All ``index_together`` elements must be lists or tuples.
* **models.E010**: ``unique_together`` must be a list or tuple.
* **models.E011**: All ``unique_together`` elements must be lists or tuples.
* **models.E012**: ``index_together/unique_together`` refers to the
  non-existent field ``<field name>``.
* **models.E013**: ``index_together/unique_together`` refers to a
  ``ManyToManyField`` ``<field name>``, but ``ManyToManyField``\s are not
  supported for that option.
* **models.E014**: ``ordering`` must be a tuple or list (even if you want to
  order by only one field).
* **models.E015**: ``ordering`` refers to the non-existent field
  ``<field name>``.
* **models.E016**: ``index_together/unique_together`` refers to field
  ``<field_name>`` which is not local to model ``<model>``.
* **models.E017**: Proxy model ``<model>`` contains model fields.
* **models.E018**: Autogenerated column name too long for field ``<field>``.
  Maximum length is ``<maximum length>`` for database ``<alias>``.
* **models.E019**: Autogenerated column name too long for M2M field
  ``<M2M field>``. Maximum length is ``<maximum length>`` for database
  ``<alias>``.
* **models.E020**: The ``<model>.check()`` class method is currently overridden.
* **models.E021**: ``ordering`` and ``order_with_respect_to`` cannot be used
  together.
* **models.E022**: ``<function>`` contains a lazy reference to
  ``<app label>>.<model>``, but app ``<app label>`` isn't installed or
  doesn't provide model ``<model>``.

Fields
~~~~~~

* **fields.E001**: Field names must not end with an underscore.
* **fields.E002**: Field names must not contain ``"__"``.
* **fields.E003**: ``pk`` is a reserved word that cannot be used as a field
  name.
* **fields.E004**: ``choices`` must be an iterable (e.g., a list or tuple).
* **fields.E005**: ``choices`` must be an iterable returning ``(actual value,
  human readable name)`` tuples.
* **fields.E006**: ``db_index`` must be ``None``, ``True`` or ``False``.
* **fields.E007**: Primary keys must not have ``null=True``.
* **fields.E100**: ``AutoField``\s must set primary_key=True.
* **fields.E110**: ``BooleanField``\s do not accept null values.
* **fields.E120**: ``CharField``\s must define a ``max_length`` attribute.
* **fields.E121**: ``max_length`` must be a positive integer.
* **fields.W122**: ``max_length`` is ignored when used with ``IntegerField``.
* **fields.E130**: ``DecimalField``\s must define a ``decimal_places`` attribute.
* **fields.E131**: ``decimal_places`` must be a non-negative integer.
* **fields.E132**: ``DecimalField``\s must define a ``max_digits`` attribute.
* **fields.E133**: ``max_digits`` must be a non-negative integer.
* **fields.E134**: ``max_digits`` must be greater or equal to ``decimal_places``.
* **fields.E140**: ``FilePathField``\s must have either ``allow_files`` or
  ``allow_folders`` set to True.
* **fields.E150**: ``GenericIPAddressField``\s cannot accept blank values if
  null values are not allowed, as blank values are stored as nulls.
* **fields.E160**: The options ``auto_now``, ``auto_now_add``, and ``default``
  are mutually exclusive. Only one of these options may be present.
* **fields.W161**: Fixed default value provided.
* **fields.E900**: ``IPAddressField`` has been removed except for support in
  historical migrations.
* **fields.W900**: ``IPAddressField`` has been deprecated. Support for it
  (except in historical migrations) will be removed in Django 1.9. *This check
  appeared in Django 1.7 and 1.8*.
* **fields.W901**: ``CommaSeparatedIntegerField`` has been deprecated. Support
  for it (except in historical migrations) will be removed in Django 2.0.

File Fields
~~~~~~~~~~~

* **fields.E200**: ``unique`` is not a valid argument for a ``FileField``.
* **fields.E201**: ``primary_key`` is not a valid argument for a ``FileField``.
* **fields.E210**: Cannot use ``ImageField`` because Pillow is not installed.

Related Fields
~~~~~~~~~~~~~~

* **fields.E300**: Field defines a relation with model ``<model>``, which is
  either not installed, or is abstract.
* **fields.E301**: Field defines a relation with the model ``<model>`` which
  has been swapped out.
* **fields.E302**: Accessor for field ``<field name>`` clashes with field
  ``<field name>``.
* **fields.E303**: Reverse query name for field ``<field name>`` clashes with
  field ``<field name>``.
* **fields.E304**: Field name ``<field name>`` clashes with accessor for
  ``<field name>``.
* **fields.E305**: Field name ``<field name>`` clashes with reverse query name
  for ``<field name>``.
* **fields.E306**: Related name must be a valid Python identifier or end with
  a ``'+'``.
* **fields.E307**: The field ``<app label>.<model>.<field name>`` was declared
  with a lazy reference to ``<app label>.<model>``, but app ``<app label>``
  isn't installed or doesn't provide model ``<model>``.
* **fields.E310**: No subset of the fields ``<field1>``, ``<field2>``, ... on
  model ``<model>`` is unique. Add ``unique=True`` on any of those fields or
  add at least a subset of them to a unique_together constraint.
* **fields.E311**: ``<model>`` must set ``unique=True`` because it is
  referenced by a ``ForeignKey``.
* **fields.E320**: Field specifies ``on_delete=SET_NULL``, but cannot be null.
* **fields.E321**: The field specifies ``on_delete=SET_DEFAULT``, but has no
  default value.
* **fields.E330**: ``ManyToManyField``\s cannot be unique.
* **fields.E331**: Field specifies a many-to-many relation through model
  ``<model>``, which has not been installed.
* **fields.E332**: Many-to-many fields with intermediate tables must not be
  symmetrical.
* **fields.E333**: The model is used as an intermediate model by ``<model>``,
  but it has more than two foreign keys to ``<model>``, which is ambiguous.
  You must specify which two foreign keys Django should use via the
  ``through_fields`` keyword argument.
* **fields.E334**: The model is used as an intermediate model by ``<model>``,
  but it has more than one foreign key from ``<model>``, which is ambiguous.
  You must specify which foreign key Django should use via the
  ``through_fields`` keyword argument.
* **fields.E335**: The model is used as an intermediate model by ``<model>``,
  but it has more than one foreign key to ``<model>``, which is ambiguous.
  You must specify which foreign key Django should use via the
  ``through_fields`` keyword argument.
* **fields.E336**: The model is used as an intermediary model by ``<model>``,
  but it does not have foreign key to ``<model>`` or ``<model>``.
* **fields.E337**: Field specifies ``through_fields`` but does not provide the
  names of the two link fields that should be used for the relation through
  ``<model>``.
* **fields.E338**: The intermediary model ``<through model>`` has no field
  ``<field name>``.
* **fields.E339**: ``<model>.<field name>`` is not a foreign key to ``<model>``.
* **fields.W340**: ``null`` has no effect on ``ManyToManyField``.
* **fields.W341**: ``ManyToManyField`` does not support ``validators``.
* **fields.W342**: Setting ``unique=True`` on a ``ForeignKey`` has the same
  effect as using a ``OneToOneField``.

Signals
~~~~~~~

* **signals.E001**: ``<handler>`` was connected to the ``<signal>`` signal with
  a lazy reference to the sender ``<app label>.<model>``, but app ``<app label>``
  isn't installed or doesn't provide model ``<model>``.

Backwards Compatibility
~~~~~~~~~~~~~~~~~~~~~~~

The following checks are performed to warn the user of any potential problems
that might occur as a result of a version upgrade.

* **1_6.W001**: Some project unit tests may not execute as expected. *This
  check was removed in Django 1.8 due to false positives*.
* **1_6.W002**: ``BooleanField`` does not have a default value. *This
  check was removed in Django 1.8 due to false positives*.
* **1_7.W001**:  Django 1.7 changed the global defaults for the
  ``MIDDLEWARE_CLASSES.``
  ``django.contrib.sessions.middleware.SessionMiddleware``,
  ``django.contrib.auth.middleware.AuthenticationMiddleware``, and
  ``django.contrib.messages.middleware.MessageMiddleware`` were removed from
  the defaults. If your project needs these middleware then you should
  configure this setting. *This check was removed in Django 1.9*.
* **1_8.W001**: The standalone ``TEMPLATE_*`` settings were deprecated in
  Django 1.8 and the :setting:`TEMPLATES` dictionary takes precedence. You must
  put the values of the following settings into your defaults ``TEMPLATES``
  dict: ``TEMPLATE_DIRS``, ``TEMPLATE_CONTEXT_PROCESSORS``, ``TEMPLATE_DEBUG``,
  ``TEMPLATE_LOADERS``, ``TEMPLATE_STRING_IF_INVALID``.
* **1_10.W001**: The ``MIDDLEWARE_CLASSES`` setting is deprecated in Django
  1.10  and the :setting:`MIDDLEWARE` setting takes precedence. Since you've
  set ``MIDDLEWARE``, the value of ``MIDDLEWARE_CLASSES`` is ignored.

Admin
-----

Admin checks are all performed as part of the ``admin`` tag.

The following checks are performed on any
:class:`~django.contrib.admin.ModelAdmin` (or subclass) that is registered
with the admin site:

* **admin.E001**: The value of ``raw_id_fields`` must be a list or tuple.
* **admin.E002**: The value of ``raw_id_fields[n]`` refers to ``<field name>``,
  which is not an attribute of ``<model>``.
* **admin.E003**: The value of ``raw_id_fields[n]`` must be a foreign key or
  a many-to-many field.
* **admin.E004**: The value of ``fields`` must be a list or tuple.
* **admin.E005**: Both ``fieldsets`` and ``fields`` are specified.
* **admin.E006**: The value of ``fields`` contains duplicate field(s).
* **admin.E007**: The value of ``fieldsets`` must be a list or tuple.
* **admin.E008**: The value of ``fieldsets[n]`` must be a list or tuple.
* **admin.E009**: The value of ``fieldsets[n]`` must be of length 2.
* **admin.E010**: The value of ``fieldsets[n][1]`` must be a dictionary.
* **admin.E011**: The value of ``fieldsets[n][1]`` must contain the key
  ``fields``.
* **admin.E012**: There are duplicate field(s) in ``fieldsets[n][1]``.
* **admin.E013**: ``fields[n]/fieldsets[n][m]`` cannot include the
  ``ManyToManyField`` ``<field name>``, because that field manually specifies a
  relationship model.
* **admin.E014**: The value of ``exclude`` must be a list or tuple.
* **admin.E015**: The value of ``exclude`` contains duplicate field(s).
* **admin.E016**: The value of ``form`` must inherit from ``BaseModelForm``.
* **admin.E017**: The value of ``filter_vertical`` must be a list or tuple.
* **admin.E018**: The value of ``filter_horizontal`` must be a list or tuple.
* **admin.E019**: The value of ``filter_vertical[n]/filter_vertical[n]`` refers
  to ``<field name>``, which is not an attribute of ``<model>``.
* **admin.E020**: The value of ``filter_vertical[n]/filter_vertical[n]`` must
  be a many-to-many field.
* **admin.E021**: The value of ``radio_fields`` must be a dictionary.
* **admin.E022**: The value of ``radio_fields`` refers to ``<field name>``,
  which is not an attribute of ``<model>``.
* **admin.E023**: The value of ``radio_fields`` refers to ``<field name>``,
  which is not a ``ForeignKey``, and does not have a ``choices`` definition.
* **admin.E024**: The value of ``radio_fields[<field name>]`` must be either
  ``admin.HORIZONTAL`` or ``admin.VERTICAL``.
* **admin.E025**: The value of ``view_on_site`` must be either a callable or a
  boolean value.
* **admin.E026**: The value of ``prepopulated_fields`` must be a dictionary.
* **admin.E027**: The value of ``prepopulated_fields`` refers to
  ``<field name>``, which is not an attribute of ``<model>``.
* **admin.E028**: The value of ``prepopulated_fields`` refers to
  ``<field name>``, which must not be a ``DateTimeField``, a ``ForeignKey``, or a
  ``ManyToManyField`` field.
* **admin.E029**: The value of ``prepopulated_fields[<field name>]`` must be a
  list or tuple.
* **admin.E030**: The value of ``prepopulated_fields`` refers to
  ``<field name>``, which is not an attribute of ``<model>``.
* **admin.E031**: The value of ``ordering`` must be a list or tuple.
* **admin.E032**: The value of ``ordering`` has the random ordering marker
  ``?``, but contains other fields as well.
* **admin.E033**: The value of ``ordering`` refers to ``<field name>``, which
  is not an attribute of ``<model>``.
* **admin.E034**: The value of ``readonly_fields`` must be a list or tuple.
* **admin.E035**: The value of ``readonly_fields[n]`` is not a callable, an
  attribute of ``<ModelAdmin class>``, or an attribute of ``<model>``.

``ModelAdmin``
~~~~~~~~~~~~~~

The following checks are performed on any
:class:`~django.contrib.admin.ModelAdmin` that is registered
with the admin site:

* **admin.E101**: The value of ``save_as`` must be a boolean.
* **admin.E102**: The value of ``save_on_top`` must be a boolean.
* **admin.E103**: The value of ``inlines`` must be a list or tuple.
* **admin.E104**: ``<InlineModelAdmin class>`` must inherit from
  ``BaseModelAdmin``.
* **admin.E105**: ``<InlineModelAdmin class>`` must have a ``model`` attribute.
* **admin.E106**: The value of ``<InlineModelAdmin class>.model`` must be a
  ``Model``.
* **admin.E107**: The value of ``list_display`` must be a list or tuple.
* **admin.E108**: The value of ``list_display[n]`` refers to ``<label>``,
  which is not a callable, an attribute of ``<ModelAdmin class>``, or an
  attribute or method on ``<model>``.
* **admin.E109**: The value of ``list_display[n]`` must not be a
  ``ManyToManyField`` field.
* **admin.E110**: The value of ``list_display_links`` must be a list, a tuple,
  or ``None``.
* **admin.E111**: The value of ``list_display_links[n]`` refers to ``<label>``,
  which is not defined in ``list_display``.
* **admin.E112**: The value of ``list_filter`` must be a list or tuple.
* **admin.E113**: The value of ``list_filter[n]`` must inherit from
  ``ListFilter``.
* **admin.E114**: The value of ``list_filter[n]`` must not inherit from
  ``FieldListFilter``.
* **admin.E115**: The value of ``list_filter[n][1]`` must inherit from
  ``FieldListFilter``.
* **admin.E116**: The value of ``list_filter[n]`` refers to ``<label>``,
  which does not refer to a Field.
* **admin.E117**: The value of ``list_select_related`` must be a boolean,
  tuple or list.
* **admin.E118**: The value of ``list_per_page`` must be an integer.
* **admin.E119**: The value of ``list_max_show_all`` must be an integer.
* **admin.E120**: The value of ``list_editable`` must be a list or tuple.
* **admin.E121**: The value of ``list_editable[n]`` refers to ``<label>``,
  which is not an attribute of ``<model>``.
* **admin.E122**: The value of ``list_editable[n]`` refers to ``<label>``,
  which is not contained in ``list_display``.
* **admin.E123**: The value of ``list_editable[n]`` cannot be in both
  ``list_editable`` and ``list_display_links``.
* **admin.E124**: The value of ``list_editable[n]`` refers to the first field
  in ``list_display`` (``<label>``), which cannot be used unless
  ``list_display_links`` is set.
* **admin.E125**: The value of ``list_editable[n]`` refers to ``<field name>``,
  which is not editable through the admin.
* **admin.E126**: The value of ``search_fields`` must be a list or tuple.
* **admin.E127**: The value of ``date_hierarchy`` refers to ``<field name>``,
  which is not an attribute of ``<model>``.
* **admin.E128**: The value of ``date_hierarchy`` must be a ``DateField`` or
  ``DateTimeField``.

``InlineModelAdmin``
~~~~~~~~~~~~~~~~~~~~

The following checks are performed on any
:class:`~django.contrib.admin.InlineModelAdmin` that is registered as an
inline on a :class:`~django.contrib.admin.ModelAdmin`.

* **admin.E201**: Cannot exclude the field ``<field name>``, because it is the
  foreign key to the parent model ``<app_label>.<model>``.
* **admin.E202**: ``<model>`` has no ``ForeignKey`` to ``<parent model>``./
  ``<model>`` has more than one ``ForeignKey`` to ``<parent model>``.
* **admin.E203**: The value of ``extra`` must be an integer.
* **admin.E204**: The value of ``max_num`` must be an integer.
* **admin.E205**: The value of ``min_num`` must be an integer.
* **admin.E206**: The value of ``formset`` must inherit from
  ``BaseModelFormSet``.

``GenericInlineModelAdmin``
~~~~~~~~~~~~~~~~~~~~~~~~~~~

The following checks are performed on any
:class:`~django.contrib.contenttypes.admin.GenericInlineModelAdmin` that is
registered as an inline on a :class:`~django.contrib.admin.ModelAdmin`.

* **admin.E301**: ``'ct_field'`` references ``<label>``, which is not a field
  on ``<model>``.
* **admin.E302**: ``'ct_fk_field'`` references ``<label>``, which is not a
  field on ``<model>``.
* **admin.E303**: ``<model>`` has no ``GenericForeignKey``.
* **admin.E304**: ``<model>`` has no ``GenericForeignKey`` using content type
  field ``<field name>`` and object ID field ``<field name>``.

``AdminSite``
~~~~~~~~~~~~~

The following checks are performed on the default
:class:`~django.contrib.admin.AdminSite`:

* **admin.E401**: :mod:`django.contrib.contenttypes` must be in
  :setting:`INSTALLED_APPS` in order to use the admin application.
* **admin.E402**: :mod:`django.contrib.auth.context_processors.auth`
  must be in :setting:`TEMPLATES` in order to use the admin application.

Auth
----

* **auth.E001**: ``REQUIRED_FIELDS`` must be a list or tuple.
* **auth.E002**: The field named as the ``USERNAME_FIELD`` for a custom user
  model must not be included in ``REQUIRED_FIELDS``.
* **auth.E003**: ``<field>`` must be unique because it is named as the
  ``USERNAME_FIELD``.
* **auth.W004**: ``<field>`` is named as the ``USERNAME_FIELD``, but it is not
  unique.
* **auth.E005**: The permission codenamed ``<codename>`` clashes with a builtin
  permission for model ``<model>``.
* **auth.E006**: The permission codenamed ``<codename>`` is duplicated for model
  ``<model>``.
* **auth.E007**: The :attr:`verbose_name
  <django.db.models.Options.verbose_name>` of model ``<model>`` must be at most
  244 characters for its builtin permission names
  to be at most 255 characters.
* **auth.E008**: The permission named ``<name>`` of model ``<model>`` is longer
  than 255 characters.
* **auth.C009**: ``<User model>.is_anonymous`` must be an attribute or property
  rather than a method. Ignoring this is a security issue as anonymous users
  will be treated as authenticated!
* **auth.C010**: ``<User model>.is_authenticated`` must be an attribute or
  property rather than a method. Ignoring this is a security issue as anonymous
  users will be treated as authenticated!


Content Types
-------------

The following checks are performed when a model contains a
:class:`~django.contrib.contenttypes.fields.GenericForeignKey` or
:class:`~django.contrib.contenttypes.fields.GenericRelation`:

* **contenttypes.E001**: The ``GenericForeignKey`` object ID references the
  non-existent field ``<field>``.
* **contenttypes.E002**: The ``GenericForeignKey`` content type references the
  non-existent field ``<field>``.
* **contenttypes.E003**: ``<field>`` is not a ``ForeignKey``.
* **contenttypes.E004**: ``<field>`` is not a ``ForeignKey`` to
  ``contenttypes.ContentType``.

Security
--------

The security checks do not make your site secure. They do not audit code, do
intrusion detection, or do anything particularly complex. Rather, they help
perform an automated, low-hanging-fruit checklist. They help you remember the
simple things that improve your site's security.

Some of these checks may not be appropriate for your particular deployment
configuration. For instance, if you do your HTTP to HTTPS redirection in a load
balancer, it'd be irritating to be constantly warned about not having enabled
:setting:`SECURE_SSL_REDIRECT`. Use :setting:`SILENCED_SYSTEM_CHECKS` to
silence unneeded checks.

The following checks are run if you use the :option:`check --deploy` option:

* **security.W001**: You do not have
  :class:`django.middleware.security.SecurityMiddleware` in your
  :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES` so the :setting:`SECURE_HSTS_SECONDS`,
  :setting:`SECURE_CONTENT_TYPE_NOSNIFF`, :setting:`SECURE_BROWSER_XSS_FILTER`,
  and :setting:`SECURE_SSL_REDIRECT` settings will have no effect.
* **security.W002**: You do not have
  :class:`django.middleware.clickjacking.XFrameOptionsMiddleware` in your
  :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`, so your pages will not be served with an
  ``'x-frame-options'`` header. Unless there is a good reason for your
  site to be served in a frame, you should consider enabling this
  header to help prevent clickjacking attacks.
* **security.W003**: You don't appear to be using Django's built-in cross-site
  request forgery protection via the middleware
  (:class:`django.middleware.csrf.CsrfViewMiddleware` is not in your
  :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`). Enabling the middleware is the safest
  approach to ensure you don't leave any holes.
* **security.W004**: You have not set a value for the
  :setting:`SECURE_HSTS_SECONDS` setting. If your entire site is served only
  over SSL, you may want to consider setting a value and enabling :ref:`HTTP
  Strict Transport Security <http-strict-transport-security>`. Be sure to read
  the documentation first; enabling HSTS carelessly can cause serious,
  irreversible problems.
* **security.W005**: You have not set the
  :setting:`SECURE_HSTS_INCLUDE_SUBDOMAINS` setting to ``True``. Without this,
  your site is potentially vulnerable to attack via an insecure connection to a
  subdomain. Only set this to ``True`` if you are certain that all subdomains of
  your domain should be served exclusively via SSL.
* **security.W006**: Your :setting:`SECURE_CONTENT_TYPE_NOSNIFF` setting is not
  set to ``True``, so your pages will not be served with an
  ``'x-content-type-options: nosniff'`` header. You should consider enabling
  this header to prevent the browser from identifying content types incorrectly.
* **security.W007**: Your :setting:`SECURE_BROWSER_XSS_FILTER` setting is not
  set to ``True``, so your pages will not be served with an
  ``'x-xss-protection: 1; mode=block'`` header. You should consider enabling
  this header to activate the browser's XSS filtering and help prevent XSS
  attacks.
* **security.W008**: Your :setting:`SECURE_SSL_REDIRECT` setting is not set to
  ``True``. Unless your site should be available over both SSL and non-SSL
  connections, you may want to either set this setting to ``True`` or configure
  a load balancer or reverse-proxy server  to redirect all connections to HTTPS.
* **security.W009**: Your :setting:`SECRET_KEY` has less than 50 characters or
  less than 5 unique characters. Please generate a long and random
  ``SECRET_KEY``, otherwise many of Django's security-critical features will be
  vulnerable to attack.
* **security.W010**: You have :mod:`django.contrib.sessions` in your
  :setting:`INSTALLED_APPS` but you have not set
  :setting:`SESSION_COOKIE_SECURE` to ``True``. Using a secure-only session
  cookie makes it more difficult for network traffic sniffers to hijack user
  sessions.
* **security.W011**: You have
  :class:`django.contrib.sessions.middleware.SessionMiddleware` in your
  :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`, but you have not set
  :setting:`SESSION_COOKIE_SECURE` to ``True``. Using a secure-only session
  cookie makes it more difficult for network traffic sniffers to hijack user
  sessions.
* **security.W012**: :setting:`SESSION_COOKIE_SECURE` is not set to ``True``.
  Using a secure-only session cookie makes it more difficult for network traffic
  sniffers to hijack user sessions.
* **security.W013**: You have :mod:`django.contrib.sessions` in your
  :setting:`INSTALLED_APPS`, but you have not set
  :setting:`SESSION_COOKIE_HTTPONLY` to ``True``. Using an ``HttpOnly`` session
  cookie makes it more difficult for cross-site scripting attacks to hijack user
  sessions.
* **security.W014**: You have
  :class:`django.contrib.sessions.middleware.SessionMiddleware` in your
  :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`, but you have not set
  :setting:`SESSION_COOKIE_HTTPONLY` to ``True``. Using an ``HttpOnly`` session
  cookie makes it more difficult for cross-site scripting attacks to hijack user
  sessions.
* **security.W015**: :setting:`SESSION_COOKIE_HTTPONLY` is not set to ``True``.
  Using an ``HttpOnly`` session cookie makes it more difficult for cross-site
  scripting attacks to hijack user sessions.
* **security.W016**: :setting:`CSRF_COOKIE_SECURE` is not set to ``True``.
  Using a secure-only CSRF cookie makes it more difficult for network traffic
  sniffers to steal the CSRF token.
* **security.W017**: :setting:`CSRF_COOKIE_HTTPONLY` is not set to ``True``.
  Using an ``HttpOnly`` CSRF cookie makes it more difficult for cross-site
  scripting attacks to steal the CSRF token.
* **security.W018**: You should not have :setting:`DEBUG` set to ``True`` in
  deployment.
* **security.W019**: You have
  :class:`django.middleware.clickjacking.XFrameOptionsMiddleware` in your
  :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`, but :setting:`X_FRAME_OPTIONS` is not set to
  ``'DENY'``. The default is ``'SAMEORIGIN'``, but unless there is a good reason
  for your site to serve other parts of itself in a frame, you should change
  it to ``'DENY'``.
* **security.W020**: :setting:`ALLOWED_HOSTS` must not be empty in deployment.

Sites
-----

The following checks are performed on any model using a
:class:`~django.contrib.sites.managers.CurrentSiteManager`:

* **sites.E001**: ``CurrentSiteManager`` could not find a field named
  ``<field name>``.
* **sites.E002**: ``CurrentSiteManager`` cannot use ``<field>`` as it is not a
  foreign key or a many-to-many field.

Database
--------

MySQL
~~~~~

If you're using MySQL, the following checks will be performed:

* **mysql.E001**: MySQL does not allow unique ``CharField``\s to have a
  ``max_length`` > 255.
* **mysql.W002**: MySQL Strict Mode is not set for database connection
  '<alias>'. See also :ref:`mysql-sql-mode`.

Templates
---------

The following checks verify that your :setting:`TEMPLATES` setting is correctly
configured:

* **templates.E001**: You have ``'APP_DIRS': True`` in your
  :setting:`TEMPLATES` but also specify ``'loaders'`` in ``OPTIONS``. Either
  remove ``APP_DIRS`` or remove the ``'loaders'`` option.
* **templates.E002**: ``string_if_invalid`` in :setting:`TEMPLATES`
  :setting:`OPTIONS <TEMPLATES-OPTIONS>` must be a string but got: ``{value}``
  (``{type}``).

Caches
------

The following checks verify that your :setting:`CACHES` setting is correctly
configured:

* **caches.E001**: You must define a ``'default'`` cache in your
  :setting:`CACHES` setting.

URLs
----

The following checks are performed on your URL configuration:

* **urls.W001**: Your URL pattern ``<pattern>`` uses
  :func:`~django.conf.urls.include` with a ``regex`` ending with a
  ``$``. Remove the dollar from the ``regex`` to avoid problems
  including URLs.
* **urls.W002**: Your URL pattern ``<pattern>`` has a ``regex``
  beginning with a ``/``. Remove this slash as it is unnecessary.
  If this pattern is targeted in an :func:`~django.conf.urls.include`, ensure
  the :func:`~django.conf.urls.include` pattern has a trailing ``/``.
* **urls.W003**: Your URL pattern ``<pattern>`` has a ``name``
  including a ``:``. Remove the colon, to avoid ambiguous namespace
  references.
* **urls.E004**: Your URL pattern ``<pattern>`` is invalid. Ensure that
  ``urlpatterns`` is a list of :func:`~django.conf.urls.url()` instances.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Clickjacking (`大一小学期/Week_3-Python/exam/2016/docs/ref/clickjacking.txt`)

========================
Clickjacking Protection
========================

.. module:: django.middleware.clickjacking
   :synopsis: Protects against Clickjacking

The clickjacking middleware and decorators provide easy-to-use protection
against `clickjacking`_.  This type of attack occurs when a malicious site
tricks a user into clicking on a concealed element of another site which they
have loaded in a hidden frame or iframe.

.. _clickjacking: https://en.wikipedia.org/wiki/Clickjacking

An example of clickjacking
==========================

Suppose an online store has a page where a logged in user can click "Buy Now" to
purchase an item. A user has chosen to stay logged into the store all the time
for convenience. An attacker site might create an "I Like Ponies" button on one
of their own pages, and load the store's page in a transparent iframe such that
the "Buy Now" button is invisibly overlaid on the "I Like Ponies" button. If the
user visits the attacker's site, clicking "I Like Ponies" will cause an
inadvertent click on the "Buy Now" button and an unknowing purchase of the item.

.. _clickjacking-prevention:

Preventing clickjacking
=======================

Modern browsers honor the `X-Frame-Options`_ HTTP header that indicates whether
or not a resource is allowed to load within a frame or iframe. If the response
contains the header with a value of ``SAMEORIGIN`` then the browser will only
load the resource in a frame if the request originated from the same site. If
the header is set to ``DENY`` then the browser will block the resource from
loading in a frame no matter which site made the request.

.. _X-Frame-Options: https://developer.mozilla.org/en-US/docs/Web/HTTP/X-Frame-Options

Django provides a few simple ways to include this header in responses from your
site:

1. A simple middleware that sets the header in all responses.

2. A set of view decorators that can be used to override the middleware or to
   only set the header for certain views.

The ``X-Frame-Options`` HTTP header will only be set by the middleware or view
decorators if it is not already present in the response.

How to use it
=============

Setting ``X-Frame-Options`` for all responses
---------------------------------------------

To set the same ``X-Frame-Options`` value for all responses in your site, put
``'django.middleware.clickjacking.XFrameOptionsMiddleware'`` to
:setting:`MIDDLEWARE`::

    MIDDLEWARE = [
        ...
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        ...
    ]

This middleware is enabled in the settings file generated by
:djadmin:`startproject`.

By default, the middleware will set the ``X-Frame-Options`` header to
``SAMEORIGIN`` for every outgoing ``HttpResponse``. If you want ``DENY``
instead, set the :setting:`X_FRAME_OPTIONS` setting::

    X_FRAME_OPTIONS = 'DENY'

When using the middleware there may be some views where you do **not** want the
``X-Frame-Options`` header set. For those cases, you can use a view decorator
that tells the middleware not to set the header::

    from django.http import HttpResponse
    from django.views.decorators.clickjacking import xframe_options_exempt

    @xframe_options_exempt
    def ok_to_load_in_a_frame(request):
        return HttpResponse("This page is safe to load in a frame on any site.")


Setting ``X-Frame-Options`` per view
------------------------------------

To set the ``X-Frame-Options`` header on a per view basis, Django provides these
decorators::

    from django.http import HttpResponse
    from django.views.decorators.clickjacking import xframe_options_deny
    from django.views.decorators.clickjacking import xframe_options_sameorigin

    @xframe_options_deny
    def view_one(request):
        return HttpResponse("I won't display in any frame!")

    @xframe_options_sameorigin
    def view_two(request):
        return HttpResponse("Display in a frame if it's from the same origin as me.")

Note that you can use the decorators in conjunction with the middleware. Use of
a decorator overrides the middleware.

Limitations
===========

The ``X-Frame-Options`` header will only protect against clickjacking in a
modern browser. Older browsers will quietly ignore the header and need `other
clickjacking prevention techniques`_.

Browsers that support ``X-Frame-Options``
-----------------------------------------

* Internet Explorer 8+
* Firefox 3.6.9+
* Opera 10.5+
* Safari 4+
* Chrome 4.1+

See also
--------

A `complete list`_ of browsers supporting ``X-Frame-Options``.

.. _complete list: https://developer.mozilla.org/en-US/docs/Web/HTTP/X-Frame-Options#Browser_compatibility
.. _other clickjacking prevention techniques: https://en.wikipedia.org/wiki/Clickjacking#Prevention

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Csrf (`大一小学期/Week_3-Python/exam/2016/docs/ref/csrf.txt`)

=====================================
Cross Site Request Forgery protection
=====================================

.. module:: django.middleware.csrf
   :synopsis: Protects against Cross Site Request Forgeries

The CSRF middleware and template tag provides easy-to-use protection against
`Cross Site Request Forgeries`_.  This type of attack occurs when a malicious
website contains a link, a form button or some JavaScript that is intended to
perform some action on your website, using the credentials of a logged-in user
who visits the malicious site in their browser.  A related type of attack,
'login CSRF', where an attacking site tricks a user's browser into logging into
a site with someone else's credentials, is also covered.

The first defense against CSRF attacks is to ensure that GET requests (and other
'safe' methods, as defined by :rfc:`7231#section-4.2.1`) are side effect free.
Requests via 'unsafe' methods, such as POST, PUT, and DELETE, can then be
protected by following the steps below.

.. _Cross Site Request Forgeries: https://www.squarefree.com/securitytips/web-developers.html#CSRF

.. _using-csrf:

How to use it
=============

To take advantage of CSRF protection in your views, follow these steps:

1. The CSRF middleware is activated by default in the :setting:`MIDDLEWARE`
   setting. If you override that setting, remember that
   ``'django.middleware.csrf.CsrfViewMiddleware'`` should come before any view
   middleware that assume that CSRF attacks have been dealt with.

   If you disabled it, which is not recommended, you can use
   :func:`~django.views.decorators.csrf.csrf_protect` on particular views
   you want to protect (see below).

2. In any template that uses a POST form, use the :ttag:`csrf_token` tag inside
   the ``<form>`` element if the form is for an internal URL, e.g.:

   .. code-block:: html+django

       <form action="" method="post">{% csrf_token %}

   This should not be done for POST forms that target external URLs, since
   that would cause the CSRF token to be leaked, leading to a vulnerability.

3. In the corresponding view functions, ensure that
   :class:`~django.template.RequestContext` is used to render the response so
   that ``{% csrf_token %}`` will work properly. If you're using the
   :func:`~django.shortcuts.render` function, generic views, or contrib apps,
   you are covered already since these all use ``RequestContext``.

.. _csrf-ajax:

AJAX
----

While the above method can be used for AJAX POST requests, it has some
inconveniences: you have to remember to pass the CSRF token in as POST data with
every POST request. For this reason, there is an alternative method: on each
XMLHttpRequest, set a custom ``X-CSRFToken`` header to the value of the CSRF
token. This is often easier, because many JavaScript frameworks provide hooks
that allow headers to be set on every request.

As a first step, you must get the CSRF token itself. The recommended source for
the token is the ``csrftoken`` cookie, which will be set if you've enabled CSRF
protection for your views as outlined above.

.. note::

    The CSRF token cookie is named ``csrftoken`` by default, but you can control
    the cookie name via the :setting:`CSRF_COOKIE_NAME` setting.

    The CSRF header name is ``HTTP_X_CSRFTOKEN`` by default, but you can
    customize it using the :setting:`CSRF_HEADER_NAME` setting.

Acquiring the token is straightforward:

.. code-block:: javascript

    // using jQuery
    function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    var csrftoken = getCookie('csrftoken');

The above code could be simplified by using the `JavaScript Cookie library
<https://github.com/js-cookie/js-cookie/>`_ to replace ``getCookie``:

.. code-block:: javascript

    var csrftoken = Cookies.get('csrftoken');

.. note::

    The CSRF token is also present in the DOM, but only if explicitly included
    using :ttag:`csrf_token` in a template. The cookie contains the canonical
    token; the ``CsrfViewMiddleware`` will prefer the cookie to the token in
    the DOM. Regardless, you're guaranteed to have the cookie if the token is
    present in the DOM, so you should use the cookie!

.. warning::

    If your view is not rendering a template containing the :ttag:`csrf_token`
    template tag, Django might not set the CSRF token cookie. This is common in
    cases where forms are dynamically added to the page. To address this case,
    Django provides a view decorator which forces setting of the cookie:
    :func:`~django.views.decorators.csrf.ensure_csrf_cookie`.

Finally, you'll have to actually set the header on your AJAX request, while
protecting the CSRF token from being sent to other domains using
`settings.crossDomain <https://api.jquery.com/jQuery.ajax>`_ in jQuery 1.5.1 and
newer:

.. code-block:: javascript

    function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    $.ajaxSetup({
        beforeSend: function(xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrftoken);
            }
        }
    });

If you're using AngularJS 1.1.3 and newer, it's sufficient to configure the
``$http`` provider with the cookie and header names:

.. code-block:: javascript

    $httpProvider.defaults.xsrfCookieName = 'csrftoken';
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';

Using CSRF in Jinja2 templates
------------------------------

Django's :class:`~django.template.backends.jinja2.Jinja2` template backend
adds ``{{ csrf_input }}`` to the context of all templates which is equivalent
to ``{% csrf_token %}`` in the Django template language. For example:

.. code-block:: html+jinja

    <form action="" method="post">{{ csrf_input }}

The decorator method
--------------------

.. module:: django.views.decorators.csrf

Rather than adding ``CsrfViewMiddleware`` as a blanket protection, you can use
the ``csrf_protect`` decorator, which has exactly the same functionality, on
particular views that need the protection. It must be used **both** on views
that insert the CSRF token in the output, and on those that accept the POST form
data. (These are often the same view function, but not always).

Use of the decorator by itself is **not recommended**, since if you forget to
use it, you will have a security hole. The 'belt and braces' strategy of using
both is fine, and will incur minimal overhead.

.. function:: csrf_protect(view)

    Decorator that provides the protection of ``CsrfViewMiddleware`` to a view.

    Usage::

        from django.views.decorators.csrf import csrf_protect
        from django.shortcuts import render

        @csrf_protect
        def my_view(request):
            c = {}
            # ...
            return render(request, "a_template.html", c)

    If you are using class-based views, you can refer to
    :ref:`Decorating class-based views<decorating-class-based-views>`.

Rejected requests
=================

By default, a '403 Forbidden' response is sent to the user if an incoming
request fails the checks performed by ``CsrfViewMiddleware``.  This should
usually only be seen when there is a genuine Cross Site Request Forgery, or
when, due to a programming error, the CSRF token has not been included with a
POST form.

The error page, however, is not very friendly, so you may want to provide your
own view for handling this condition.  To do this, simply set the
:setting:`CSRF_FAILURE_VIEW` setting.

CSRF failures are logged as warnings to the :ref:`django-request-logger`
logger.

.. _how-csrf-works:

How it works
============

The CSRF protection is based on the following things:

1. A CSRF cookie that is based on a random secret value, which other sites
   will not have access to.

   This cookie is set by ``CsrfViewMiddleware``. It is sent with every
   response that has called ``django.middleware.csrf.get_token()`` (the
   function used internally to retrieve the CSRF token), if it wasn't already
   set on the request.

   In order to protect against `BREACH`_ attacks, the token is not simply the
   secret; a random salt is prepended to the secret and used to scramble it.

   For security reasons, the value of the secret is changed each time a
   user logs in.

2. A hidden form field with the name 'csrfmiddlewaretoken' present in all
   outgoing POST forms. The value of this field is, again, the value of the
   secret, with a salt which is both added to it and used to scramble it. The
   salt is regenerated on every call to ``get_token()`` so that the form field
   value is changed in every such response.

   This part is done by the template tag.

3. For all incoming requests that are not using HTTP GET, HEAD, OPTIONS or
   TRACE, a CSRF cookie must be present, and the 'csrfmiddlewaretoken' field
   must be present and correct. If it isn't, the user will get a 403 error.

   When validating the 'csrfmiddlewaretoken' field value, only the secret,
   not the full token, is compared with the secret in the cookie value.
   This allows the use of ever-changing tokens. While each request may use its
   own token, the secret remains common to all.

   This check is done by ``CsrfViewMiddleware``.

4. In addition, for HTTPS requests, strict referer checking is done by
   ``CsrfViewMiddleware``. This means that even if a subdomain can set or
   modify cookies on your domain, it can't force a user to post to your
   application since that request won't come from your own exact domain.

   This also addresses a man-in-the-middle attack that's possible under HTTPS
   when using a session independent secret, due to the fact that HTTP
   ``Set-Cookie`` headers are (unfortunately) accepted by clients even when
   they are talking to a site under HTTPS. (Referer checking is not done for
   HTTP requests because the presence of the ``Referer`` header isn't reliable
   enough under HTTP.)

   If the :setting:`CSRF_COOKIE_DOMAIN` setting is set, the referer is compared
   against it. This setting supports subdomains. For example,
   ``CSRF_COOKIE_DOMAIN = '.example.com'`` will allow POST requests from
   ``www.example.com`` and ``api.example.com``. If the setting is not set, then
   the referer must match the HTTP ``Host`` header.

   Expanding the accepted referers beyond the current host or cookie domain can
   be done with the :setting:`CSRF_TRUSTED_ORIGINS` setting.

This ensures that only forms that have originated from trusted domains can be
used to POST data back.

It deliberately ignores GET requests (and other requests that are defined as
'safe' by :rfc:`7231`). These requests ought never to have any potentially
dangerous side effects , and so a CSRF attack with a GET request ought to be
harmless. :rfc:`7231` defines POST, PUT, and DELETE as 'unsafe', and all other
methods are also assumed to be unsafe, for maximum protection.

The CSRF protection cannot protect against man-in-the-middle attacks, so use
:ref:`HTTPS <security-recommendation-ssl>` with
:ref:`http-strict-transport-security`. It also assumes :ref:`validation of
the HOST header <host-headers-virtual-hosting>` and that there aren't any
:ref:`cross-site scripting vulnerabilities <cross-site-scripting>` on your site
(because XSS vulnerabilities already let an attacker do anything a CSRF
vulnerability allows and much worse).

.. versionchanged:: 1.9

    Checking against the :setting:`CSRF_COOKIE_DOMAIN` setting was added.

.. versionchanged:: 1.10

   Added salting to the token and started changing it with each request
   to protect against `BREACH`_ attacks.

.. _BREACH: http://breachattack.com/

Caching
=======

If the :ttag:`csrf_token` template tag is used by a template (or the
``get_token`` function is called some other way), ``CsrfViewMiddleware`` will
add a cookie and a ``Vary: Cookie`` header to the response. This means that the
middleware will play well with the cache middleware if it is used as instructed
(``UpdateCacheMiddleware`` goes before all other middleware).

However, if you use cache decorators on individual views, the CSRF middleware
will not yet have been able to set the Vary header or the CSRF cookie, and the
response will be cached without either one. In this case, on any views that
will require a CSRF token to be inserted you should use the
:func:`django.views.decorators.csrf.csrf_protect` decorator first::

  from django.views.decorators.cache import cache_page
  from django.views.decorators.csrf import csrf_protect

  @cache_page(60 * 15)
  @csrf_protect
  def my_view(request):
      ...

If you are using class-based views, you can refer to :ref:`Decorating
class-based views<decorating-class-based-views>`.

Testing
=======

The ``CsrfViewMiddleware`` will usually be a big hindrance to testing view
functions, due to the need for the CSRF token which must be sent with every POST
request.  For this reason, Django's HTTP client for tests has been modified to
set a flag on requests which relaxes the middleware and the ``csrf_protect``
decorator so that they no longer rejects requests.  In every other respect
(e.g. sending cookies etc.), they behave the same.

If, for some reason, you *want* the test client to perform CSRF
checks, you can create an instance of the test client that enforces
CSRF checks::

    >>> from django.test import Client
    >>> csrf_client = Client(enforce_csrf_checks=True)

.. _csrf-limitations:

Limitations
===========

Subdomains within a site will be able to set cookies on the client for the whole
domain.  By setting the cookie and using a corresponding token, subdomains will
be able to circumvent the CSRF protection.  The only way to avoid this is to
ensure that subdomains are controlled by trusted users (or, are at least unable
to set cookies).  Note that even without CSRF, there are other vulnerabilities,
such as session fixation, that make giving subdomains to untrusted parties a bad
idea, and these vulnerabilities cannot easily be fixed with current browsers.

Edge cases
==========

Certain views can have unusual requirements that mean they don't fit the normal
pattern envisaged here. A number of utilities can be useful in these
situations. The scenarios they might be needed in are described in the following
section.

Utilities
---------

The examples below assume you are using function-based views. If you
are working with class-based views, you can refer to :ref:`Decorating
class-based views<decorating-class-based-views>`.

.. function:: csrf_exempt(view)

    This decorator marks a view as being exempt from the protection ensured by
    the middleware. Example::

        from django.views.decorators.csrf import csrf_exempt
        from django.http import HttpResponse

        @csrf_exempt
        def my_view(request):
            return HttpResponse('Hello world')

.. function:: requires_csrf_token(view)

    Normally the :ttag:`csrf_token` template tag will not work if
    ``CsrfViewMiddleware.process_view`` or an equivalent like ``csrf_protect``
    has not run. The view decorator ``requires_csrf_token`` can be used to
    ensure the template tag does work. This decorator works similarly to
    ``csrf_protect``, but never rejects an incoming request.

    Example::

        from django.views.decorators.csrf import requires_csrf_token
        from django.shortcuts import render

        @requires_csrf_token
        def my_view(request):
            c = {}
            # ...
            return render(request, "a_template.html", c)

.. function:: ensure_csrf_cookie(view)

    This decorator forces a view to send the CSRF cookie.

Scenarios
---------

CSRF protection should be disabled for just a few views
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Most views requires CSRF protection, but a few do not.

Solution: rather than disabling the middleware and applying ``csrf_protect`` to
all the views that need it, enable the middleware and use
:func:`~django.views.decorators.csrf.csrf_exempt`.

CsrfViewMiddleware.process_view not used
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

There are cases when ``CsrfViewMiddleware.process_view`` may not have run
before your view is run - 404 and 500 handlers, for example - but you still
need the CSRF token in a form.

Solution: use :func:`~django.views.decorators.csrf.requires_csrf_token`

Unprotected view needs the CSRF token
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

There may be some views that are unprotected and have been exempted by
``csrf_exempt``, but still need to include the CSRF token.

Solution: use :func:`~django.views.decorators.csrf.csrf_exempt` followed by
:func:`~django.views.decorators.csrf.requires_csrf_token`. (i.e. ``requires_csrf_token``
should be the innermost decorator).

View needs protection for one path
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A view needs CSRF protection under one set of conditions only, and mustn't have
it for the rest of the time.

Solution: use :func:`~django.views.decorators.csrf.csrf_exempt` for the whole
view function, and :func:`~django.views.decorators.csrf.csrf_protect` for the
path within it that needs protection. Example::

    from django.views.decorators.csrf import csrf_exempt, csrf_protect

    @csrf_exempt
    def my_view(request):

        @csrf_protect
        def protected_path(request):
            do_something()

        if some_condition():
           return protected_path(request)
        else:
           do_something_else()

Page uses AJAX without any HTML form
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A page makes a POST request via AJAX, and the page does not have an HTML form
with a :ttag:`csrf_token` that would cause the required CSRF cookie to be sent.

Solution: use :func:`~django.views.decorators.csrf.ensure_csrf_cookie` on the
view that sends the page.

Contrib and reusable apps
=========================

Because it is possible for the developer to turn off the ``CsrfViewMiddleware``,
all relevant views in contrib apps use the ``csrf_protect`` decorator to ensure
the security of these applications against CSRF.  It is recommended that the
developers of other reusable apps that want the same guarantees also use the
``csrf_protect`` decorator on their views.

Settings
========

A number of settings can be used to control Django's CSRF behavior:

* :setting:`CSRF_COOKIE_AGE`
* :setting:`CSRF_COOKIE_DOMAIN`
* :setting:`CSRF_COOKIE_HTTPONLY`
* :setting:`CSRF_COOKIE_NAME`
* :setting:`CSRF_COOKIE_PATH`
* :setting:`CSRF_COOKIE_SECURE`
* :setting:`CSRF_FAILURE_VIEW`
* :setting:`CSRF_HEADER_NAME`
* :setting:`CSRF_TRUSTED_ORIGINS`

Frequently Asked Questions
==========================

Is posting an arbitrary CSRF token pair (cookie and POST data) a vulnerability?
-------------------------------------------------------------------------------

No, this is by design. Without a man-in-the-middle attack, there is no way for
an attacker to send a CSRF token cookie to a victim's browser, so a successful
attack would need to obtain the victim's browser's cookie via XSS or similar,
in which case an attacker usually doesn't need CSRF attacks.

Some security audit tools flag this as a problem but as mentioned before, an
attacker cannot steal a user's browser's CSRF cookie. "Stealing" or modifying
*your own* token using Firebug, Chrome dev tools, etc. isn't a vulnerability.

Is the fact that Django's CSRF protection isn't linked to a session a problem?
------------------------------------------------------------------------------

No, this is by design. Not linking CSRF protection to a session allows using
the protection on sites such as a `pastebin` that allow submissions from
anonymous users which don't have a session.

Why might a user encounter a CSRF validation failure after logging in?
----------------------------------------------------------------------

For security reasons, CSRF tokens are rotated each time a user logs in. Any
page with a form generated before a login will have an old, invalid CSRF token
and need to be reloaded. This might happen if a user uses the back button after
a login or if they log in in a different browser tab.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Databases (`大一小学期/Week_3-Python/exam/2016/docs/ref/databases.txt`)

=========
Databases
=========

Django attempts to support as many features as possible on all database
backends. However, not all database backends are alike, and we've had to make
design decisions on which features to support and which assumptions we can make
safely.

This file describes some of the features that might be relevant to Django
usage. Of course, it is not intended as a replacement for server-specific
documentation or reference manuals.

General notes
=============

.. _persistent-database-connections:

Persistent connections
----------------------

Persistent connections avoid the overhead of re-establishing a connection to
the database in each request. They're controlled by the
:setting:`CONN_MAX_AGE` parameter which defines the maximum lifetime of a
connection. It can be set independently for each database.

The default value is ``0``, preserving the historical behavior of closing the
database connection at the end of each request. To enable persistent
connections, set :setting:`CONN_MAX_AGE` to a positive number of seconds. For
unlimited persistent connections, set it to ``None``.

Connection management
~~~~~~~~~~~~~~~~~~~~~

Django opens a connection to the database when it first makes a database
query. It keeps this connection open and reuses it in subsequent requests.
Django closes the connection once it exceeds the maximum age defined by
:setting:`CONN_MAX_AGE` or when it isn't usable any longer.

In detail, Django automatically opens a connection to the database whenever it
needs one and doesn't have one already — either because this is the first
connection, or because the previous connection was closed.

At the beginning of each request, Django closes the connection if it has
reached its maximum age. If your database terminates idle connections after
some time, you should set :setting:`CONN_MAX_AGE` to a lower value, so that
Django doesn't attempt to use a connection that has been terminated by the
database server. (This problem may only affect very low traffic sites.)

At the end of each request, Django closes the connection if it has reached its
maximum age or if it is in an unrecoverable error state. If any database
errors have occurred while processing the requests, Django checks whether the
connection still works, and closes it if it doesn't. Thus, database errors
affect at most one request; if the connection becomes unusable, the next
request gets a fresh connection.

Caveats
~~~~~~~

Since each thread maintains its own connection, your database must support at
least as many simultaneous connections as you have worker threads.

Sometimes a database won't be accessed by the majority of your views, for
example because it's the database of an external system, or thanks to caching.
In such cases, you should set :setting:`CONN_MAX_AGE` to a low value or even
``0``, because it doesn't make sense to maintain a connection that's unlikely
to be reused. This will help keep the number of simultaneous connections to
this database small.

The development server creates a new thread for each request it handles,
negating the effect of persistent connections. Don't enable them during
development.

When Django establishes a connection to the database, it sets up appropriate
parameters, depending on the backend being used. If you enable persistent
connections, this setup is no longer repeated every request. If you modify
parameters such as the connection's isolation level or time zone, you should
either restore Django's defaults at the end of each request, force an
appropriate value at the beginning of each request, or disable persistent
connections.

Encoding
--------

Django assumes that all databases use UTF-8 encoding. Using other encodings may
result in unexpected behavior such as "value too long" errors from your
database for data that is valid in Django. See the database specific notes
below for information on how to set up your database correctly.

.. _postgresql-notes:

PostgreSQL notes
================

Django supports PostgreSQL 9.2 and higher. It requires the use of `psycopg2`_
2.4.5 or higher (or 2.5+ if you want to use :mod:`django.contrib.postgres`).

.. _psycopg2: http://initd.org/psycopg/

PostgreSQL connection settings
-------------------------------

See :setting:`HOST` for details.

Optimizing PostgreSQL's configuration
-------------------------------------

Django needs the following parameters for its database connections:

- ``client_encoding``: ``'UTF8'``,
- ``default_transaction_isolation``: ``'read committed'`` by default,
  or the value set in the connection options (see below),
- ``timezone``: ``'UTC'`` when :setting:`USE_TZ` is ``True``, value of
  :setting:`TIME_ZONE` otherwise.

If these parameters already have the correct values, Django won't set them for
every new connection, which improves performance slightly. You can configure
them directly in :file:`postgresql.conf` or more conveniently per database
user with `ALTER ROLE`_.

Django will work just fine without this optimization, but each new connection
will do some additional queries to set these parameters.

.. _ALTER ROLE: http://www.postgresql.org/docs/current/interactive/sql-alterrole.html

.. _database-isolation-level:

Isolation level
---------------

Like PostgreSQL itself, Django defaults to the ``READ COMMITTED`` `isolation
level`_. If you need a higher isolation level such as ``REPEATABLE READ`` or
``SERIALIZABLE``, set it in the :setting:`OPTIONS` part of your database
configuration in :setting:`DATABASES`::

    import psycopg2.extensions

    DATABASES = {
        # ...
        'OPTIONS': {
            'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE,
        },
    }

.. note::

    Under higher isolation levels, your application should be prepared to
    handle exceptions raised on serialization failures. This option is
    designed for advanced uses.

.. _isolation level: http://www.postgresql.org/docs/current/static/transaction-iso.html

Indexes for ``varchar`` and ``text`` columns
--------------------------------------------

When specifying ``db_index=True`` on your model fields, Django typically
outputs a single ``CREATE INDEX`` statement.  However, if the database type
for the field is either ``varchar`` or ``text`` (e.g., used by ``CharField``,
``FileField``, and ``TextField``), then Django will create
an additional index that uses an appropriate `PostgreSQL operator class`_
for the column.  The extra index is necessary to correctly perform
lookups that use the ``LIKE`` operator in their SQL, as is done with the
``contains`` and ``startswith`` lookup types.

.. _PostgreSQL operator class: http://www.postgresql.org/docs/current/static/indexes-opclass.html

Migration operation for adding extensions
-----------------------------------------

If you need to add a PostgreSQL extension (like ``hstore``, ``postgis``, etc.)
using a migration, use the
:class:`~django.contrib.postgres.operations.CreateExtension` operation.

Speeding up test execution with non-durable settings
----------------------------------------------------

You can speed up test execution times by `configuring PostgreSQL to be
non-durable <http://www.postgresql.org/docs/current/static/non-durability.html>`_.

.. warning::

    This is dangerous: it will make your database more susceptible to data loss
    or corruption in the case of a server crash or power loss. Only use this on
    a development machine where you can easily restore the entire contents of
    all databases in the cluster.

.. _mysql-notes:

MySQL notes
===========

Version support
---------------

Django supports MySQL 5.5 and higher.

Django's ``inspectdb`` feature uses the ``information_schema`` database, which
contains detailed data on all database schemas.

Django expects the database to support Unicode (UTF-8 encoding) and delegates to
it the task of enforcing transactions and referential integrity. It is important
to be aware of the fact that the two latter ones aren't actually enforced by
MySQL when using the MyISAM storage engine, see the next section.

.. _mysql-storage-engines:

Storage engines
---------------

MySQL has several `storage engines`_. You can change the default storage engine
in the server configuration.

Until MySQL 5.5.4, the default engine was MyISAM_ [#]_. The main drawbacks of
MyISAM are that it doesn't support transactions or enforce foreign-key
constraints. On the plus side, it was the only engine that supported full-text
indexing and searching until MySQL 5.6.4.

Since MySQL 5.5.5, the default storage engine is InnoDB_. This engine is fully
transactional and supports foreign key references. It's probably the best
choice at this point. However, note that the InnoDB autoincrement counter
is lost on a MySQL restart because it does not remember the
``AUTO_INCREMENT`` value, instead recreating it as "max(id)+1". This may
result in an inadvertent reuse of :class:`~django.db.models.AutoField` values.

If you upgrade an existing project to MySQL 5.5.5 and subsequently add some
tables, ensure that your tables are using the same storage engine (i.e. MyISAM
vs. InnoDB). Specifically, if tables that have a ``ForeignKey`` between them
use different storage engines, you may see an error like the following when
running ``migrate``::

    _mysql_exceptions.OperationalError: (
        1005, "Can't create table '\\db_name\\.#sql-4a8_ab' (errno: 150)"
    )

.. _storage engines: https://dev.mysql.com/doc/refman/5.6/en/storage-engines.html
.. _MyISAM: https://dev.mysql.com/doc/refman/5.6/en/myisam-storage-engine.html
.. _InnoDB: https://dev.mysql.com/doc/refman/5.6/en/innodb-storage-engine.html

.. [#] Unless this was changed by the packager of your MySQL package. We've
   had reports that the Windows Community Server installer sets up InnoDB as
   the default storage engine, for example.

.. _mysql-db-api-drivers:

MySQL DB API Drivers
--------------------

The Python Database API is described in :pep:`249`. MySQL has three prominent
drivers that implement this API:

- `MySQLdb`_ is a native driver that has been developed and supported for over
  a decade by Andy Dustman.
- `mysqlclient`_ is a fork of ``MySQLdb`` which notably supports Python 3 and
  can be used as a drop-in replacement for MySQLdb. At the time of this writing,
  this is **the recommended choice** for using MySQL with Django.
- `MySQL Connector/Python`_ is a pure Python driver from Oracle that does not
  require the MySQL client library or any Python modules outside the standard
  library.

.. _MySQLdb: https://pypi.python.org/pypi/MySQL-python/1.2.4
.. _mysqlclient: https://pypi.python.org/pypi/mysqlclient
.. _MySQL Connector/Python: https://dev.mysql.com/downloads/connector/python

All these drivers are thread-safe and provide connection pooling. ``MySQLdb``
is the only one not supporting Python 3 currently.

In addition to a DB API driver, Django needs an adapter to access the database
drivers from its ORM. Django provides an adapter for MySQLdb/mysqlclient while
MySQL Connector/Python includes `its own`_.

.. _its own: https://dev.mysql.com/doc/connector-python/en/connector-python-django-backend.html

MySQLdb
~~~~~~~

Django requires MySQLdb version 1.2.1p2 or later.

At the time of writing, the latest release of MySQLdb (1.2.5) doesn't support
Python 3. In order to use MySQLdb under Python 3, you'll have to install
``mysqlclient`` instead.

.. note::
    There are known issues with the way MySQLdb converts date strings into
    datetime objects. Specifically, date strings with value ``0000-00-00`` are
    valid for MySQL but will be converted into ``None`` by MySQLdb.

    This means you should be careful while using :djadmin:`loaddata` and
    :djadmin:`dumpdata` with rows that may have ``0000-00-00`` values, as they
    will be converted to ``None``.

mysqlclient
~~~~~~~~~~~

Django requires `mysqlclient`_ 1.3.3 or later. Note that Python 3.2 is not
supported. Except for the Python 3.3+ support, mysqlclient should mostly behave
the same as MySQLDB.

MySQL Connector/Python
~~~~~~~~~~~~~~~~~~~~~~

MySQL Connector/Python is available from the `download page`_.
The Django adapter is available in versions 1.1.X and later. It may not
support the most recent releases of Django.

.. _download page: https://dev.mysql.com/downloads/connector/python/

.. _mysql-time-zone-definitions:

Time zone definitions
---------------------

If you plan on using Django's :doc:`timezone support </topics/i18n/timezones>`,
use `mysql_tzinfo_to_sql`_ to load time zone tables into the MySQL database.
This needs to be done just once for your MySQL server, not per database.

.. _mysql_tzinfo_to_sql: https://dev.mysql.com/doc/refman/5.6/en/mysql-tzinfo-to-sql.html

Creating your database
----------------------

You can `create your database`_ using the command-line tools and this SQL::

  CREATE DATABASE <dbname> CHARACTER SET utf8;

This ensures all tables and columns will use UTF-8 by default.

.. _create your database: https://dev.mysql.com/doc/refman/5.6/en/create-database.html

.. _mysql-collation:

Collation settings
~~~~~~~~~~~~~~~~~~

The collation setting for a column controls the order in which data is sorted
as well as what strings compare as equal. It can be set on a database-wide
level and also per-table and per-column. This is `documented thoroughly`_ in
the MySQL documentation. In all cases, you set the collation by directly
manipulating the database tables; Django doesn't provide a way to set this on
the model definition.

.. _documented thoroughly: https://dev.mysql.com/doc/refman/5.6/en/charset.html

By default, with a UTF-8 database, MySQL will use the
``utf8_general_ci`` collation. This results in all string equality
comparisons being done in a *case-insensitive* manner. That is, ``"Fred"`` and
``"freD"`` are considered equal at the database level. If you have a unique
constraint on a field, it would be illegal to try to insert both ``"aa"`` and
``"AA"`` into the same column, since they compare as equal (and, hence,
non-unique) with the default collation.

In many cases, this default will not be a problem. However, if you really want
case-sensitive comparisons on a particular column or table, you would change
the column or table to use the ``utf8_bin`` collation. The main thing to be
aware of in this case is that if you are using MySQLdb 1.2.2, the database
backend in Django will then return bytestrings (instead of unicode strings) for
any character fields it receive from the database. This is a strong variation
from Django's normal practice of *always* returning unicode strings. It is up
to you, the developer, to handle the fact that you will receive bytestrings if
you configure your table(s) to use ``utf8_bin`` collation. Django itself should
mostly work smoothly with such columns (except for the ``contrib.sessions``
``Session`` and ``contrib.admin`` ``LogEntry`` tables described below), but
your code must be prepared to call ``django.utils.encoding.smart_text()`` at
times if it really wants to work with consistent data -- Django will not do
this for you (the database backend layer and the model population layer are
separated internally so the database layer doesn't know it needs to make this
conversion in this one particular case).

If you're using MySQLdb 1.2.1p2, Django's standard
:class:`~django.db.models.CharField` class will return unicode strings even
with ``utf8_bin`` collation. However, :class:`~django.db.models.TextField`
fields will be returned as an ``array.array`` instance (from Python's standard
``array`` module). There isn't a lot Django can do about that, since, again,
the information needed to make the necessary conversions isn't available when
the data is read in from the database. This problem was `fixed in MySQLdb
1.2.2`_, so if you want to use :class:`~django.db.models.TextField` with
``utf8_bin`` collation, upgrading to version 1.2.2 and then dealing with the
bytestrings (which shouldn't be too difficult) as described above is the
recommended solution.

Should you decide to use ``utf8_bin`` collation for some of your tables with
MySQLdb 1.2.1p2 or 1.2.2, you should still use ``utf8_general_ci``
(the default) collation for the ``django.contrib.sessions.models.Session``
table (usually called ``django_session``) and the
:class:`django.contrib.admin.models.LogEntry` table (usually called
``django_admin_log``). Those are the two standard tables that use
:class:`~django.db.models.TextField` internally.

.. _fixed in MySQLdb 1.2.2: http://sourceforge.net/tracker/index.php?func=detail&aid=1495765&group_id=22307&atid=374932

Please note that according to `MySQL Unicode Character Sets`_, comparisons for
the ``utf8_general_ci`` collation are faster, but slightly less correct, than
comparisons for ``utf8_unicode_ci``. If this is acceptable for your application,
you should use ``utf8_general_ci`` because it is faster. If this is not acceptable
(for example, if you require German dictionary order), use ``utf8_unicode_ci``
because it is more accurate.

.. _MySQL Unicode Character Sets: https://dev.mysql.com/doc/refman/5.7/en/charset-unicode-sets.html

.. warning::

    Model formsets validate unique fields in a case-sensitive manner. Thus when
    using a case-insensitive collation, a formset with unique field values that
    differ only by case will pass validation, but upon calling ``save()``, an
    ``IntegrityError`` will be raised.

Connecting to the database
--------------------------

Refer to the :doc:`settings documentation </ref/settings>`.

Connection settings are used in this order:

1. :setting:`OPTIONS`.
2. :setting:`NAME`, :setting:`USER`, :setting:`PASSWORD`,
   :setting:`HOST`, :setting:`PORT`
3. MySQL option files.

In other words, if you set the name of the database in :setting:`OPTIONS`,
this will take precedence over :setting:`NAME`, which would override
anything in a `MySQL option file`_.

Here's a sample configuration which uses a MySQL option file::

    # settings.py
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'OPTIONS': {
                'read_default_file': '/path/to/my.cnf',
            },
        }
    }


    # my.cnf
    [client]
    database = NAME
    user = USER
    password = PASSWORD
    default-character-set = utf8

Several other MySQLdb connection options may be useful, such as ``ssl``,
``init_command``, and ``sql_mode``. Consult the `MySQLdb documentation`_ for
more details.

.. _MySQL option file: https://dev.mysql.com/doc/refman/5.6/en/option-files.html
.. _MySQLdb documentation: http://mysql-python.sourceforge.net/

.. _mysql-sql-mode:

Setting ``sql_mode``
~~~~~~~~~~~~~~~~~~~~

From MySQL 5.7 onwards and on fresh installs of MySQL 5.6, the default value of
the ``sql_mode`` option contains ``STRICT_TRANS_TABLES``. That option escalates
warnings into errors when data are truncated upon insertion, so Django highly
recommends activating a `strict mode`_ for MySQL to prevent data loss (either
``STRICT_TRANS_TABLES`` or ``STRICT_ALL_TABLES``).

.. _strict mode: https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sql-mode-strict

If you need to customize the SQL mode, you can set the ``sql_mode`` variable
like other MySQL options: either in a config file or with the entry
``'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"`` in the
:setting:`OPTIONS` part of your database configuration in :setting:`DATABASES`.

Creating your tables
--------------------

When Django generates the schema, it doesn't specify a storage engine, so
tables will be created with whatever default storage engine your database
server is configured for. The easiest solution is to set your database server's
default storage engine to the desired engine.

If you're using a hosting service and can't change your server's default
storage engine, you have a couple of options.

* After the tables are created, execute an ``ALTER TABLE`` statement to
  convert a table to a new storage engine (such as InnoDB)::

      ALTER TABLE <tablename> ENGINE=INNODB;

  This can be tedious if you have a lot of tables.

* Another option is to use the ``init_command`` option for MySQLdb prior to
  creating your tables::

      'OPTIONS': {
         'init_command': 'SET default_storage_engine=INNODB',
      }

  This sets the default storage engine upon connecting to the database.
  After your tables have been created, you should remove this option as it
  adds a query that is only needed during table creation to each database
  connection.

Table names
-----------

There are `known issues`_ in even the latest versions of MySQL that can cause the
case of a table name to be altered when certain SQL statements are executed
under certain conditions. It is recommended that you use lowercase table
names, if possible, to avoid any problems that might arise from this behavior.
Django uses lowercase table names when it auto-generates table names from
models, so this is mainly a consideration if you are overriding the table name
via the :class:`~django.db.models.Options.db_table` parameter.

.. _known issues: https://bugs.mysql.com/bug.php?id=48875

Savepoints
----------

Both the Django ORM and MySQL (when using the InnoDB :ref:`storage engine
<mysql-storage-engines>`) support database :ref:`savepoints
<topics-db-transactions-savepoints>`.

If you use the MyISAM storage engine please be aware of the fact that you will
receive database-generated errors if you try to use the :ref:`savepoint-related
methods of the transactions API <topics-db-transactions-savepoints>`. The reason
for this is that detecting the storage engine of a MySQL database/table is an
expensive operation so it was decided it isn't worth to dynamically convert
these methods in no-op's based in the results of such detection.

Notes on specific fields
------------------------

Character fields
~~~~~~~~~~~~~~~~

Any fields that are stored with ``VARCHAR`` column types have their
``max_length`` restricted to 255 characters if you are using ``unique=True``
for the field. This affects :class:`~django.db.models.CharField`,
:class:`~django.db.models.SlugField` and
:class:`~django.db.models.CommaSeparatedIntegerField`.

``TextField`` limitations
~~~~~~~~~~~~~~~~~~~~~~~~~

MySQL can index only the first N chars of a ``BLOB`` or ``TEXT`` column. Since
``TextField`` doesn't have a defined length, you can't mark it as
``unique=True``. MySQL will report: "BLOB/TEXT column '<db_column>' used in key
specification without a key length".

.. _mysql-fractional-seconds:

Fractional seconds support for Time and DateTime fields
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

MySQL 5.6.4 and later can store fractional seconds, provided that the
column definition includes a fractional indication (e.g. ``DATETIME(6)``).
Earlier versions do not support them at all. In addition, versions of MySQLdb
older than 1.2.5 have `a bug`_ that also prevents the use of fractional seconds
with MySQL.

.. _a bug: https://github.com/farcepest/MySQLdb1/issues/24

Django will not upgrade existing columns to include fractional seconds if the
database server supports it. If you want to enable them on an existing database,
it's up to you to either manually update the column on the target database, by
executing a command like::

    ALTER TABLE `your_table` MODIFY `your_datetime_column` DATETIME(6)

or using a :class:`~django.db.migrations.operations.RunSQL` operation in a
:ref:`data migration <data-migrations>`.

``TIMESTAMP`` columns
~~~~~~~~~~~~~~~~~~~~~

If you are using a legacy database that contains ``TIMESTAMP`` columns, you must
set :setting:`USE_TZ = False <USE_TZ>` to avoid data corruption.
:djadmin:`inspectdb` maps these columns to
:class:`~django.db.models.DateTimeField` and if you enable timezone support,
both MySQL and Django will attempt to convert the values from UTC to local time.

Row locking with ``QuerySet.select_for_update()``
-------------------------------------------------

MySQL does not support the ``NOWAIT`` option to the ``SELECT ... FOR UPDATE``
statement. If ``select_for_update()`` is used with ``nowait=True`` then a
``DatabaseError`` will be raised.

Automatic typecasting can cause unexpected results
--------------------------------------------------

When performing a query on a string type, but with an integer value, MySQL will
coerce the types of all values in the table to an integer before performing the
comparison. If your table contains the values ``'abc'``, ``'def'`` and you
query for ``WHERE mycolumn=0``, both rows will match. Similarly, ``WHERE mycolumn=1``
will match the value ``'abc1'``. Therefore, string type fields included in Django
will always cast the value to a string before using it in a query.

If you implement custom model fields that inherit from
:class:`~django.db.models.Field` directly, are overriding
:meth:`~django.db.models.Field.get_prep_value`, or use
:class:`~django.db.models.expressions.RawSQL`,
:meth:`~django.db.models.query.QuerySet.extra`, or
:meth:`~django.db.models.Manager.raw`, you should ensure that you perform
appropriate typecasting.

.. _sqlite-notes:

SQLite notes
============

SQLite_ provides an excellent development alternative for applications that
are predominantly read-only or require a smaller installation footprint. As
with all database servers, though, there are some differences that are
specific to SQLite that you should be aware of.

.. _SQLite: https://www.sqlite.org/

.. _sqlite-string-matching:

Substring matching and case sensitivity
-----------------------------------------

For all SQLite versions, there is some slightly counter-intuitive behavior when
attempting to match some types of strings.  These are triggered when using the
:lookup:`iexact` or :lookup:`contains` filters in Querysets. The behavior
splits into two cases:

1. For substring matching, all matches are done case-insensitively. That is a
filter such as ``filter(name__contains="aa")`` will match a name of ``"Aabb"``.

2. For strings containing characters outside the ASCII range, all exact string
matches are performed case-sensitively, even when the case-insensitive options
are passed into the query. So the :lookup:`iexact` filter will behave exactly
the same as the :lookup:`exact` filter in these cases.

Some possible workarounds for this are `documented at sqlite.org`_, but they
aren't utilized by the default SQLite backend in Django, as incorporating them
would be fairly difficult to do robustly. Thus, Django exposes the default
SQLite behavior and you should be aware of this when doing case-insensitive or
substring filtering.

.. _documented at sqlite.org: https://www.sqlite.org/faq.html#q18

Old SQLite and ``CASE`` expressions
-----------------------------------

SQLite 3.6.23.1 and older contains a bug when `handling query parameters`_ in
a ``CASE`` expression that contains an ``ELSE`` and arithmetic.

SQLite 3.6.23.1 was released in March 2010, and most current binary
distributions for different platforms include a newer version of SQLite, with
the notable exception of the Python 2.7 installers for Windows.

As of this writing, the latest release for Windows - Python 2.7.10 - includes
SQLite 3.6.21. You can install ``pysqlite2`` or replace ``sqlite3.dll`` (by
default installed in ``C:\Python27\DLLs``) with a newer version from
https://www.sqlite.org/ to remedy this issue.

.. _handling query parameters: https://code.djangoproject.com/ticket/24148

.. _using-newer-versions-of-pysqlite:

Using newer versions of the SQLite DB-API 2.0 driver
----------------------------------------------------

Django will use a ``pysqlite2`` module in preference to ``sqlite3`` as shipped
with the Python standard library if it finds one is available.

This provides the ability to upgrade both the DB-API 2.0 interface or SQLite 3
itself to versions newer than the ones included with your particular Python
binary distribution, if needed.

"Database is locked" errors
---------------------------

SQLite is meant to be a lightweight database, and thus can't support a high
level of concurrency. ``OperationalError: database is locked`` errors indicate
that your application is experiencing more concurrency than ``sqlite`` can
handle in default configuration. This error means that one thread or process has
an exclusive lock on the database connection and another thread timed out
waiting for the lock the be released.

Python's SQLite wrapper has
a default timeout value that determines how long the second thread is allowed to
wait on the lock before it times out and raises the ``OperationalError: database
is locked`` error.

If you're getting this error, you can solve it by:

* Switching to another database backend. At a certain point SQLite becomes
  too "lite" for real-world applications, and these sorts of concurrency
  errors indicate you've reached that point.

* Rewriting your code to reduce concurrency and ensure that database
  transactions are short-lived.

* Increase the default timeout value by setting the ``timeout`` database
  option::

      'OPTIONS': {
          # ...
          'timeout': 20,
          # ...
      }

  This will simply make SQLite wait a bit longer before throwing "database
  is locked" errors; it won't really do anything to solve them.

``QuerySet.select_for_update()`` not supported
----------------------------------------------

SQLite does not support the ``SELECT ... FOR UPDATE`` syntax. Calling it will
have no effect.

"pyformat" parameter style in raw queries not supported
-------------------------------------------------------

For most backends, raw queries (``Manager.raw()`` or ``cursor.execute()``)
can use the "pyformat" parameter style, where placeholders in the query
are given as ``'%(name)s'`` and the parameters are passed as a dictionary
rather than a list. SQLite does not support this.

.. _oracle-notes:

Oracle notes
============

Django supports `Oracle Database Server`_ versions 11.2 and higher. Version
4.3.1 or higher of the `cx_Oracle`_ Python driver is required, although we
recommend version 5.1.3 or later as these versions support Python 3.

Note that due to a Unicode-corruption bug in ``cx_Oracle`` 5.0, that
version of the driver should **not** be used with Django;
``cx_Oracle`` 5.0.1 resolved this issue, so if you'd like to use a
more recent ``cx_Oracle``, use version 5.0.1.

``cx_Oracle`` 5.0.1 or greater can optionally be compiled with the
``WITH_UNICODE`` environment variable.  This is recommended but not
required.

.. _`Oracle Database Server`: http://www.oracle.com/
.. _`cx_Oracle`: http://cx-oracle.sourceforge.net/

In order for the ``python manage.py migrate`` command to work, your Oracle
database user must have privileges to run the following commands:

* CREATE TABLE
* CREATE SEQUENCE
* CREATE PROCEDURE
* CREATE TRIGGER

To run a project's test suite, the user usually needs these *additional*
privileges:

* CREATE USER
* DROP USER
* CREATE TABLESPACE
* DROP TABLESPACE
* CREATE SESSION WITH ADMIN OPTION
* CREATE TABLE WITH ADMIN OPTION
* CREATE SEQUENCE WITH ADMIN OPTION
* CREATE PROCEDURE WITH ADMIN OPTION
* CREATE TRIGGER WITH ADMIN OPTION

Note that, while the RESOURCE role has the required CREATE TABLE, CREATE
SEQUENCE, CREATE PROCEDURE and CREATE TRIGGER privileges, and a user
granted RESOURCE WITH ADMIN OPTION can grant RESOURCE, such a user cannot
grant the individual privileges (e.g. CREATE TABLE), and thus RESOURCE
WITH ADMIN OPTION is not usually sufficient for running tests.

Some test suites also create views; to run these, the user also needs
the CREATE VIEW WITH ADMIN OPTION privilege. In particular, this is needed
for Django's own test suite.

All of these privileges are included in the DBA role, which is appropriate
for use on a private developer's database.

The Oracle database backend uses the ``SYS.DBMS_LOB`` and ``SYS.DBMS_RANDOM``
packages, so your user will require execute permissions on it. It's normally
accessible to all users by default, but in case it is not, you'll need to grant
permissions like so:

.. code-block:: sql

    GRANT EXECUTE ON SYS.DBMS_LOB TO user;
    GRANT EXECUTE ON SYS.DBMS_RANDOM TO user;

Connecting to the database
--------------------------

To connect using the service name of your Oracle database, your ``settings.py``
file should look something like this::

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.oracle',
            'NAME': 'xe',
            'USER': 'a_user',
            'PASSWORD': 'a_password',
            'HOST': '',
            'PORT': '',
        }
    }


In this case, you should leave both :setting:`HOST` and :setting:`PORT` empty.
However, if you don't use a ``tnsnames.ora`` file or a similar naming method
and want to connect using the SID ("xe" in this example), then fill in both
:setting:`HOST` and :setting:`PORT` like so::

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.oracle',
            'NAME': 'xe',
            'USER': 'a_user',
            'PASSWORD': 'a_password',
            'HOST': 'dbprod01ned.mycompany.com',
            'PORT': '1540',
        }
    }

You should either supply both :setting:`HOST` and :setting:`PORT`, or leave
both as empty strings. Django will use a different connect descriptor depending
on that choice.

Threaded option
----------------

If you plan to run Django in a multithreaded environment (e.g. Apache using the
default MPM module on any modern operating system), then you **must** set
the ``threaded`` option of your Oracle database configuration to True::

            'OPTIONS': {
                'threaded': True,
            },

Failure to do this may result in crashes and other odd behavior.

INSERT ... RETURNING INTO
-------------------------

By default, the Oracle backend uses a ``RETURNING INTO`` clause to efficiently
retrieve the value of an ``AutoField`` when inserting new rows.  This behavior
may result in a ``DatabaseError`` in certain unusual setups, such as when
inserting into a remote table, or into a view with an ``INSTEAD OF`` trigger.
The ``RETURNING INTO`` clause can be disabled by setting the
``use_returning_into`` option of the database configuration to False::

            'OPTIONS': {
                'use_returning_into': False,
            },

In this case, the Oracle backend will use a separate ``SELECT`` query to
retrieve AutoField values.

Naming issues
-------------

Oracle imposes a name length limit of 30 characters. To accommodate this, the
backend truncates database identifiers to fit, replacing the final four
characters of the truncated name with a repeatable MD5 hash value.
Additionally, the backend turns database identifiers to all-uppercase.

To prevent these transformations (this is usually required only when dealing
with legacy databases or accessing tables which belong to other users), use
a quoted name as the value for ``db_table``::

    class LegacyModel(models.Model):
        class Meta:
            db_table = '"name_left_in_lowercase"'

    class ForeignModel(models.Model):
        class Meta:
            db_table = '"OTHER_USER"."NAME_ONLY_SEEMS_OVER_30"'

Quoted names can also be used with Django's other supported database
backends; except for Oracle, however, the quotes have no effect.

When running ``migrate``, an ``ORA-06552`` error may be encountered if
certain Oracle keywords are used as the name of a model field or the
value of a ``db_column`` option.  Django quotes all identifiers used
in queries to prevent most such problems, but this error can still
occur when an Oracle datatype is used as a column name.  In
particular, take care to avoid using the names ``date``,
``timestamp``, ``number`` or ``float`` as a field name.

NULL and empty strings
----------------------

Django generally prefers to use the empty string ('') rather than
NULL, but Oracle treats both identically. To get around this, the
Oracle backend ignores an explicit ``null`` option on fields that
have the empty string as a possible value and generates DDL as if
``null=True``. When fetching from the database, it is assumed that
a ``NULL`` value in one of these fields really means the empty
string, and the data is silently converted to reflect this assumption.

``TextField`` limitations
-------------------------

The Oracle backend stores ``TextFields`` as ``NCLOB`` columns. Oracle imposes
some limitations on the usage of such LOB columns in general:

* LOB columns may not be used as primary keys.

* LOB columns may not be used in indexes.

* LOB columns may not be used in a ``SELECT DISTINCT`` list. This means that
  attempting to use the ``QuerySet.distinct`` method on a model that
  includes ``TextField`` columns will result in an ``ORA-00932`` error when
  run against Oracle. As a workaround, use the ``QuerySet.defer`` method in
  conjunction with ``distinct()`` to prevent ``TextField`` columns from being
  included in the ``SELECT DISTINCT`` list.

.. _third-party-notes:

Using a 3rd-party database backend
==================================

In addition to the officially supported databases, there are backends provided
by 3rd parties that allow you to use other databases with Django:

* `SAP SQL Anywhere`_
* `IBM DB2`_
* `Microsoft SQL Server`_
* Firebird_
* ODBC_

The Django versions and ORM features supported by these unofficial backends
vary considerably. Queries regarding the specific capabilities of these
unofficial backends, along with any support queries, should be directed to
the support channels provided by each 3rd party project.

.. _SAP SQL Anywhere: https://github.com/sqlanywhere/sqlany-django
.. _IBM DB2: https://pypi.python.org/pypi/ibm_db/
.. _Microsoft SQL Server: https://django-mssql.readthedocs.io/en/latest/
.. _Firebird: https://github.com/maxirobaina/django-firebird
.. _ODBC: https://github.com/lionheart/django-pyodbc/

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Django Admin (`大一小学期/Week_3-Python/exam/2016/docs/ref/django-admin.txt`)

==================================
``django-admin`` and ``manage.py``
==================================

``django-admin`` is Django's command-line utility for administrative tasks.
This document outlines all it can do.

In addition, ``manage.py`` is automatically created in each Django project.
``manage.py`` does the same thing as ``django-admin`` but takes care of a few
things for you:

* It puts your project's package on ``sys.path``.

* It sets the :envvar:`DJANGO_SETTINGS_MODULE` environment variable so that
  it points to your project's ``settings.py`` file.

The ``django-admin`` script should be on your system path if you installed
Django via its ``setup.py`` utility. If it's not on your path, you can find it
in ``site-packages/django/bin`` within your Python installation. Consider
symlinking it from some place on your path, such as ``/usr/local/bin``.

For Windows users, who do not have symlinking functionality available, you can
copy ``django-admin.exe`` to a location on your existing path or edit the
``PATH`` settings (under ``Settings - Control Panel - System - Advanced -
Environment...``) to point to its installed location.

Generally, when working on a single Django project, it's easier to use
``manage.py`` than ``django-admin``. If you need to switch between multiple
Django settings files, use ``django-admin`` with
:envvar:`DJANGO_SETTINGS_MODULE` or the :option:`--settings` command line
option.

The command-line examples throughout this document use ``django-admin`` to
be consistent, but any example can use ``manage.py`` or ``python -m django``
just as well.

.. versionadded:: 1.9

    ``python -m django`` was added.

Usage
=====

.. code-block:: console

    $ django-admin <command> [options]
    $ manage.py <command> [options]
    $ python -m django <command> [options]

``command`` should be one of the commands listed in this document.
``options``, which is optional, should be zero or more of the options available
for the given command.

Getting runtime help
--------------------

.. django-admin:: help

Run ``django-admin help`` to display usage information and a list of the
commands provided by each application.

Run ``django-admin help --commands`` to display a list of all available
commands.

Run ``django-admin help <command>`` to display a description of the given
command and a list of its available options.

App names
---------

Many commands take a list of "app names." An "app name" is the basename of
the package containing your models. For example, if your :setting:`INSTALLED_APPS`
contains the string ``'mysite.blog'``, the app name is ``blog``.

Determining the version
-----------------------

.. django-admin:: version

Run ``django-admin version`` to display the current Django version.

The output follows the schema described in :pep:`440`::

    1.4.dev17026
    1.4a1
    1.4

Displaying debug output
-----------------------

.. program:: None

Use :option:`--verbosity` to specify the amount of notification and debug
information that ``django-admin`` prints to the console.

Available commands
==================

``check``
---------

.. django-admin:: check [app_label [app_label ...]]

Uses the :doc:`system check framework </ref/checks>` to inspect the entire
Django project for common problems.

By default, all apps will be checked. You can check a subset of apps by
providing a list of app labels as arguments::

    django-admin check auth admin myapp

If you do not specify any app, all apps will be checked.

.. django-admin-option:: --tag TAGS, -t TAGS

The system check framework performs many different types of checks that are
:ref:`categorized with tags <system-check-builtin-tags>`. You can use these
tags to restrict the checks performed to just those in a particular category.
For example, to perform only models and compatibility checks, run::

    django-admin check --tag models --tag compatibility

.. django-admin-option:: --list-tags

Lists all available tags.

.. django-admin-option:: --deploy

Activates some additional checks that are only relevant in a deployment setting.

You can use this option in your local development environment, but since your
local development settings module may not have many of your production settings,
you will probably want to point the ``check`` command at a different settings
module, either by setting the ``DJANGO_SETTINGS_MODULE`` environment variable,
or by passing the ``--settings`` option::

    django-admin check --deploy --settings=production_settings

Or you could run it directly on a production or staging deployment to verify
that the correct settings are in use (omitting ``--settings``). You could even
make it part of your integration test suite.

.. django-admin-option:: --fail-level {CRITICAL,ERROR,WARNING,INFO,DEBUG}

.. versionadded:: 1.10

Specifies the message level that will cause the command to exit with a non-zero
status. Default is ``ERROR``.

``compilemessages``
-------------------

.. django-admin:: compilemessages

Compiles ``.po`` files created by :djadmin:`makemessages` to ``.mo`` files for
use with the built-in gettext support. See :doc:`/topics/i18n/index`.

.. django-admin-option:: --locale LOCALE, -l LOCALE

Specifies the locale(s) to process. If not provided, all locales are processed.

.. django-admin-option:: --exclude EXCLUDE, -x EXCLUDE

Specifies the locale(s) to exclude from processing. If not provided, no locales
are excluded.

.. django-admin-option:: --use-fuzzy, -f

Includes fuzzy translations into compiled files.

.. versionchanged:: 1.9

    ``compilemessages`` now matches the operation of :djadmin:`makemessages`,
    scanning the project tree for ``.po`` files to compile.

Example usage::

    django-admin compilemessages --locale=pt_BR
    django-admin compilemessages --locale=pt_BR --locale=fr -f
    django-admin compilemessages -l pt_BR
    django-admin compilemessages -l pt_BR -l fr --use-fuzzy
    django-admin compilemessages --exclude=pt_BR
    django-admin compilemessages --exclude=pt_BR --exclude=fr
    django-admin compilemessages -x pt_BR
    django-admin compilemessages -x pt_BR -x fr

``createcachetable``
--------------------

.. django-admin:: createcachetable

Creates the cache tables for use with the database cache backend using the
information from your settings file. See :doc:`/topics/cache` for more
information.

.. django-admin-option:: --database DATABASE

Specifies the database in which the cache table(s) will be created. Defaults to
``default``.

.. django-admin-option:: --dry-run

Prints the SQL that would be run without actually running it, so you can
customize it or use the migrations framework.

.. versionchanged:: 1.9

    The ``--dry-run`` option was added.

``dbshell``
-----------

.. django-admin:: dbshell

Runs the command-line client for the database engine specified in your
:setting:`ENGINE <DATABASE-ENGINE>` setting, with the connection parameters
specified in your :setting:`USER`, :setting:`PASSWORD`, etc., settings.

* For PostgreSQL, this runs the ``psql`` command-line client.
* For MySQL, this runs the ``mysql`` command-line client.
* For SQLite, this runs the ``sqlite3`` command-line client.
* For Oracle, this runs the ``sqlplus`` command-line client.

This command assumes the programs are on your ``PATH`` so that a simple call to
the program name (``psql``, ``mysql``, ``sqlite3``, ``sqlplus``) will find the
program in the right place. There's no way to specify the location of the
program manually.

.. django-admin-option:: --database DATABASE

Specifies the database onto which to open a shell. Defaults to ``default``.

``diffsettings``
----------------

.. django-admin:: diffsettings

Displays differences between the current settings file and Django's default
settings.

Settings that don't appear in the defaults are followed by ``"###"``. For
example, the default settings don't define :setting:`ROOT_URLCONF`, so
:setting:`ROOT_URLCONF` is followed by ``"###"`` in the output of
``diffsettings``.

.. django-admin-option:: --all

Displays all settings, even if they have Django's default value. Such settings
are prefixed by ``"###"``.

``dumpdata``
------------

.. django-admin:: dumpdata [app_label[.ModelName] [app_label[.ModelName] ...]]

Outputs to standard output all data in the database associated with the named
application(s).

If no application name is provided, all installed applications will be dumped.

The output of ``dumpdata`` can be used as input for :djadmin:`loaddata`.

Note that ``dumpdata`` uses the default manager on the model for selecting the
records to dump. If you're using a :ref:`custom manager <custom-managers>` as
the default manager and it filters some of the available records, not all of the
objects will be dumped.

.. django-admin-option:: --all, -a

Uses Django's base manager, dumping records which might otherwise be filtered
or modified by a custom manager.

.. django-admin-option:: --format FORMAT

Specifies the serialization format of the output. Defaults to JSON. Supported
formats are listed in :ref:`serialization-formats`.

.. django-admin-option:: --indent INDENT

Specifies the number of indentation spaces to use in the output. Defaults to
``None`` which displays all data on single line.

.. django-admin-option:: --exclude EXCLUDE, -e EXCLUDE

Prevents specific applications or models (specified in the form of
``app_label.ModelName``) from being dumped. If you specify a model name, the
output will be restricted to that model, rather than the entire application.
You can also mix application names and model names.

If you want to exclude multiple applications, pass ``--exclude`` more than
once::

    django-admin dumpdata --exclude=auth --exclude=contenttypes

.. django-admin-option:: --database DATABASE

Specifies the database from which data will be dumped. Defaults to ``default``.

.. django-admin-option:: --natural-foreign

Uses the ``natural_key()`` model method to serialize any foreign key and
many-to-many relationship to objects of the type that defines the method. If
you're dumping ``contrib.auth`` ``Permission`` objects or
``contrib.contenttypes`` ``ContentType`` objects, you should probably use this
flag. See the :ref:`natural keys <topics-serialization-natural-keys>`
documentation for more details on this and the next option.

.. django-admin-option:: --natural-primary

Omits the primary key in the serialized data of this object since it can be
calculated during deserialization.

.. django-admin-option:: --pks PRIMARY_KEYS

Outputs only the objects specified by a comma separated list of primary keys.
This is only available when dumping one model. By default, all the records of
the model are output.

.. django-admin-option:: --output OUTPUT, -o OUTPUT

Specifies a file to write the serialized data to. By default, the data goes to
standard output.

When this option is set and ``--verbosity`` is greater than 0 (the default), a
progress bar is shown in the terminal.

.. versionchanged:: 1.9

    The progress bar in the terminal was added.

``flush``
---------

.. django-admin:: flush

Removes all data from the database and re-executes any post-synchronization
handlers. The table of which migrations have been applied is not cleared.

If you would rather start from an empty database and re-run all migrations, you
should drop and recreate the database and then run :djadmin:`migrate` instead.

.. django-admin-option:: --noinput, --no-input

Suppresses all user prompts.

.. versionchanged:: 1.9

    The ``--no-input`` alias was added.

.. django-admin-option:: --database DATABASE

Specifies the database to flush. Defaults to ``default``.

``inspectdb``
-------------

.. django-admin:: inspectdb [table [table ...]]

Introspects the database tables in the database pointed-to by the
:setting:`NAME` setting and outputs a Django model module (a ``models.py``
file) to standard output. You may choose what tables to inspect by passing
their names as arguments.

Use this if you have a legacy database with which you'd like to use Django.
The script will inspect the database and create a model for each table within
it.

As you might expect, the created models will have an attribute for every field
in the table. Note that ``inspectdb`` has a few special cases in its field-name
output:

* If ``inspectdb`` cannot map a column's type to a model field type, it'll
  use ``TextField`` and will insert the Python comment
  ``'This field type is a guess.'`` next to the field in the generated
  model.

* If the database column name is a Python reserved word (such as
  ``'pass'``, ``'class'`` or ``'for'``), ``inspectdb`` will append
  ``'_field'`` to the attribute name. For example, if a table has a column
  ``'for'``, the generated model will have a field ``'for_field'``, with
  the ``db_column`` attribute set to ``'for'``. ``inspectdb`` will insert
  the Python comment
  ``'Field renamed because it was a Python reserved word.'`` next to the
  field.

This feature is meant as a shortcut, not as definitive model generation. After
you run it, you'll want to look over the generated models yourself to make
customizations. In particular, you'll need to rearrange models' order, so that
models that refer to other models are ordered properly.

Primary keys are automatically introspected for PostgreSQL, MySQL and
SQLite, in which case Django puts in the ``primary_key=True`` where
needed.

``inspectdb`` works with PostgreSQL, MySQL and SQLite. Foreign-key detection
only works in PostgreSQL and with certain types of MySQL tables.

Django doesn't create database defaults when a
:attr:`~django.db.models.Field.default` is specified on a model field.
Similarly, database defaults aren't translated to model field defaults or
detected in any fashion by ``inspectdb``.

By default, ``inspectdb`` creates unmanaged models. That is, ``managed = False``
in the model's ``Meta`` class tells Django not to manage each table's creation,
modification, and deletion. If you do want to allow Django to manage the
table's lifecycle, you'll need to change the
:attr:`~django.db.models.Options.managed` option to ``True`` (or simply remove
it because ``True`` is its default value).

.. versionadded:: 1.10

    Support for the ``table`` argument(s) to choose what tables should be
    inspected was added.

.. django-admin-option:: --database DATABASE

Specifies the database to introspect. Defaults to ``default``.

``loaddata``
------------

.. django-admin:: loaddata fixture [fixture ...]

Searches for and loads the contents of the named fixture into the database.

.. django-admin-option:: --database DATABASE

Specifies the database into which the data will be loaded. Defaults to
``default``.

.. django-admin-option:: --ignorenonexistent, -i

Ignores fields and models that may have been removed since the fixture was
originally generated.

.. django-admin-option:: --app APP_LABEL

Specifies a single app to look for fixtures in rather than looking in all apps.

What's a "fixture"?
~~~~~~~~~~~~~~~~~~~

A *fixture* is a collection of files that contain the serialized contents of
the database. Each fixture has a unique name, and the files that comprise the
fixture can be distributed over multiple directories, in multiple applications.

Django will search in three locations for fixtures:

1. In the ``fixtures`` directory of every installed application
2. In any directory named in the :setting:`FIXTURE_DIRS` setting
3. In the literal path named by the fixture

Django will load any and all fixtures it finds in these locations that match
the provided fixture names.

If the named fixture has a file extension, only fixtures of that type
will be loaded. For example::

    django-admin loaddata mydata.json

would only load JSON fixtures called ``mydata``. The fixture extension
must correspond to the registered name of a
:ref:`serializer <serialization-formats>` (e.g., ``json`` or ``xml``).

If you omit the extensions, Django will search all available fixture types
for a matching fixture. For example::

    django-admin loaddata mydata

would look for any fixture of any fixture type called ``mydata``. If a fixture
directory contained ``mydata.json``, that fixture would be loaded
as a JSON fixture.

The fixtures that are named can include directory components. These
directories will be included in the search path. For example::

    django-admin loaddata foo/bar/mydata.json

would search ``<app_label>/fixtures/foo/bar/mydata.json`` for each installed
application,  ``<dirname>/foo/bar/mydata.json`` for each directory in
:setting:`FIXTURE_DIRS`, and the literal path ``foo/bar/mydata.json``.

When fixture files are processed, the data is saved to the database as is.
Model defined :meth:`~django.db.models.Model.save` methods are not called, and
any :data:`~django.db.models.signals.pre_save` or
:data:`~django.db.models.signals.post_save` signals will be called with
``raw=True`` since the instance only contains attributes that are local to the
model. You may, for example, want to disable handlers that access
related fields that aren't present during fixture loading and would otherwise
raise an exception::

    from django.db.models.signals import post_save
    from .models import MyModel

    def my_handler(**kwargs):
        # disable the handler during fixture loading
        if kwargs['raw']:
            return
        ...

    post_save.connect(my_handler, sender=MyModel)

You could also write a simple decorator to encapsulate this logic::

    from functools import wraps

    def disable_for_loaddata(signal_handler):
        """
        Decorator that turns off signal handlers when loading fixture data.
        """
        @wraps(signal_handler)
        def wrapper(*args, **kwargs):
            if kwargs['raw']:
                return
            signal_handler(*args, **kwargs)
        return wrapper

    @disable_for_loaddata
    def my_handler(**kwargs):
        ...

Just be aware that this logic will disable the signals whenever fixtures are
deserialized, not just during ``loaddata``.

Note that the order in which fixture files are processed is undefined. However,
all fixture data is installed as a single transaction, so data in
one fixture can reference data in another fixture. If the database backend
supports row-level constraints, these constraints will be checked at the
end of the transaction.

The :djadmin:`dumpdata` command can be used to generate input for ``loaddata``.

Compressed fixtures
~~~~~~~~~~~~~~~~~~~

Fixtures may be compressed in ``zip``, ``gz``, or ``bz2`` format. For example::

    django-admin loaddata mydata.json

would look for any of ``mydata.json``, ``mydata.json.zip``,
``mydata.json.gz``, or ``mydata.json.bz2``. The first file contained within a
zip-compressed archive is used.

Note that if two fixtures with the same name but different
fixture type are discovered (for example, if ``mydata.json`` and
``mydata.xml.gz`` were found in the same fixture directory), fixture
installation will be aborted, and any data installed in the call to
``loaddata`` will be removed from the database.

.. admonition:: MySQL with MyISAM and fixtures

    The MyISAM storage engine of MySQL doesn't support transactions or
    constraints, so if you use MyISAM, you won't get validation of fixture
    data, or a rollback if multiple transaction files are found.

Database-specific fixtures
~~~~~~~~~~~~~~~~~~~~~~~~~~

If you're in a multi-database setup, you might have fixture data that
you want to load onto one database, but not onto another. In this
situation, you can add a database identifier into the names of your fixtures.

For example, if your :setting:`DATABASES` setting has a 'master' database
defined, name the fixture ``mydata.master.json`` or
``mydata.master.json.gz`` and the fixture will only be loaded when you
specify you want to load data into the ``master`` database.

``makemessages``
----------------

.. django-admin:: makemessages

Runs over the entire source tree of the current directory and pulls out all
strings marked for translation. It creates (or updates) a message file in the
conf/locale (in the Django tree) or locale (for project and application)
directory. After making changes to the messages files you need to compile them
with :djadmin:`compilemessages` for use with the builtin gettext support. See
the :ref:`i18n documentation <how-to-create-language-files>` for details.

.. django-admin-option:: --all, -a

Updates the message files for all available languages.

.. django-admin-option:: --extension EXTENSIONS, -e EXTENSIONS

Specifies a list of file extensions to examine (default: ``html``, ``txt``,
``py`` or ``js`` if :option:`--domain` is ``js``).

Example usage::

    django-admin makemessages --locale=de --extension xhtml

Separate multiple extensions with commas or use ``-e`` or ``--extension``
multiple times::

    django-admin makemessages --locale=de --extension=html,txt --extension xml

.. django-admin-option:: --locale LOCALE, -l LOCALE

Specifies the locale(s) to process.

.. django-admin-option:: --exclude EXCLUDE, -x EXCLUDE

Specifies the locale(s) to exclude from processing. If not provided, no locales
are excluded.

Example usage::

    django-admin makemessages --locale=pt_BR
    django-admin makemessages --locale=pt_BR --locale=fr
    django-admin makemessages -l pt_BR
    django-admin makemessages -l pt_BR -l fr
    django-admin makemessages --exclude=pt_BR
    django-admin makemessages --exclude=pt_BR --exclude=fr
    django-admin makemessages -x pt_BR
    django-admin makemessages -x pt_BR -x fr

.. django-admin-option:: --domain DOMAIN, -d DOMAIN

Specifies the domain of the messages files. Supported options are:

* ``django`` for all ``*.py``, ``*.html`` and ``*.txt`` files (default)
* ``djangojs`` for ``*.js`` files

.. django-admin-option:: --symlinks, -s

Follows symlinks to directories when looking for new translation strings.

Example usage::

    django-admin makemessages --locale=de --symlinks

.. django-admin-option:: --ignore PATTERN, -i PATTERN

Ignores files or directories matching the given :mod:`glob`-style pattern. Use
multiple times to ignore more.

These patterns are used by default: ``'CVS'``, ``'.*'``, ``'*~'``, ``'*.pyc'``.

Example usage::

    django-admin makemessages --locale=en_US --ignore=apps/* --ignore=secret/*.html

.. django-admin-option:: --no-default-ignore

Disables the default values of ``--ignore``.

.. django-admin-option:: --no-wrap

Disables breaking long message lines into several lines in language files.

.. django-admin-option:: --no-location

Suppresses writing '``#: filename:line``’ comment lines in language files.
Using this option makes it harder for technically skilled translators to
understand each message's context.

.. django-admin-option:: --keep-pot

Prevents deleting the temporary ``.pot`` files generated before creating the
``.po`` file. This is useful for debugging errors which may prevent the final
language files from being created.

.. seealso::

    See :ref:`customizing-makemessages` for instructions on how to customize
    the keywords that :djadmin:`makemessages` passes to ``xgettext``.

``makemigrations``
------------------

.. django-admin:: makemigrations [app_label [app_label ...]]

Creates new migrations based on the changes detected to your models.
Migrations, their relationship with apps and more are covered in depth in
:doc:`the migrations documentation</topics/migrations>`.

Providing one or more app names as arguments will limit the migrations created
to the app(s) specified and any dependencies needed (the table at the other end
of a ``ForeignKey``, for example).

.. django-admin-option:: --noinput, --no-input

Suppresses all user prompts. If a suppressed prompt cannot be resolved
automatically, the command will exit with error code 3.

.. versionchanged:: 1.9

    The ``--no-input`` alias was added.

.. django-admin-option:: --empty

Outputs an empty migration for the specified apps, for manual editing. This is
for advanced users and should not be used unless you are familiar with the
migration format, migration operations, and the dependencies between your
migrations.

.. django-admin-option:: --dry-run

Shows what migrations would be made without actually writing any migrations
files to disk. Using this option along with ``--verbosity 3`` will also show
the complete migrations files that would be written.

.. django-admin-option:: --merge

Enables fixing of migration conflicts.

.. django-admin-option:: --name NAME, -n NAME

Allows naming the generated migration(s) instead of using a generated name.

.. django-admin-option:: --exit, -e

.. deprecated:: 1.10

   Use the ``--check`` option instead.

Makes ``makemigrations`` exit with error code 1 when no migrations are created
(or would have been created, if combined with ``--dry-run``).

.. django-admin-option:: --check

.. versionadded:: 1.10

Makes ``makemigrations`` exit with a non-zero status when model changes without
migrations are detected.

``migrate``
-----------

.. django-admin:: migrate [app_label] [migration_name]

Synchronizes the database state with the current set of models and migrations.
Migrations, their relationship with apps and more are covered in depth in
:doc:`the migrations documentation</topics/migrations>`.

The behavior of this command changes depending on the arguments provided:

* No arguments: All apps have all of their migrations run.
* ``<app_label>``: The specified app has its migrations run, up to the most
  recent migration. This may involve running other apps' migrations too, due
  to dependencies.
* ``<app_label> <migrationname>``: Brings the database schema to a state where
  the named migration is applied, but no later migrations in the same app are
  applied. This may involve unapplying migrations if you have previously
  migrated past the named migration. Use the name ``zero`` to unapply all
  migrations for an app.

.. django-admin-option:: --database DATABASE

Specifies the database to migrate. Defaults to ``default``.

.. django-admin-option:: --fake

Tells Django to mark the migrations as having been applied or unapplied, but
without actually running the SQL to change your database schema.

This is intended for advanced users to manipulate the
current migration state directly if they're manually applying changes;
be warned that using ``--fake`` runs the risk of putting the migration state
table into a state where manual recovery will be needed to make migrations
run correctly.

.. django-admin-option:: --fake-initial

Allows Django to skip an app's initial migration if all database tables with
the names of all models created by all
:class:`~django.db.migrations.operations.CreateModel` operations in that
migration already exist. This option is intended for use when first running
migrations against a database that preexisted the use of migrations. This
option does not, however, check for matching database schema beyond matching
table names and so is only safe to use if you are confident that your existing
schema matches what is recorded in your initial migration.

.. django-admin-option:: --run-syncdb

.. versionadded:: 1.9

Allows creating tables for apps without migrations. While this isn't
recommended, the migrations framework is sometimes too slow on large projects
with hundreds of models.

.. django-admin-option:: --noinput, --no-input

Suppresses all user prompts. An example prompt is asking about removing stale
content types.

.. versionchanged:: 1.9

    The ``--no-input`` alias was added.

``runserver``
-------------

.. django-admin:: runserver [addrport]

Starts a lightweight development Web server on the local machine. By default,
the server runs on port 8000 on the IP address ``127.0.0.1``. You can pass in an
IP address and port number explicitly.

If you run this script as a user with normal privileges (recommended), you
might not have access to start a port on a low port number. Low port numbers
are reserved for the superuser (root).

This server uses the WSGI application object specified by the
:setting:`WSGI_APPLICATION` setting.

DO NOT USE THIS SERVER IN A PRODUCTION SETTING. It has not gone through
security audits or performance tests. (And that's how it's gonna stay. We're in
the business of making Web frameworks, not Web servers, so improving this
server to be able to handle a production environment is outside the scope of
Django.)

The development server automatically reloads Python code for each request, as
needed. You don't need to restart the server for code changes to take effect.
However, some actions like adding files don't trigger a restart, so you'll
have to restart the server in these cases.

If you are using Linux and install `pyinotify`_, kernel signals will be used to
autoreload the server (rather than polling file modification timestamps each
second). This offers better scaling to large projects, reduction in response
time to code modification, more robust change detection, and battery usage
reduction.

.. _pyinotify: https://pypi.python.org/pypi/pyinotify/

When you start the server, and each time you change Python code while the
server is running, the system check framework will check your entire Django
project for some common errors (see the :djadmin:`check` command). If any
errors are found, they will be printed to standard output.

You can run as many concurrent servers as you want, as long as they're on
separate ports. Just execute ``django-admin runserver`` more than once.

Note that the default IP address, ``127.0.0.1``, is not accessible from other
machines on your network. To make your development server viewable to other
machines on the network, use its own IP address (e.g. ``192.168.2.1``) or
``0.0.0.0`` or ``::`` (with IPv6 enabled).

You can provide an IPv6 address surrounded by brackets
(e.g. ``[200a::1]:8000``). This will automatically enable IPv6 support.

A hostname containing ASCII-only characters can also be used.

If the :doc:`staticfiles</ref/contrib/staticfiles>` contrib app is enabled
(default in new projects) the :djadmin:`runserver` command will be overridden
with its own :ref:`runserver<staticfiles-runserver>` command.

If :djadmin:`migrate` was not previously executed, the table that stores the
history of migrations is created at first run of ``runserver``.

Logging of each request and response of the server is sent to the
:ref:`django-server-logger` logger.

.. versionchanged:: 1.10

    In older versions, log messages were written to ``sys.stderr`` instead of
    being handled through Python logging.

.. django-admin-option:: --noreload

Disables the auto-reloader. This means any Python code changes you make while
the server is running will *not* take effect if the particular Python modules
have already been loaded into memory.

.. django-admin-option:: --nothreading

Disables use of threading in the development server. The server is
multithreaded by default.

.. django-admin-option:: --ipv6, -6

Uses IPv6 for the development server. This changes the default IP address from
``127.0.0.1`` to ``::1``.

Examples of using different ports and addresses
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Port 8000 on IP address ``127.0.0.1``::

    django-admin runserver

Port 8000 on IP address ``1.2.3.4``::

    django-admin runserver 1.2.3.4:8000

Port 7000 on IP address ``127.0.0.1``::

    django-admin runserver 7000

Port 7000 on IP address ``1.2.3.4``::

    django-admin runserver 1.2.3.4:7000

Port 8000 on IPv6 address ``::1``::

    django-admin runserver -6

Port 7000 on IPv6 address ``::1``::

    django-admin runserver -6 7000

Port 7000 on IPv6 address ``2001:0db8:1234:5678::9``::

    django-admin runserver [2001:0db8:1234:5678::9]:7000

Port 8000 on IPv4 address of host ``localhost``::

    django-admin runserver localhost:8000

Port 8000 on IPv6 address of host ``localhost``::

    django-admin runserver -6 localhost:8000

Serving static files with the development server
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

By default, the development server doesn't serve any static files for your site
(such as CSS files, images, things under :setting:`MEDIA_URL` and so forth). If
you want to configure Django to serve static media, read
:doc:`/howto/static-files/index`.

``sendtestemail``
-----------------

.. django-admin:: sendtestemail [email [email ...]]

.. versionadded:: 1.9

Sends a test email (to confirm email sending through Django is working) to the
recipient(s) specified. For example::

    django-admin sendtestemail foo@example.com bar@example.com

There are a couple of options, and you may use any combination of them
together:

.. django-admin-option:: --managers

Mails the email addresses specified in :setting:`MANAGERS` using
:meth:`~django.core.mail.mail_managers()`.

.. django-admin-option:: --admins

Mails the email addresses specified in :setting:`ADMINS` using
:meth:`~django.core.mail.mail_admins()`.

``shell``
---------

.. django-admin:: shell

Starts the Python interactive interpreter.

.. django-admin-option:: --interface {ipython,bpython,python}, -i {ipython,bpython,python}

Specifies the shell to use. By default, Django will use IPython_ or bpython_ if
either is installed. If both are installed, specify which one you want like so:

IPython::

    django-admin shell -i ipython

bpython::

    django-admin shell -i bpython

If you have a "rich" shell installed but want to force use of the "plain"
Python interpreter, use ``python`` as the interface name, like so::

    django-admin shell -i python

.. deprecated:: 1.10

   In older versions, use the ``--plain`` option instead of ``-i python``. This
   is deprecated and will be removed in Django 2.0.

.. _IPython: https://ipython.org/
.. _bpython: http://bpython-interpreter.org/

.. django-admin-option:: --nostartup

Disables reading the startup script for the "plain" Python interpreter. By
default, the script pointed to by the :envvar:`PYTHONSTARTUP` environment
variable or the ``~/.pythonrc.py`` script is read.

.. django-admin-option:: --command COMMAND, -c COMMAND

.. versionadded:: 1.10

Lets you pass a command as a string to execute it as Django, like so::

    django-admin shell --command="import django; print(django.__version__)"

``showmigrations``
------------------

.. django-admin:: showmigrations [app_label [app_label ...]]

Shows all migrations in a project. You can choose from one of two formats:

.. django-admin-option:: --list, -l

Lists all of the apps Django knows about, the migrations available for each
app, and whether or not each migration is applied (marked by an ``[X]`` next to
the migration name).

Apps without migrations are also listed, but have ``(no migrations)`` printed
under them.

This is the default output format.

.. django-admin-option:: --plan, -p

Shows the migration plan Django will follow to apply migrations. Any supplied
app labels are ignored because the plan might go beyond those apps. Like
``--list``, applied migrations are marked by an ``[X]``. For a ``--verbosity``
of 2 and above, all dependencies of a migration will also be shown.

.. django-admin-option:: --database DATABASE

Specifies the database to examine. Defaults to ``default``.

``sqlflush``
------------

.. django-admin:: sqlflush

Prints the SQL statements that would be executed for the :djadmin:`flush`
command.

.. django-admin-option:: --database DATABASE

Specifies the database for which to print the SQL. Defaults to ``default``.

``sqlmigrate``
--------------

.. django-admin:: sqlmigrate app_label migration_name

Prints the SQL for the named migration. This requires an active database
connection, which it will use to resolve constraint names; this means you must
generate the SQL against a copy of the database you wish to later apply it on.

Note that ``sqlmigrate`` doesn't colorize its output.

.. django-admin-option:: --backwards

Generates the SQL for unapplying the migration. By default, the SQL created is
for running the migration in the forwards direction.

.. django-admin-option:: --database DATABASE

Specifies the database for which to generate the SQL. Defaults to ``default``.

.. versionchanged:: 1.9

    To increase the readability of the overall SQL output the SQL code
    generated for each migration operation is preceded by the operation's
    description.

``sqlsequencereset``
--------------------

.. django-admin:: sqlsequencereset app_label [app_label ...]

Prints the SQL statements for resetting sequences for the given app name(s).

Sequences are indexes used by some database engines to track the next available
number for automatically incremented fields.

Use this command to generate SQL which will fix cases where a sequence is out
of sync with its automatically incremented field data.

.. django-admin-option:: --database DATABASE

Specifies the database for which to print the SQL. Defaults to ``default``.

``squashmigrations``
--------------------

.. django-admin:: squashmigrations app_label [start_migration_name] migration_name

Squashes the migrations for ``app_label`` up to and including ``migration_name``
down into fewer migrations, if possible. The resulting squashed migrations
can live alongside the unsquashed ones safely. For more information,
please read :ref:`migration-squashing`.

.. versionadded:: 1.9

When ``start_migration_name`` is given, Django will only include migrations
starting from and including this migration. This helps to mitigate the
squashing limitation of :class:`~django.db.migrations.operations.RunPython` and
:class:`django.db.migrations.operations.RunSQL` migration operations.

.. django-admin-option:: --no-optimize

Disables the optimizer when generating a squashed migration. By default, Django
will try to optimize the operations in your migrations to reduce the size of
the resulting file. Use this option if this process is failing or creating
incorrect migrations, though please also file a Django bug report about the
behavior, as optimization is meant to be safe.

.. django-admin-option:: --noinput, --no-input

Suppresses all user prompts.

.. versionchanged:: 1.9

    The ``--no-input`` alias was added.

``startapp``
------------

.. django-admin:: startapp name [directory]

Creates a Django app directory structure for the given app name in the current
directory or the given destination.

By default the directory created contains a ``models.py`` file and other app
template files. (See the `source`_ for more details.) If only the app
name is given, the app directory will be created in the current working
directory.

If the optional destination is provided, Django will use that existing
directory rather than creating a new one. You can use '.' to denote the current
working directory.

For example::

    django-admin startapp myapp /Users/jezdez/Code/myapp

.. _custom-app-and-project-templates:

.. django-admin-option:: --template TEMPLATE

Provides the path to a directory with a custom app template file or a path to a
compressed file (``.tar.gz``, ``.tar.bz2``, ``.tgz``, ``.tbz``, ``.zip``)
containing the app template files.

For example, this would look for an app template in the given directory when
creating the ``myapp`` app::

    django-admin startapp --template=/Users/jezdez/Code/my_app_template myapp

Django will also accept URLs (``http``, ``https``, ``ftp``) to compressed
archives with the app template files, downloading and extracting them on the
fly.

For example, taking advantage of GitHub's feature to expose repositories as
zip files, you can use a URL like::

    django-admin startapp --template=https://github.com/githubuser/django-app-template/archive/master.zip myapp

.. django-admin-option:: --extension EXTENSIONS, -e EXTENSIONS

Specifies which file extensions in the app template should be rendered with the
template engine. Defaults to ``py``.

.. django-admin-option:: --name FILES, -n FILES

Specifies which files in the app template (in addition to those matching
``--extension``) should be rendered with the template engine. Defaults to an
empty list.

The :class:`template context <django.template.Context>` used for all matching
files is:

- Any option passed to the ``startapp`` command (among the command's supported
  options)
- ``app_name`` -- the app name as passed to the command
- ``app_directory`` -- the full path of the newly created app
- ``camel_case_app_name`` -- the app name in camel case format
- ``docs_version`` -- the version of the documentation: ``'dev'`` or ``'1.x'``

.. versionadded:: 1.9

    ``camel_case_app_name`` was added.

.. _render_warning:

.. warning::

    When the app template files are rendered with the Django template
    engine (by default all ``*.py`` files), Django will also replace all
    stray template variables contained. For example, if one of the Python files
    contains a docstring explaining a particular feature related
    to template rendering, it might result in an incorrect example.

    To work around this problem, you can use the :ttag:`templatetag`
    templatetag to "escape" the various parts of the template syntax.

    In addition, to allow Python template files that contain Django template
    language syntax while also preventing packaging systems from trying to
    byte-compile invalid ``*.py`` files, template files ending with ``.py-tpl``
    will be renamed to ``.py``.

    .. versionchanged:: 1.9.2

        Renaming of ``.py-tpl`` to ``.py`` was added.

.. _source: https://github.com/django/django/tree/master/django/conf/app_template/

``startproject``
----------------

.. django-admin:: startproject name [directory]

Creates a Django project directory structure for the given project name in
the current directory or the given destination.

By default, the new directory contains ``manage.py`` and a project package
(containing a ``settings.py`` and other files). See the `template source`_ for
details.

If only the project name is given, both the project directory and project
package will be named ``<projectname>`` and the project directory
will be created in the current working directory.

If the optional destination is provided, Django will use that existing
directory as the project directory, and create ``manage.py`` and the project
package within it. Use '.' to denote the current working directory.

For example::

    django-admin startproject myproject /Users/jezdez/Code/myproject_repo

.. django-admin-option:: --template TEMPLATE

Specifies a directory, file path, or URL of a custom project template. See the
:option:`startapp --template` documentation for examples and usage.

.. django-admin-option:: --extension EXTENSIONS, -e EXTENSIONS

Specifies which file extensions in the project template should be rendered with
the template engine. Defaults to ``py``.

.. django-admin-option:: --name FILES, -n FILES

Specifies which files in the project template (in addition to those matching
``--extension``) should be rendered with the template engine. Defaults to an
empty list.

The :class:`template context <django.template.Context>` used is:

- Any option passed to the ``startproject`` command (among the command's
  supported options)
- ``project_name`` -- the project name as passed to the command
- ``project_directory`` -- the full path of the newly created project
- ``secret_key`` -- a random key for the :setting:`SECRET_KEY` setting
- ``docs_version`` -- the version of the documentation: ``'dev'`` or ``'1.x'``

Please also see the :ref:`rendering warning <render_warning>` as mentioned
for :djadmin:`startapp`.

.. _`template source`: https://github.com/django/django/tree/master/django/conf/project_template/

``test``
--------

.. django-admin:: test [test_label [test_label ...]]

Runs tests for all installed apps. See :doc:`/topics/testing/index` for more
information.

.. django-admin-option:: --failfast

Stops running tests and reports the failure immediately after a test fails.

.. django-admin-option:: --testrunner TESTRUNNER

Controls the test runner class that is used to execute tests. This value
overrides the value provided by the :setting:`TEST_RUNNER` setting.

.. django-admin-option:: --liveserver LIVESERVER

Overrides the default address where the live server (used with
:class:`~django.test.LiveServerTestCase`) is expected to run from. The default
value is ``localhost:8081-8179``.

.. versionchanged:: 1.9

    In earlier versions, the default value was ``localhost:8081``.

.. django-admin-option:: --noinput, --no-input

Suppresses all user prompts. A typical prompt is a warning about deleting an
existing test database.

.. versionchanged:: 1.9

    The ``--no-input`` alias was added.

Test runner options
~~~~~~~~~~~~~~~~~~~

The ``test`` command receives options on behalf of the specified
:option:`--testrunner`. These are the options of the default test runner:
:class:`~django.test.runner.DiscoverRunner`.

.. django-admin-option:: --keepdb, -k

Preserves the test database between test runs. This has the advantage of
skipping both the create and destroy actions which can greatly decrease the
time to run tests, especially those in a large test suite. If the test database
does not exist, it will be created on the first run and then preserved for each
subsequent run. Any unapplied migrations will also be applied to the test
database before running the test suite.

.. django-admin-option:: --reverse, -r

Sorts test cases in the opposite execution order. This may help in debugging
the side effects of tests that aren't properly isolated. :ref:`Grouping by test
class <order-of-tests>` is preserved when using this option.

.. django-admin-option:: --debug-sql, -d

Enables :ref:`SQL logging <django-db-logger>` for failing tests. If
``--verbosity`` is ``2``, then queries in passing tests are also output.

.. django-admin-option:: --parallel [N]

.. versionadded:: 1.9

Runs tests in separate parallel processes. Since modern processors have
multiple cores, this allows running tests significantly faster.

By default ``--parallel`` runs one process per core according to
:func:`multiprocessing.cpu_count()`. You can adjust the number of processes
either by providing it as the option's value, e.g. ``--parallel=4``, or by
setting the ``DJANGO_TEST_PROCESSES`` environment variable.

Django distributes test cases — :class:`unittest.TestCase` subclasses — to
subprocesses. If there are fewer test cases than configured processes, Django
will reduce the number of processes accordingly.

Each process gets its own database. You must ensure that different test cases
don't access the same resources. For instance, test cases that touch the
filesystem should create a temporary directory for their own use.

This option requires the third-party ``tblib`` package to display tracebacks
correctly:

.. code-block:: console

    $ pip install tblib

This feature isn't available on Windows. It doesn't work with the Oracle
database backend either.

If you want to use :mod:`pdb` while debugging tests, you must disable parallel
execution (``--parallel=1``). You'll see something like ``bdb.BdbQuit`` if you
don't.

.. warning::

    When test parallelization is enabled and a test fails, Django may be
    unable to display the exception traceback. This can make debugging
    difficult. If you encounter this problem, run the affected test without
    parallelization to see the traceback of the failure.

    This is a known limitation. It arises from the need to serialize objects
    in order to exchange them between processes. See
    :ref:`python:pickle-picklable` for details.

.. option:: --tag TAGS

.. versionadded:: 1.10

Runs only tests :ref:`marked with the specified tags <topics-tagging-tests>`.
May be specified multiple times and combined with :option:`test --exclude-tag`.

.. option:: --exclude-tag EXCLUDE_TAGS

.. versionadded:: 1.10

Excludes tests :ref:`marked with the specified tags <topics-tagging-tests>`.
May be specified multiple times and combined with :option:`test --tag`.

``testserver``
--------------

.. django-admin:: testserver [fixture [fixture ...]]

Runs a Django development server (as in :djadmin:`runserver`) using data from
the given fixture(s).

For example, this command::

    django-admin testserver mydata.json

...would perform the following steps:

1. Create a test database, as described in :ref:`the-test-database`.
2. Populate the test database with fixture data from the given fixtures.
   (For more on fixtures, see the documentation for :djadmin:`loaddata` above.)
3. Runs the Django development server (as in :djadmin:`runserver`), pointed at
   this newly created test database instead of your production database.

This is useful in a number of ways:

* When you're writing :doc:`unit tests </topics/testing/overview>` of how your views
  act with certain fixture data, you can use ``testserver`` to interact with
  the views in a Web browser, manually.

* Let's say you're developing your Django application and have a "pristine"
  copy of a database that you'd like to interact with. You can dump your
  database to a fixture (using the :djadmin:`dumpdata` command, explained
  above), then use ``testserver`` to run your Web application with that data.
  With this arrangement, you have the flexibility of messing up your data
  in any way, knowing that whatever data changes you're making are only
  being made to a test database.

Note that this server does *not* automatically detect changes to your Python
source code (as :djadmin:`runserver` does). It does, however, detect changes to
templates.

.. django-admin-option:: --addrport ADDRPORT

Specifies a different port, or IP address and port, from the default of
``127.0.0.1:8000``. This value follows exactly the same format and serves
exactly the same function as the argument to the :djadmin:`runserver` command.

Examples:

To run the test server on port 7000 with ``fixture1`` and ``fixture2``::

    django-admin testserver --addrport 7000 fixture1 fixture2
    django-admin testserver fixture1 fixture2 --addrport 7000

(The above statements are equivalent. We include both of them to demonstrate
that it doesn't matter whether the options come before or after the fixture
arguments.)

To run on 1.2.3.4:7000 with a ``test`` fixture::

    django-admin testserver --addrport 1.2.3.4:7000 test

.. django-admin-option:: --noinput, --no-input

Suppresses all user prompts. A typical prompt is a warning about deleting an
existing test database.

.. versionchanged:: 1.9

    The ``--no-input`` alias was added.

Commands provided by applications
=================================

Some commands are only available when the ``django.contrib`` application that
:doc:`implements </howto/custom-management-commands>` them has been
:setting:`enabled <INSTALLED_APPS>`. This section describes them grouped by
their application.

``django.contrib.auth``
-----------------------

``changepassword``
~~~~~~~~~~~~~~~~~~

.. django-admin:: changepassword [<username>]

This command is only available if Django's :doc:`authentication system
</topics/auth/index>` (``django.contrib.auth``) is installed.

Allows changing a user's password. It prompts you to enter a new password twice
for the given user. If the entries are identical, this immediately becomes the
new password. If you do not supply a user, the command will attempt to change
the password whose username matches the current user.

.. django-admin-option:: --database DATABASE

Specifies the database to query for the user. Defaults to ``default``.

Example usage::

    django-admin changepassword ringo

``createsuperuser``
~~~~~~~~~~~~~~~~~~~

.. django-admin:: createsuperuser

This command is only available if Django's :doc:`authentication system
</topics/auth/index>` (``django.contrib.auth``) is installed.

Creates a superuser account (a user who has all permissions). This is
useful if you need to create an initial superuser account or if you need to
programmatically generate superuser accounts for your site(s).

When run interactively, this command will prompt for a password for
the new superuser account. When run non-interactively, no password
will be set, and the superuser account will not be able to log in until
a password has been manually set for it.

.. django-admin-option:: --username USERNAME
.. django-admin-option:: --email EMAIL

The username and email address for the new account can be supplied by
using the ``--username`` and ``--email`` arguments on the command
line. If either of those is not supplied, ``createsuperuser`` will prompt for
it when running interactively.

.. django-admin-option:: --database DATABASE

Specifies the database into which the superuser object will be saved.

You can subclass the management command and override ``get_input_data()`` if you
want to customize data input and validation. Consult the source code for
details on the existing implementation and the method's parameters. For example,
it could be useful if you have a ``ForeignKey`` in
:attr:`~django.contrib.auth.models.CustomUser.REQUIRED_FIELDS` and want to
allow creating an instance instead of entering the primary key of an existing
instance.

``django.contrib.gis``
----------------------

``ogrinspect``
~~~~~~~~~~~~~~

This command is only available if :doc:`GeoDjango </ref/contrib/gis/index>`
(``django.contrib.gis``) is installed.

Please refer to its :djadmin:`description <ogrinspect>` in the GeoDjango
documentation.

``django.contrib.sessions``
---------------------------

``clearsessions``
~~~~~~~~~~~~~~~~~

.. django-admin:: clearsessions

Can be run as a cron job or directly to clean out expired sessions.

``django.contrib.sitemaps``
---------------------------

``ping_google``
~~~~~~~~~~~~~~~

This command is only available if the :doc:`Sitemaps framework
</ref/contrib/sitemaps>` (``django.contrib.sitemaps``) is installed.

Please refer to its :djadmin:`description <ping_google>` in the Sitemaps
documentation.

``django.contrib.staticfiles``
------------------------------

``collectstatic``
~~~~~~~~~~~~~~~~~

This command is only available if the :doc:`static files application
</howto/static-files/index>` (``django.contrib.staticfiles``) is installed.

Please refer to its :djadmin:`description <collectstatic>` in the
:doc:`staticfiles </ref/contrib/staticfiles>` documentation.

``findstatic``
~~~~~~~~~~~~~~

This command is only available if the :doc:`static files application
</howto/static-files/index>` (``django.contrib.staticfiles``) is installed.

Please refer to its :djadmin:`description <findstatic>` in the :doc:`staticfiles
</ref/contrib/staticfiles>` documentation.

Default options
===============

.. program:: None

Although some commands may allow their own custom options, every command
allows for the following options:

.. django-admin-option:: --pythonpath PYTHONPATH

Adds the given filesystem path to the Python `import search path`_. If this
isn't provided, ``django-admin`` will use the ``PYTHONPATH`` environment
variable.

This option is unnecessary in ``manage.py``, because it takes care of setting
the Python path for you.

Example usage::

    django-admin migrate --pythonpath='/home/djangoprojects/myproject'

.. _import search path: http://www.diveintopython.net/getting_to_know_python/everything_is_an_object.html

.. django-admin-option:: --settings SETTINGS

Specifies the settings module to use. The settings module should be in Python
package syntax, e.g. ``mysite.settings``. If this isn't provided,
``django-admin`` will use the ``DJANGO_SETTINGS_MODULE`` environment variable.

This option is unnecessary in ``manage.py``, because it uses
``settings.py`` from the current project by default.

Example usage::

    django-admin migrate --settings=mysite.settings

.. django-admin-option:: --traceback

Displays a full stack trace when a :exc:`~django.core.management.CommandError`
is raised. By default, ``django-admin`` will show a simple error message when a
``CommandError`` occurs and a full stack trace for any other exception.

Example usage::

    django-admin migrate --traceback

.. django-admin-option:: --verbosity {0,1,2,3}, --v {0,1,2,3}

Specifies the amount of notification and debug information that a command
should print to the console.

* ``0`` means no output.
* ``1`` means normal output (default).
* ``2`` means verbose output.
* ``3`` means *very* verbose output.

Example usage::

    django-admin migrate --verbosity 2

.. django-admin-option:: --no-color

Disables colorized command output.  Some commands format their output to be
colorized. For example, errors will be printed to the console in red and SQL
statements will be syntax highlighted.

Example usage::

    django-admin runserver --no-color

Extra niceties
==============

.. _syntax-coloring:

Syntax coloring
---------------

The ``django-admin`` / ``manage.py`` commands will use pretty
color-coded output if your terminal supports ANSI-colored output. It
won't use the color codes if you're piping the command's output to
another program.

Under Windows, the native console doesn't support ANSI escape sequences so by
default there is no color output. But you can install the `ANSICON`_
third-party tool, the Django commands will detect its presence and will make
use of its services to color output just like on Unix-based platforms.

The colors used for syntax highlighting can be customized. Django
ships with three color palettes:

* ``dark``, suited to terminals that show white text on a black
  background. This is the default palette.

* ``light``, suited to terminals that show black text on a white
  background.

* ``nocolor``, which disables syntax highlighting.

You select a palette by setting a ``DJANGO_COLORS`` environment
variable to specify the palette you want to use. For example, to
specify the ``light`` palette under a Unix or OS/X BASH shell, you
would run the following at a command prompt::

    export DJANGO_COLORS="light"

You can also customize the colors that are used. Django specifies a
number of roles in which color is used:

* ``error`` - A major error.
* ``notice`` - A minor error.
* ``success`` - A success.
* ``warning`` - A warning.
* ``sql_field`` - The name of a model field in SQL.
* ``sql_coltype`` - The type of a model field in SQL.
* ``sql_keyword`` - An SQL keyword.
* ``sql_table`` - The name of a model in SQL.
* ``http_info`` - A 1XX HTTP Informational server response.
* ``http_success`` - A 2XX HTTP Success server response.
* ``http_not_modified`` - A 304 HTTP Not Modified server response.
* ``http_redirect`` - A 3XX HTTP Redirect server response other than 304.
* ``http_not_found`` - A 404 HTTP Not Found server response.
* ``http_bad_request`` - A 4XX HTTP Bad Request server response other than 404.
* ``http_server_error`` - A 5XX HTTP Server Error response.
* ``migrate_heading`` - A heading in a migrations management command.
* ``migrate_label`` - A migration name.

.. versionchanged:: 1.9

    ``success`` was added.

Each of these roles can be assigned a specific foreground and
background color, from the following list:

* ``black``
* ``red``
* ``green``
* ``yellow``
* ``blue``
* ``magenta``
* ``cyan``
* ``white``

Each of these colors can then be modified by using the following
display options:

* ``bold``
* ``underscore``
* ``blink``
* ``reverse``
* ``conceal``

A color specification follows one of the following patterns:

* ``role=fg``
* ``role=fg/bg``
* ``role=fg,option,option``
* ``role=fg/bg,option,option``

where ``role`` is the name of a valid color role, ``fg`` is the
foreground color, ``bg`` is the background color and each ``option``
is one of the color modifying options. Multiple color specifications
are then separated by a semicolon. For example::

    export DJANGO_COLORS="error=yellow/blue,blink;notice=magenta"

would specify that errors be displayed using blinking yellow on blue,
and notices displayed using magenta. All other color roles would be
left uncolored.

Colors can also be specified by extending a base palette. If you put
a palette name in a color specification, all the colors implied by that
palette will be loaded. So::

    export DJANGO_COLORS="light;error=yellow/blue,blink;notice=magenta"

would specify the use of all the colors in the light color palette,
*except* for the colors for errors and notices which would be
overridden as specified.

.. _ANSICON: http://adoxa.altervista.org/ansicon/

Bash completion
---------------

If you use the Bash shell, consider installing the Django bash completion
script, which lives in ``extras/django_bash_completion`` in the Django
distribution. It enables tab-completion of ``django-admin`` and
``manage.py`` commands, so you can, for instance...

* Type ``django-admin``.
* Press [TAB] to see all available options.
* Type ``sql``, then [TAB], to see all available options whose names start
  with ``sql``.

See :doc:`/howto/custom-management-commands` for how to add customized actions.

==========================================
Running management commands from your code
==========================================

.. function:: django.core.management.call_command(name, *args, **options)

To call a management command from code use ``call_command``.

``name``
  the name of the command to call or a command object. Passing the name is
  preferred unless the object is required for testing.

``*args``
  a list of arguments accepted by the command. Arguments are passed to the
  argument parser, so you can use the same style as you would on the command
  line. For example, ``call_command('flush', 'verbosity=0')``.

``**options``
  named options accepted on the command-line. Options are passed to the command
  without triggering the argument parser, which means you'll need to pass the
  correct type. For example, ``call_command('flush', verbosity=0)`` (zero must
  be an integer rather than a string).

Examples::

      from django.core import management
      from django.core.management.commands import loaddata

      management.call_command('flush', verbosity=0, interactive=False)
      management.call_command('loaddata', 'test_data', verbosity=0)
      management.call_command(loaddata.Command(), 'test_data', verbosity=0)

Note that command options that take no arguments are passed as keywords
with ``True`` or ``False``, as you can see with the ``interactive`` option above.

Named arguments can be passed by using either one of the following syntaxes::

      # Similar to the command line
      management.call_command('dumpdata', '--natural-foreign')

      # Named argument similar to the command line minus the initial dashes and
      # with internal dashes replaced by underscores
      management.call_command('dumpdata', natural_foreign=True)

      # `use_natural_foreign_keys` is the option destination variable
      management.call_command('dumpdata', use_natural_foreign_keys=True)

Command options which take multiple options are passed a list::

      management.call_command('dumpdata', exclude=['contenttypes', 'auth'])

The return value of the ``call_command()`` function is the same as the return
value of the ``handle()`` method of the command.

.. versionchanged:: 1.10

    ``call_command()`` now returns the value received from the
    ``command.handle()`` method. It now also accepts a command object as the
    first argument.

Output redirection
==================

Note that you can redirect standard output and error streams as all commands
support the ``stdout`` and ``stderr`` options. For example, you could write::

    with open('/path/to/command_output') as f:
        management.call_command('dumpdata', stdout=f)

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Exceptions (`大一小学期/Week_3-Python/exam/2016/docs/ref/exceptions.txt`)

=================
Django Exceptions
=================

Django raises some of its own exceptions as well as standard Python exceptions.

Django Core Exceptions
======================

.. module:: django.core.exceptions
    :synopsis: Django core exceptions

Django core exception classes are defined in ``django.core.exceptions``.

``ObjectDoesNotExist``
----------------------

.. exception:: ObjectDoesNotExist

    The base class for :exc:`~django.db.models.Model.DoesNotExist` exceptions;
    a ``try/except`` for ``ObjectDoesNotExist`` will catch
    :exc:`~django.db.models.Model.DoesNotExist` exceptions for all models.

    See :meth:`~django.db.models.query.QuerySet.get()` for further information
    on :exc:`ObjectDoesNotExist` and :exc:`~django.db.models.Model.DoesNotExist`.

``FieldDoesNotExist``
---------------------

.. exception:: FieldDoesNotExist

    The ``FieldDoesNotExist`` exception is raised by a model's
    ``_meta.get_field()`` method when the requested field does not exist on the
    model or on the model's parents.

``MultipleObjectsReturned``
---------------------------

.. exception:: MultipleObjectsReturned

    The :exc:`MultipleObjectsReturned` exception is raised by a query if only
    one object is expected, but multiple objects are returned. A base version
    of this exception is provided in :mod:`django.core.exceptions`; each model
    class contains a subclassed version that can be used to identify the
    specific object type that has returned multiple objects.

    See :meth:`~django.db.models.query.QuerySet.get()` for further information.

``SuspiciousOperation``
-----------------------

.. exception:: SuspiciousOperation

    The :exc:`SuspiciousOperation` exception is raised when a user has
    performed an operation that should be considered suspicious from a security
    perspective, such as tampering with a session cookie. Subclasses of
    ``SuspiciousOperation`` include:

    * ``DisallowedHost``
    * ``DisallowedModelAdminLookup``
    * ``DisallowedModelAdminToField``
    * ``DisallowedRedirect``
    * ``InvalidSessionKey``
    * ``RequestDataTooBig``
    * ``SuspiciousFileOperation``
    * ``SuspiciousMultipartForm``
    * ``SuspiciousSession``
    * ``TooManyFieldsSent``

    If a ``SuspiciousOperation`` exception reaches the WSGI handler level it is
    logged at the ``Error`` level and results in
    a :class:`~django.http.HttpResponseBadRequest`. See the :doc:`logging
    documentation </topics/logging/>` for more information.

``PermissionDenied``
--------------------

.. exception:: PermissionDenied

    The :exc:`PermissionDenied` exception is raised when a user does not have
    permission to perform the action requested.

``ViewDoesNotExist``
--------------------

.. exception:: ViewDoesNotExist

    The :exc:`ViewDoesNotExist` exception is raised by
    :mod:`django.urls` when a requested view does not exist.

``MiddlewareNotUsed``
---------------------

.. exception:: MiddlewareNotUsed

    The :exc:`MiddlewareNotUsed` exception is raised when a middleware is not
    used in the server configuration.

``ImproperlyConfigured``
------------------------

.. exception:: ImproperlyConfigured

    The :exc:`ImproperlyConfigured` exception is raised when Django is
    somehow improperly configured -- for example, if a value in ``settings.py``
    is incorrect or unparseable.

``FieldError``
--------------

.. exception:: FieldError

    The :exc:`FieldError` exception is raised when there is a problem with a
    model field. This can happen for several reasons:

    - A field in a model clashes with a field of the same name from an
      abstract base class
    - An infinite loop is caused by ordering
    - A keyword cannot be parsed from the filter parameters
    - A field cannot be determined from a keyword in the query
      parameters
    - A join is not permitted on the specified field
    - A field name is invalid
    - A query contains invalid order_by arguments

``ValidationError``
-------------------

.. exception:: ValidationError

    The :exc:`ValidationError` exception is raised when data fails form or
    model field validation. For more information about validation, see
    :doc:`Form and Field Validation </ref/forms/validation>`,
    :ref:`Model Field Validation <validating-objects>` and the
    :doc:`Validator Reference </ref/validators>`.

``NON_FIELD_ERRORS``
~~~~~~~~~~~~~~~~~~~~

.. data:: NON_FIELD_ERRORS

``ValidationError``\s that don't belong to a particular field in a form
or model are classified as ``NON_FIELD_ERRORS``. This constant is used
as a key in dictionaries that otherwise map fields to their respective
list of errors.

.. currentmodule:: django.urls

URL Resolver exceptions
=======================

URL Resolver exceptions are defined in ``django.urls``.

.. deprecated:: 1.10

    In older versions, these exceptions are located in
    ``django.core.urlresolvers``. Importing from the old location will continue
    to work until Django 2.0.

``Resolver404``
---------------

.. exception:: Resolver404

    The :exc:`Resolver404` exception is raised by
    :func:`~django.urls.resolve()` if the path passed to ``resolve()`` doesn't
    map to a view. It's a subclass of :class:`django.http.Http404`.

``NoReverseMatch``
------------------

.. exception:: NoReverseMatch

    The :exc:`NoReverseMatch` exception is raised by :mod:`django.urls` when a
    matching URL in your URLconf cannot be identified based on the parameters
    supplied.

.. currentmodule:: django.db

Database Exceptions
===================

Database exceptions may be imported from ``django.db``.

Django wraps the standard database exceptions so that your Django code has a
guaranteed common implementation of these classes.

.. exception:: Error
.. exception:: InterfaceError
.. exception:: DatabaseError
.. exception:: DataError
.. exception:: OperationalError
.. exception:: IntegrityError
.. exception:: InternalError
.. exception:: ProgrammingError
.. exception:: NotSupportedError

The Django wrappers for database exceptions behave exactly the same as
the underlying database exceptions. See :pep:`249`, the Python Database API
Specification v2.0, for further information.

As per :pep:`3134`, a ``__cause__`` attribute is set with the original
(underlying) database exception, allowing access to any additional
information provided. (Note that this attribute is available under
both Python 2 and Python 3, although :pep:`3134` normally only applies
to Python 3. To avoid unexpected differences with Python 3, Django will also
ensure that the exception made available via ``__cause__`` has a usable
``__traceback__`` attribute.)

.. versionchanged:: 1.10

    The ``__traceback__`` attribute described above was added.

.. exception:: models.ProtectedError

Raised to prevent deletion of referenced objects when using
:attr:`django.db.models.PROTECT`. :exc:`models.ProtectedError` is a subclass
of :exc:`IntegrityError`.

.. currentmodule:: django.http

Http Exceptions
===============

Http exceptions may be imported from ``django.http``.

``UnreadablePostError``
-----------------------

.. exception:: UnreadablePostError

    :exc:`UnreadablePostError` is raised when a user cancels an upload.

Transaction Exceptions
======================

.. currentmodule:: django.db.transaction

Transaction exceptions are defined in ``django.db.transaction``.

``TransactionManagementError``
------------------------------

.. exception:: TransactionManagementError

    :exc:`TransactionManagementError` is raised for any and all problems
    related to database transactions.

.. currentmodule:: django.test

Testing Framework Exceptions
============================

Exceptions provided by the ``django.test`` package.

``RedirectCycleError``
----------------------

.. exception:: client.RedirectCycleError

    :exc:`~client.RedirectCycleError` is raised when the test client detects a
    loop or an overly long chain of redirects.

Python Exceptions
=================

Django raises built-in Python exceptions when appropriate as well. See the
Python documentation for further information on the :ref:`bltin-exceptions`.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Index (`大一小学期/Week_3-Python/exam/2016/docs/ref/index.txt`)

=============
API Reference
=============

.. toctree::
   :maxdepth: 1

   applications
   checks
   class-based-views/index
   clickjacking
   contrib/index
   csrf
   databases
   django-admin
   exceptions
   files/index
   forms/index
   middleware
   migration-operations
   models/index
   request-response
   schema-editor
   settings
   signals
   templates/index
   template-response
   unicode
   urlresolvers
   urls
   utils
   validators
   views

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Middleware (`大一小学期/Week_3-Python/exam/2016/docs/ref/middleware.txt`)

==========
Middleware
==========

.. module:: django.middleware
   :synopsis: Django's built-in middleware classes.

This document explains all middleware components that come with Django. For
information on how to use them and how to write your own middleware, see
the :doc:`middleware usage guide </topics/http/middleware>`.

Available middleware
====================

Cache middleware
----------------

.. module:: django.middleware.cache
   :synopsis: Middleware for the site-wide cache.

.. class:: UpdateCacheMiddleware

.. class:: FetchFromCacheMiddleware

Enable the site-wide cache. If these are enabled, each Django-powered page will
be cached for as long as the :setting:`CACHE_MIDDLEWARE_SECONDS` setting
defines. See the :doc:`cache documentation </topics/cache>`.

"Common" middleware
-------------------

.. module:: django.middleware.common
   :synopsis: Middleware adding "common" conveniences for perfectionists.

.. class:: CommonMiddleware

Adds a few conveniences for perfectionists:

* Forbids access to user agents in the :setting:`DISALLOWED_USER_AGENTS`
  setting, which should be a list of compiled regular expression objects.

* Performs URL rewriting based on the :setting:`APPEND_SLASH` and
  :setting:`PREPEND_WWW` settings.

  If :setting:`APPEND_SLASH` is ``True`` and the initial URL doesn't end
  with a slash, and it is not found in the URLconf, then a new URL is
  formed by appending a slash at the end. If this new URL is found in the
  URLconf, then Django redirects the request to this new URL. Otherwise,
  the initial URL is processed as usual.

  For example, ``foo.com/bar`` will be redirected to ``foo.com/bar/`` if
  you don't have a valid URL pattern for ``foo.com/bar`` but *do* have a
  valid pattern for ``foo.com/bar/``.

  If :setting:`PREPEND_WWW` is ``True``, URLs that lack a leading "www."
  will be redirected to the same URL with a leading "www."

  Both of these options are meant to normalize URLs. The philosophy is that
  each URL should exist in one, and only one, place. Technically a URL
  ``foo.com/bar`` is distinct from ``foo.com/bar/`` -- a search-engine
  indexer would treat them as separate URLs -- so it's best practice to
  normalize URLs.

* Handles ETags based on the :setting:`USE_ETAGS` setting. If
  :setting:`USE_ETAGS` is set to ``True``, Django will calculate an ETag
  for each request by MD5-hashing the page content, and it'll take care of
  sending ``Not Modified`` responses, if appropriate.

.. attribute:: CommonMiddleware.response_redirect_class

Defaults to :class:`~django.http.HttpResponsePermanentRedirect`. Subclass
``CommonMiddleware`` and override the attribute to customize the redirects
issued by the middleware.

.. class:: BrokenLinkEmailsMiddleware

* Sends broken link notification emails to :setting:`MANAGERS` (see
  :doc:`/howto/error-reporting`).

Exception middleware
--------------------

.. module:: django.middleware.exception
   :synopsis: Middleware to return responses for exceptions.

.. class:: ExceptionMiddleware

.. versionadded:: 1.10

Catches exceptions raised during the request/response cycle and returns the
appropriate response.

* :class:`~django.http.Http404` is processed by
  :data:`~django.conf.urls.handler404` (or a more friendly debug page if
  :setting:`DEBUG=True <DEBUG>`).
* :class:`~django.core.exceptions.PermissionDenied` is processed
  by :data:`~django.conf.urls.handler403`.
* ``MultiPartParserError`` is processed by :data:`~django.conf.urls.handler400`.
* :class:`~django.core.exceptions.SuspiciousOperation` is processed by
  :data:`~django.conf.urls.handler400`  (or a more friendly debug page if
  :setting:`DEBUG=True <DEBUG>`).
* Any other exception is processed by :data:`~django.conf.urls.handler500`
  (or a more friendly debug page if :setting:`DEBUG=True <DEBUG>`).

Django uses this middleware regardless of whether or not you include it in
:setting:`MIDDLEWARE`, however, you may want to subclass if your own middleware
needs to transform any of these exceptions into the appropriate responses.
:class:`~django.middleware.locale.LocaleMiddleware` does this, for example.

GZip middleware
---------------

.. module:: django.middleware.gzip
   :synopsis: Middleware to serve GZipped content for performance.

.. class:: GZipMiddleware

.. warning::

    Security researchers recently revealed that when compression techniques
    (including ``GZipMiddleware``) are used on a website, the site may become
    exposed to a number of possible attacks. Before using ``GZipMiddleware`` on
    your site, you should consider very carefully whether you are subject to
    these attacks. If you're in *any* doubt about whether you're affected, you
    should avoid using ``GZipMiddleware``. For more details, see the `the BREACH
    paper (PDF)`_ and `breachattack.com`_.

    .. _the BREACH paper (PDF): http://breachattack.com/resources/BREACH%20-%20SSL,%20gone%20in%2030%20seconds.pdf
    .. _breachattack.com: http://breachattack.com

Compresses content for browsers that understand GZip compression (all modern
browsers).

This middleware should be placed before any other middleware that need to
read or write the response body so that compression happens afterward.

It will NOT compress content if any of the following are true:

* The content body is less than 200 bytes long.

* The response has already set the ``Content-Encoding`` header.

* The request (the browser) hasn't sent an ``Accept-Encoding`` header
  containing ``gzip``.

You can apply GZip compression to individual views using the
:func:`~django.views.decorators.gzip.gzip_page()` decorator.

.. versionchanged:: 1.10

    In older versions, Django's CSRF protection mechanism was vulnerable to
    BREACH attacks when compression was used. This is no longer the case, but
    you should still take care not to compromise your own secrets this way.

Conditional GET middleware
--------------------------

.. module:: django.middleware.http
   :synopsis: Middleware handling advanced HTTP features.

.. class:: ConditionalGetMiddleware

Handles conditional GET operations. If the response has a ``ETag`` or
``Last-Modified`` header, and the request has ``If-None-Match`` or
``If-Modified-Since``, the response is replaced by an
:class:`~django.http.HttpResponseNotModified`.

Also sets the ``Date`` and ``Content-Length`` response-headers.

Locale middleware
-----------------

.. module:: django.middleware.locale
   :synopsis: Middleware to enable language selection based on the request.

.. class:: LocaleMiddleware

Enables language selection based on data from the request. It customizes
content for each user. See the :doc:`internationalization documentation
</topics/i18n/translation>`.

.. attribute:: LocaleMiddleware.response_redirect_class

Defaults to :class:`~django.http.HttpResponseRedirect`. Subclass
``LocaleMiddleware`` and override the attribute to customize the redirects
issued by the middleware.

Message middleware
------------------

.. module:: django.contrib.messages.middleware
   :synopsis: Message middleware.

.. class:: MessageMiddleware

Enables cookie- and session-based message support. See the
:doc:`messages documentation </ref/contrib/messages>`.

.. _security-middleware:

Security middleware
-------------------

.. module:: django.middleware.security
    :synopsis: Security middleware.

.. warning::
    If your deployment situation allows, it's usually a good idea to have your
    front-end Web server perform the functionality provided by the
    ``SecurityMiddleware``. That way, if there are requests that aren't served
    by Django (such as static media or user-uploaded files), they will have
    the same protections as requests to your Django application.

.. class:: SecurityMiddleware

The ``django.middleware.security.SecurityMiddleware`` provides several security
enhancements to the request/response cycle. Each one can be independently
enabled or disabled with a setting.

* :setting:`SECURE_BROWSER_XSS_FILTER`
* :setting:`SECURE_CONTENT_TYPE_NOSNIFF`
* :setting:`SECURE_HSTS_INCLUDE_SUBDOMAINS`
* :setting:`SECURE_HSTS_SECONDS`
* :setting:`SECURE_REDIRECT_EXEMPT`
* :setting:`SECURE_SSL_HOST`
* :setting:`SECURE_SSL_REDIRECT`

.. _http-strict-transport-security:

HTTP Strict Transport Security
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For sites that should only be accessed over HTTPS, you can instruct modern
browsers to refuse to connect to your domain name via an insecure connection
(for a given period of time) by setting the `"Strict-Transport-Security"
header`_. This reduces your exposure to some SSL-stripping man-in-the-middle
(MITM) attacks.

``SecurityMiddleware`` will set this header for you on all HTTPS responses if
you set the :setting:`SECURE_HSTS_SECONDS` setting to a non-zero integer value.

When enabling HSTS, it's a good idea to first use a small value for testing,
for example, :setting:`SECURE_HSTS_SECONDS = 3600<SECURE_HSTS_SECONDS>` for one
hour. Each time a Web browser sees the HSTS header from your site, it will
refuse to communicate non-securely (using HTTP) with your domain for the given
period of time. Once you confirm that all assets are served securely on your
site (i.e. HSTS didn't break anything), it's a good idea to increase this value
so that infrequent visitors will be protected (31536000 seconds, i.e. 1 year,
is common).

Additionally, if you set the :setting:`SECURE_HSTS_INCLUDE_SUBDOMAINS` setting
to ``True``, ``SecurityMiddleware`` will add the ``includeSubDomains`` directive
to the ``Strict-Transport-Security`` header. This is recommended (assuming all
subdomains are served exclusively using HTTPS), otherwise your site may still
be vulnerable via an insecure connection to a subdomain.

.. warning::
    The HSTS policy applies to your entire domain, not just the URL of the
    response that you set the header on. Therefore, you should only use it if
    your entire domain is served via HTTPS only.

    Browsers properly respecting the HSTS header will refuse to allow users to
    bypass warnings and connect to a site with an expired, self-signed, or
    otherwise invalid SSL certificate. If you use HSTS, make sure your
    certificates are in good shape and stay that way!

.. note::
    If you are deployed behind a load-balancer or reverse-proxy server, and the
    ``Strict-Transport-Security`` header is not being added to your responses,
    it may be because Django doesn't realize that it's on a secure connection;
    you may need to set the :setting:`SECURE_PROXY_SSL_HEADER` setting.

.. _"Strict-Transport-Security" header: https://en.wikipedia.org/wiki/Strict_Transport_Security

.. _x-content-type-options:

``X-Content-Type-Options: nosniff``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Some browsers will try to guess the content types of the assets that they
fetch, overriding the ``Content-Type`` header. While this can help display
sites with improperly configured servers, it can also pose a security
risk.

If your site serves user-uploaded files, a malicious user could upload a
specially-crafted file that would be interpreted as HTML or JavaScript by
the browser when you expected it to be something harmless.

To learn more about this header and how the browser treats it, you can
read about it on the `IE Security Blog`_.

To prevent the browser from guessing the content type and force it to
always use the type provided in the ``Content-Type`` header, you can pass
the ``X-Content-Type-Options: nosniff`` header.  ``SecurityMiddleware`` will
do this for all responses if the :setting:`SECURE_CONTENT_TYPE_NOSNIFF` setting
is ``True``.

Note that in most deployment situations where Django isn't involved in serving
user-uploaded files, this setting won't help you. For example, if your
:setting:`MEDIA_URL` is served directly by your front-end Web server (nginx,
Apache, etc.) then you'd want to set this header there. On the other hand, if
you are using Django to do something like require authorization in order to
download files and you cannot set the header using your Web server, this
setting will be useful.

.. _IE Security Blog: http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx

.. _x-xss-protection:

``X-XSS-Protection: 1; mode=block``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Some browsers have the ability to block content that appears to be an `XSS
attack`_. They work by looking for JavaScript content in the GET or POST
parameters of a page. If the JavaScript is replayed in the server's response,
the page is blocked from rendering and an error page is shown instead.

The `X-XSS-Protection header`_ is used to control the operation of the
XSS filter.

To enable the XSS filter in the browser, and force it to always block
suspected XSS attacks, you can pass the ``X-XSS-Protection: 1; mode=block``
header. ``SecurityMiddleware`` will do this for all responses if the
:setting:`SECURE_BROWSER_XSS_FILTER` setting is ``True``.

.. warning::
    The browser XSS filter is a useful defense measure, but must not be
    relied upon exclusively. It cannot detect all XSS attacks and not all
    browsers support the header. Ensure you are still :ref:`validating and
    sanitizing <cross-site-scripting>` all input to prevent XSS attacks.

.. _XSS attack: https://en.wikipedia.org/wiki/Cross-site_scripting
.. _X-XSS-Protection header: http://blogs.msdn.com/b/ie/archive/2008/07/02/ie8-security-part-iv-the-xss-filter.aspx

.. _ssl-redirect:

SSL Redirect
~~~~~~~~~~~~

If your site offers both HTTP and HTTPS connections, most users will end up
with an unsecured connection by default. For best security, you should redirect
all HTTP connections to HTTPS.

If you set the :setting:`SECURE_SSL_REDIRECT` setting to True,
``SecurityMiddleware`` will permanently (HTTP 301) redirect all HTTP
connections to HTTPS.

.. note::

    For performance reasons, it's preferable to do these redirects outside of
    Django, in a front-end load balancer or reverse-proxy server such as
    `nginx`_. :setting:`SECURE_SSL_REDIRECT` is intended for the deployment
    situations where this isn't an option.

If the :setting:`SECURE_SSL_HOST` setting has a value, all redirects will be
sent to that host instead of the originally-requested host.

If there are a few pages on your site that should be available over HTTP, and
not redirected to HTTPS, you can list regular expressions to match those URLs
in the :setting:`SECURE_REDIRECT_EXEMPT` setting.

.. note::
    If you are deployed behind a load-balancer or reverse-proxy server and
    Django can't seem to tell when a request actually is already secure, you
    may need to set the :setting:`SECURE_PROXY_SSL_HEADER` setting.

.. _nginx: http://nginx.org

Session middleware
------------------

.. module:: django.contrib.sessions.middleware
   :synopsis: Session middleware.

.. class:: SessionMiddleware

Enables session support. See the :doc:`session documentation
</topics/http/sessions>`.

Site middleware
---------------

.. module:: django.contrib.sites.middleware
  :synopsis: Site middleware.

.. class:: CurrentSiteMiddleware

Adds the ``site`` attribute representing the current site to every incoming
``HttpRequest`` object. See the :ref:`sites documentation <site-middleware>`.

Authentication middleware
-------------------------

.. module:: django.contrib.auth.middleware
  :synopsis: Authentication middleware.

.. class:: AuthenticationMiddleware

Adds the ``user`` attribute, representing the currently-logged-in user, to
every incoming ``HttpRequest`` object. See :ref:`Authentication in Web requests
<auth-web-requests>`.

.. class:: RemoteUserMiddleware

Middleware for utilizing Web server provided authentication. See
:doc:`/howto/auth-remote-user` for usage details.

.. class:: PersistentRemoteUserMiddleware

.. versionadded:: 1.9

Middleware for utilizing Web server provided authentication when enabled only
on the login page. See :ref:`persistent-remote-user-middleware-howto` for usage
details.

CSRF protection middleware
--------------------------

.. module:: django.middleware.csrf
   :synopsis: Middleware adding protection against Cross Site Request
              Forgeries.

.. class:: CsrfViewMiddleware

Adds protection against Cross Site Request Forgeries by adding hidden form
fields to POST forms and checking requests for the correct value. See the
:doc:`Cross Site Request Forgery protection documentation </ref/csrf>`.

``X-Frame-Options`` middleware
------------------------------

.. module:: django.middleware.clickjacking
   :synopsis: Clickjacking protection

.. class:: XFrameOptionsMiddleware

Simple :doc:`clickjacking protection via the X-Frame-Options header </ref/clickjacking/>`.

.. _middleware-ordering:

Middleware ordering
===================

Here are some hints about the ordering of various Django middleware classes:

#. :class:`~django.middleware.security.SecurityMiddleware`

   It should go near the top of the list if you're going to turn on the SSL
   redirect as that avoids running through a bunch of other unnecessary
   middleware.

#. :class:`~django.middleware.cache.UpdateCacheMiddleware`

   Before those that modify the ``Vary`` header (``SessionMiddleware``,
   ``GZipMiddleware``, ``LocaleMiddleware``).

#. :class:`~django.middleware.gzip.GZipMiddleware`

   Before any middleware that may change or use the response body.

   After ``UpdateCacheMiddleware``: Modifies ``Vary`` header.

#. :class:`~django.middleware.http.ConditionalGetMiddleware`

   Before ``CommonMiddleware``: uses its ``Etag`` header when
   :setting:`USE_ETAGS` = ``True``.

#. :class:`~django.contrib.sessions.middleware.SessionMiddleware`

   After ``UpdateCacheMiddleware``: Modifies ``Vary`` header.

#. :class:`~django.middleware.locale.LocaleMiddleware`

   One of the topmost, after ``SessionMiddleware`` (uses session data) and
   ``UpdateCacheMiddleware`` (modifies ``Vary`` header).

#. :class:`~django.middleware.common.CommonMiddleware`

   Before any middleware that may change the response (it calculates ``ETags``).

   After ``GZipMiddleware`` so it won't calculate an ``ETag`` header on gzipped
   contents.

   Close to the top: it redirects when :setting:`APPEND_SLASH` or
   :setting:`PREPEND_WWW` are set to ``True``.

#. :class:`~django.middleware.csrf.CsrfViewMiddleware`

   Before any view middleware that assumes that CSRF attacks have been dealt
   with.

#. :class:`~django.contrib.auth.middleware.AuthenticationMiddleware`

   After ``SessionMiddleware``: uses session storage.

#. :class:`~django.contrib.messages.middleware.MessageMiddleware`

   After ``SessionMiddleware``: can use session-based storage.

#. :class:`~django.middleware.cache.FetchFromCacheMiddleware`

   After any middleware that modifies the ``Vary`` header: that header is used
   to pick a value for the cache hash-key.

#. :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware`

   Should be near the bottom as it's a last-resort type of middleware.

#. :class:`~django.contrib.redirects.middleware.RedirectFallbackMiddleware`

   Should be near the bottom as it's a last-resort type of middleware.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Migration Operations (`大一小学期/Week_3-Python/exam/2016/docs/ref/migration-operations.txt`)

====================
Migration Operations
====================

.. module:: django.db.migrations.operations

Migration files are composed of one or more ``Operation``\s, objects that
declaratively record what the migration should do to your database.

Django also uses these ``Operation`` objects to work out what your models
looked like historically, and to calculate what changes you've made to
your models since the last migration so it can automatically write
your migrations; that's why they're declarative, as it means Django can
easily load them all into memory and run through them without touching
the database to work out what your project should look like.

There are also more specialized ``Operation`` objects which are for things like
:ref:`data migrations <data-migrations>` and for advanced manual database
manipulation. You can also write your own ``Operation`` classes if you want
to encapsulate a custom change you commonly make.

If you need an empty migration file to write your own ``Operation`` objects
into, just use ``python manage.py makemigrations --empty yourappname``,
but be aware that manually adding schema-altering operations can confuse the
migration autodetector and make resulting runs of :djadmin:`makemigrations`
output incorrect code.

All of the core Django operations are available from the
``django.db.migrations.operations`` module.

For introductory material, see the :doc:`migrations topic guide
</topics/migrations>`.

Schema Operations
=================

``CreateModel``
---------------

.. class:: CreateModel(name, fields, options=None, bases=None, managers=None)

Creates a new model in the project history and a corresponding table in the
database to match it.

``name`` is the model name, as would be written in the ``models.py`` file.

``fields`` is a list of 2-tuples of ``(field_name, field_instance)``.
The field instance should be an unbound field (so just
``models.CharField(...)``, rather than a field taken from another model).

``options`` is an optional dictionary of values from the model's ``Meta`` class.

``bases`` is an optional list of other classes to have this model inherit from;
it can contain both class objects as well as strings in the format
``"appname.ModelName"`` if you want to depend on another model (so you inherit
from the historical version). If it's not supplied, it defaults to just
inheriting from the standard ``models.Model``.

``managers`` takes a list of 2-tuples of ``(manager_name, manager_instance)``.
The first manager in the list will be the default manager for this model during
migrations.

``DeleteModel``
---------------

.. class:: DeleteModel(name)

Deletes the model from the project history and its table from the database.

``RenameModel``
---------------

.. class:: RenameModel(old_name, new_name)

Renames the model from an old name to a new one.

You may have to manually add
this if you change the model's name and quite a few of its fields at once; to
the autodetector, this will look like you deleted a model with the old name
and added a new one with a different name, and the migration it creates will
lose any data in the old table.

``AlterModelTable``
-------------------

.. class:: AlterModelTable(name, table)

Changes the model's table name (the :attr:`~django.db.models.Options.db_table`
option on the ``Meta`` subclass).

``AlterUniqueTogether``
-----------------------

.. class:: AlterUniqueTogether(name, unique_together)

Changes the model's set of unique constraints (the
:attr:`~django.db.models.Options.unique_together` option on the ``Meta``
subclass).

``AlterIndexTogether``
----------------------

.. class:: AlterIndexTogether(name, index_together)

Changes the model's set of custom indexes (the
:attr:`~django.db.models.Options.index_together` option on the ``Meta``
subclass).

``AlterOrderWithRespectTo``
---------------------------

.. class:: AlterOrderWithRespectTo(name, order_with_respect_to)

Makes or deletes the ``_order`` column needed for the
:attr:`~django.db.models.Options.order_with_respect_to` option on the ``Meta``
subclass.

``AlterModelOptions``
---------------------

.. class:: AlterModelOptions(name, options)

Stores changes to miscellaneous model options (settings on a model's ``Meta``)
like ``permissions`` and ``verbose_name``. Does not affect the database, but
persists these changes for :class:`RunPython` instances to use. ``options``
should be a dictionary mapping option names to values.

``AlterModelManagers``
----------------------

.. class:: AlterModelManagers(name, managers)

Alters the managers that are available during migrations.

``AddField``
------------

.. class:: AddField(model_name, name, field, preserve_default=True)

Adds a field to a model. ``model_name`` is the model's name, ``name`` is
the field's name, and ``field`` is an unbound Field instance (the thing
you would put in the field declaration in ``models.py`` - for example,
``models.IntegerField(null=True)``.

The ``preserve_default`` argument indicates whether the field's default
value is permanent and should be baked into the project state (``True``),
or if it is temporary and just for this migration (``False``) - usually
because the migration is adding a non-nullable field to a table and needs
a default value to put into existing rows. It does not affect the behavior
of setting defaults in the database directly - Django never sets database
defaults and always applies them in the Django ORM code.

``RemoveField``
---------------

.. class:: RemoveField(model_name, name)

Removes a field from a model.

Bear in mind that when reversed, this is actually adding a field to a model.
The operation is reversible (apart from any data loss, which of course is
irreversible) if the field is nullable or if it has a default value that can be
used to populate the recreated column. If the field is not nullable and does
not have a default value, the operation is irreversible.

``AlterField``
--------------

.. class:: AlterField(model_name, name, field, preserve_default=True)

Alters a field's definition, including changes to its type,
:attr:`~django.db.models.Field.null`, :attr:`~django.db.models.Field.unique`,
:attr:`~django.db.models.Field.db_column` and other field attributes.

The ``preserve_default`` argument indicates whether the field's default
value is permanent and should be baked into the project state (``True``),
or if it is temporary and just for this migration (``False``) - usually
because the migration is altering a nullable field to a non-nullable one and
needs a default value to put into existing rows. It does not affect the
behavior of setting defaults in the database directly - Django never sets
database defaults and always applies them in the Django ORM code.

Note that not all changes are possible on all databases - for example, you
cannot change a text-type field like ``models.TextField()`` into a number-type
field like ``models.IntegerField()`` on most databases.

``RenameField``
---------------

.. class:: RenameField(model_name, old_name, new_name)

Changes a field's name (and, unless :attr:`~django.db.models.Field.db_column`
is set, its column name).

Special Operations
==================

``RunSQL``
----------

.. class:: RunSQL(sql, reverse_sql=None, state_operations=None, hints=None, elidable=False)

Allows running of arbitrary SQL on the database - useful for more advanced
features of database backends that Django doesn't support directly, like
partial indexes.

``sql``, and ``reverse_sql`` if provided, should be strings of SQL to run on
the database. On most database backends (all but PostgreSQL), Django will
split the SQL into individual statements prior to executing them. This
requires installing the sqlparse_ Python library.

You can also pass a list of strings or 2-tuples. The latter is used for passing
queries and parameters in the same way as :ref:`cursor.execute()
<executing-custom-sql>`. These three operations are equivalent::

    migrations.RunSQL("INSERT INTO musician (name) VALUES ('Reinhardt');")
    migrations.RunSQL([("INSERT INTO musician (name) VALUES ('Reinhardt');", None)])
    migrations.RunSQL([("INSERT INTO musician (name) VALUES (%s);", ['Reinhardt'])])

If you want to include literal percent signs in the query, you have to double
them if you are passing parameters.

The ``reverse_sql`` queries are executed when the migration is unapplied, so
you can reverse the changes done in the forwards queries::

    migrations.RunSQL(
        [("INSERT INTO musician (name) VALUES (%s);", ['Reinhardt'])],
        [("DELETE FROM musician where name=%s;", ['Reinhardt'])],
    )

The ``state_operations`` argument is so you can supply operations that are
equivalent to the SQL in terms of project state; for example, if you are
manually creating a column, you should pass in a list containing an ``AddField``
operation here so that the autodetector still has an up-to-date state of the
model (otherwise, when you next run ``makemigrations``, it won't see any
operation that adds that field and so will try to run it again). For example::

    migrations.RunSQL(
        "ALTER TABLE musician ADD COLUMN name varchar(255) NOT NULL;",
        state_operations=[
            migrations.AddField(
                'musician',
                'name',
                models.CharField(max_length=255),
            ),
        ],
    )

The optional ``hints`` argument will be passed as ``**hints`` to the
:meth:`allow_migrate` method of database routers to assist them in making
routing decisions. See :ref:`topics-db-multi-db-hints` for more details on
database hints.

The optional ``elidable`` argument determines whether or not the operation will
be removed (elided) when :ref:`squashing migrations <migration-squashing>`.

.. attribute:: RunSQL.noop

    Pass the ``RunSQL.noop`` attribute to ``sql`` or ``reverse_sql`` when you
    want the operation not to do anything in the given direction. This is
    especially useful in making the operation reversible.

.. _sqlparse: https://pypi.python.org/pypi/sqlparse

.. versionadded:: 1.10

    The ``elidable`` argument was added.

``RunPython``
-------------

.. class:: RunPython(code, reverse_code=None, atomic=None, hints=None, elidable=False)

Runs custom Python code in a historical context. ``code`` (and ``reverse_code``
if supplied) should be callable objects that accept two arguments; the first is
an instance of ``django.apps.registry.Apps`` containing historical models that
match the operation's place in the project history, and the second is an
instance of :class:`SchemaEditor
<django.db.backends.base.schema.BaseDatabaseSchemaEditor>`.

The ``reverse_code`` argument is called when unapplying migrations. This
callable should undo what is done in the ``code`` callable so that the
migration is reversible.

The optional ``hints`` argument will be passed as ``**hints`` to the
:meth:`allow_migrate` method of database routers to assist them in making a
routing decision. See :ref:`topics-db-multi-db-hints` for more details on
database hints.

The optional ``elidable`` argument determines whether or not the operation will
be removed (elided) when :ref:`squashing migrations <migration-squashing>`.

You are advised to write the code as a separate function above the ``Migration``
class in the migration file, and just pass it to ``RunPython``. Here's an
example of using ``RunPython`` to create some initial objects on a ``Country``
model::

    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals

    from django.db import migrations, models

    def forwards_func(apps, schema_editor):
        # We get the model from the versioned app registry;
        # if we directly import it, it'll be the wrong version
        Country = apps.get_model("myapp", "Country")
        db_alias = schema_editor.connection.alias
        Country.objects.using(db_alias).bulk_create([
            Country(name="USA", code="us"),
            Country(name="France", code="fr"),
        ])

    def reverse_func(apps, schema_editor):
        # forwards_func() creates two Country instances,
        # so reverse_func() should delete them.
        Country = apps.get_model("myapp", "Country")
        db_alias = schema_editor.connection.alias
        Country.objects.using(db_alias).filter(name="USA", code="us").delete()
        Country.objects.using(db_alias).filter(name="France", code="fr").delete()

    class Migration(migrations.Migration):

        dependencies = []

        operations = [
            migrations.RunPython(forwards_func, reverse_func),
        ]

This is generally the operation you would use to create
:ref:`data migrations <data-migrations>`, run
custom data updates and alterations, and anything else you need access to an
ORM and/or Python code for.

If you're upgrading from South, this is basically the South pattern as an
operation - one or two methods for forwards and backwards, with an ORM and
schema operations available. Most of the time, you should be able to translate
the ``orm.Model`` or ``orm["appname", "Model"]`` references from South directly
into ``apps.get_model("appname", "Model")`` references here and leave most of
the rest of the code unchanged for data migrations. However, ``apps`` will only
have references to models in the current app unless migrations in other apps
are added to the migration's dependencies.

Much like :class:`RunSQL`, ensure that if you change schema inside here you're
either doing it outside the scope of the Django model system (e.g. triggers)
or that you use :class:`SeparateDatabaseAndState` to add in operations that will
reflect your changes to the model state - otherwise, the versioned ORM and
the autodetector will stop working correctly.

By default, ``RunPython`` will run its contents inside a transaction on
databases that do not support DDL transactions (for example, MySQL and
Oracle). This should be safe, but may cause a crash if you attempt to use
the ``schema_editor`` provided on these backends; in this case, pass
``atomic=False`` to the ``RunPython`` operation.

On databases that do support DDL transactions (SQLite and PostgreSQL),
``RunPython`` operations do not have any transactions automatically added
besides the transactions created for each migration. Thus, on PostgreSQL, for
example, you should avoid combining schema changes and ``RunPython`` operations
in the same migration or you may hit errors like ``OperationalError: cannot
ALTER TABLE "mytable" because it has pending trigger events``.

If you have a different database and aren't sure if it supports DDL
transactions, check the ``django.db.connection.features.can_rollback_ddl``
attribute.

If the ``RunPython`` operation is part of a :ref:`non-atomic migration
<non-atomic-migrations>`, the operation will only be executed in a transaction
if ``atomic=True`` is passed to the ``RunPython`` operation.

.. warning::

    ``RunPython`` does not magically alter the connection of the models for you;
    any model methods you call will go to the default database unless you
    give them the current database alias (available from
    ``schema_editor.connection.alias``, where ``schema_editor`` is the second
    argument to your function).

.. staticmethod:: RunPython.noop

    Pass the ``RunPython.noop`` method to ``code`` or ``reverse_code`` when
    you want the operation not to do anything in the given direction. This is
    especially useful in making the operation reversible.

.. versionadded:: 1.10

    The ``elidable`` argument was added.

.. versionchanged:: 1.10

    The ``atomic`` argument default was changed to ``None``, indicating that
    the atomicity is controlled by the ``atomic`` attribute of the migration.

``SeparateDatabaseAndState``
----------------------------

.. class:: SeparateDatabaseAndState(database_operations=None, state_operations=None)

A highly specialized operation that let you mix and match the database
(schema-changing) and state (autodetector-powering) aspects of operations.

It accepts two list of operations, and when asked to apply state will use the
state list, and when asked to apply changes to the database will use the database
list. Do not use this operation unless you're very sure you know what you're doing.

Writing your own
================

Operations have a relatively simple API, and they're designed so that you can
easily write your own to supplement the built-in Django ones. The basic structure
of an ``Operation`` looks like this::

    from django.db.migrations.operations.base import Operation

    class MyCustomOperation(Operation):

        # If this is False, it means that this operation will be ignored by
        # sqlmigrate; if true, it will be run and the SQL collected for its output.
        reduces_to_sql = False

        # If this is False, Django will refuse to reverse past this operation.
        reversible = False

        def __init__(self, arg1, arg2):
            # Operations are usually instantiated with arguments in migration
            # files. Store the values of them on self for later use.
            pass

        def state_forwards(self, app_label, state):
            # The Operation should take the 'state' parameter (an instance of
            # django.db.migrations.state.ProjectState) and mutate it to match
            # any schema changes that have occurred.
            pass

        def database_forwards(self, app_label, schema_editor, from_state, to_state):
            # The Operation should use schema_editor to apply any changes it
            # wants to make to the database.
            pass

        def database_backwards(self, app_label, schema_editor, from_state, to_state):
            # If reversible is True, this is called when the operation is reversed.
            pass

        def describe(self):
            # This is used to describe what the operation does in console output.
            return "Custom Operation"

You can take this template and work from it, though we suggest looking at the
built-in Django operations in ``django.db.migrations.operations`` - they're
easy to read and cover a lot of the example usage of semi-internal aspects
of the migration framework like ``ProjectState`` and the patterns used to get
historical models, as well as ``ModelState`` and the patterns used to mutate
historical models in ``state_forwards()``.

Some things to note:

* You don't need to learn too much about ``ProjectState`` to just write simple
  migrations; just know that it has an ``apps`` property that gives access to
  an app registry (which you can then call ``get_model`` on).

* ``database_forwards`` and ``database_backwards`` both get two states passed
  to them; these just represent the difference the ``state_forwards`` method
  would have applied, but are given to you for convenience and speed reasons.

* ``to_state`` in the database_backwards method is the *older* state; that is,
  the one that will be the current state once the migration has finished reversing.

* You might see implementations of ``references_model`` on the built-in
  operations; this is part of the autodetection code and does not matter for
  custom operations.

.. warning::

    For performance reasons, the :class:`~django.db.models.Field` instances in
    ``ModelState.fields`` are reused across migrations. You must never change
    the attributes on these instances. If you need to mutate a field in
    ``state_forwards()``, you must remove the old instance from
    ``ModelState.fields`` and add a new instance in its place. The same is true
    for the :class:`~django.db.models.Manager` instances in
    ``ModelState.managers``.

As a simple example, let's make an operation that loads PostgreSQL extensions
(which contain some of PostgreSQL's more exciting features). It's simple enough;
there's no model state changes, and all it does is run one command::

    from django.db.migrations.operations.base import Operation

    class LoadExtension(Operation):

        reversible = True

        def __init__(self, name):
            self.name = name

        def state_forwards(self, app_label, state):
            pass

        def database_forwards(self, app_label, schema_editor, from_state, to_state):
            schema_editor.execute("CREATE EXTENSION IF NOT EXISTS %s" % self.name)

        def database_backwards(self, app_label, schema_editor, from_state, to_state):
            schema_editor.execute("DROP EXTENSION %s" % self.name)

        def describe(self):
            return "Creates extension %s" % self.name

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Request Response (`大一小学期/Week_3-Python/exam/2016/docs/ref/request-response.txt`)

============================
Request and response objects
============================

.. module:: django.http
   :synopsis: Classes dealing with HTTP requests and responses.

Quick overview
==============

Django uses request and response objects to pass state through the system.

When a page is requested, Django creates an :class:`HttpRequest` object that
contains metadata about the request. Then Django loads the appropriate view,
passing the :class:`HttpRequest` as the first argument to the view function.
Each view is responsible for returning an :class:`HttpResponse` object.

This document explains the APIs for :class:`HttpRequest` and
:class:`HttpResponse` objects, which are defined in the :mod:`django.http`
module.

``HttpRequest`` objects
=======================

.. class:: HttpRequest

.. _httprequest-attributes:

Attributes
----------

All attributes should be considered read-only, unless stated otherwise.

.. attribute:: HttpRequest.scheme

    A string representing the scheme of the request (``http`` or ``https``
    usually).

.. attribute:: HttpRequest.body

    The raw HTTP request body as a byte string. This is useful for processing
    data in different ways than conventional HTML forms: binary images,
    XML payload etc. For processing conventional form data, use ``HttpRequest.POST``.

    You can also read from an HttpRequest using a file-like interface. See
    :meth:`HttpRequest.read()`.

.. attribute:: HttpRequest.path

    A string representing the full path to the requested page, not including
    the scheme or domain.

    Example: ``"/music/bands/the_beatles/"``

.. attribute:: HttpRequest.path_info

    Under some Web server configurations, the portion of the URL after the
    host name is split up into a script prefix portion and a path info
    portion. The ``path_info`` attribute always contains the path info portion
    of the path, no matter what Web server is being used. Using this instead
    of :attr:`~HttpRequest.path` can make your code easier to move between
    test and deployment servers.

    For example, if the ``WSGIScriptAlias`` for your application is set to
    ``"/minfo"``, then ``path`` might be ``"/minfo/music/bands/the_beatles/"``
    and ``path_info`` would be ``"/music/bands/the_beatles/"``.

.. attribute:: HttpRequest.method

    A string representing the HTTP method used in the request. This is
    guaranteed to be uppercase. Example::

        if request.method == 'GET':
            do_something()
        elif request.method == 'POST':
            do_something_else()

.. attribute:: HttpRequest.encoding

    A string representing the current encoding used to decode form submission
    data (or ``None``, which means the :setting:`DEFAULT_CHARSET` setting is
    used). You can write to this attribute to change the encoding used when
    accessing the form data. Any subsequent attribute accesses (such as reading
    from ``GET`` or ``POST``) will use the new ``encoding`` value.  Useful if
    you know the form data is not in the :setting:`DEFAULT_CHARSET` encoding.

.. attribute:: HttpRequest.content_type

    .. versionadded:: 1.10

    A string representing the MIME type of the request, parsed from the
    ``CONTENT_TYPE`` header.

.. attribute:: HttpRequest.content_params

    .. versionadded:: 1.10

    A dictionary of key/value parameters included in the ``CONTENT_TYPE``
    header.

.. attribute:: HttpRequest.GET

    A dictionary-like object containing all given HTTP GET parameters. See the
    :class:`QueryDict` documentation below.

.. attribute:: HttpRequest.POST

    A dictionary-like object containing all given HTTP POST parameters,
    providing that the request contains form data. See the
    :class:`QueryDict` documentation below. If you need to access raw or
    non-form data posted in the request, access this through the
    :attr:`HttpRequest.body` attribute instead.

    It's possible that a request can come in via POST with an empty ``POST``
    dictionary -- if, say, a form is requested via the POST HTTP method but
    does not include form data. Therefore, you shouldn't use ``if request.POST``
    to check for use of the POST method; instead, use ``if request.method ==
    "POST"`` (see above).

    Note: ``POST`` does *not* include file-upload information. See ``FILES``.

.. attribute:: HttpRequest.COOKIES

    A standard Python dictionary containing all cookies. Keys and values are
    strings.

.. attribute:: HttpRequest.FILES

    A dictionary-like object containing all uploaded files. Each key in
    ``FILES`` is the ``name`` from the ``<input type="file" name="" />``. Each
    value in ``FILES`` is an :class:`~django.core.files.uploadedfile.UploadedFile`.

    See :doc:`/topics/files` for more information.

    Note that ``FILES`` will only contain data if the request method was POST
    and the ``<form>`` that posted to the request had
    ``enctype="multipart/form-data"``. Otherwise, ``FILES`` will be a blank
    dictionary-like object.

.. attribute:: HttpRequest.META

    A standard Python dictionary containing all available HTTP headers.
    Available headers depend on the client and server, but here are some
    examples:

    * ``CONTENT_LENGTH`` -- The length of the request body (as a string).
    * ``CONTENT_TYPE`` -- The MIME type of the request body.
    * ``HTTP_ACCEPT`` -- Acceptable content types for the response.
    * ``HTTP_ACCEPT_ENCODING`` -- Acceptable encodings for the response.
    * ``HTTP_ACCEPT_LANGUAGE`` -- Acceptable languages for the response.
    * ``HTTP_HOST`` -- The HTTP Host header sent by the client.
    * ``HTTP_REFERER`` -- The referring page, if any.
    * ``HTTP_USER_AGENT`` -- The client's user-agent string.
    * ``QUERY_STRING`` -- The query string, as a single (unparsed) string.
    * ``REMOTE_ADDR`` -- The IP address of the client.
    * ``REMOTE_HOST`` -- The hostname of the client.
    * ``REMOTE_USER`` -- The user authenticated by the Web server, if any.
    * ``REQUEST_METHOD`` -- A string such as ``"GET"`` or ``"POST"``.
    * ``SERVER_NAME`` -- The hostname of the server.
    * ``SERVER_PORT`` -- The port of the server (as a string).

    With the exception of ``CONTENT_LENGTH`` and ``CONTENT_TYPE``, as given
    above, any HTTP headers in the request are converted to ``META`` keys by
    converting all characters to uppercase, replacing any hyphens with
    underscores and adding an ``HTTP_`` prefix to the name. So, for example, a
    header called ``X-Bender`` would be mapped to the ``META`` key
    ``HTTP_X_BENDER``.

    Note that :djadmin:`runserver` strips all headers with underscores in the
    name, so you won't see them in ``META``. This prevents header-spoofing
    based on ambiguity between underscores and dashes both being normalizing to
    underscores in WSGI environment variables. It matches the behavior of
    Web servers like Nginx and Apache 2.4+.

.. attribute:: HttpRequest.resolver_match

    An instance of :class:`~django.urls.ResolverMatch` representing the
    resolved URL. This attribute is only set after URL resolving took place,
    which means it's available in all views but not in middleware which are
    executed before URL resolving takes place (you can use it in
    :meth:`process_view` though).

Attributes set by application code
----------------------------------

Django doesn't set these attributes itself but makes use of them if set by your
application.

.. attribute:: HttpRequest.current_app

    The :ttag:`url` template tag will use its value as the ``current_app``
    argument to :func:`~django.urls.reverse()`.

.. attribute:: HttpRequest.urlconf

    This will be used as the root URLconf for the current request, overriding
    the :setting:`ROOT_URLCONF` setting. See
    :ref:`how-django-processes-a-request` for details.

    ``urlconf`` can be set to ``None`` to revert any changes made by previous
    middleware and return to using the :setting:`ROOT_URLCONF`.

    .. versionchanged:: 1.9

        Setting ``urlconf=None`` raised
        :exc:`~django.core.exceptions.ImproperlyConfigured` in older versions.

Attributes set by middleware
----------------------------

Some of the middleware included in Django's contrib apps set attributes on the
request. If you don't see the attribute on a request, be sure the appropriate
middleware class is listed in :setting:`MIDDLEWARE`.

.. attribute:: HttpRequest.session

    From the :class:`~django.contrib.sessions.middleware.SessionMiddleware`: A
    readable and writable, dictionary-like object that represents the current
    session.

.. attribute:: HttpRequest.site

    From the :class:`~django.contrib.sites.middleware.CurrentSiteMiddleware`:
    An instance of :class:`~django.contrib.sites.models.Site` or
    :class:`~django.contrib.sites.requests.RequestSite` as returned by
    :func:`~django.contrib.sites.shortcuts.get_current_site()`
    representing the current site.

.. attribute:: HttpRequest.user

    From the :class:`~django.contrib.auth.middleware.AuthenticationMiddleware`:
    An instance of :setting:`AUTH_USER_MODEL` representing the currently
    logged-in user. If the user isn't currently logged in, ``user`` will be set
    to an instance of :class:`~django.contrib.auth.models.AnonymousUser`. You
    can tell them apart with
    :attr:`~django.contrib.auth.models.User.is_authenticated`, like so::

        if request.user.is_authenticated:
            ... # Do something for logged-in users.
        else:
            ... # Do something for anonymous users.

Methods
-------

.. method:: HttpRequest.get_host()

    Returns the originating host of the request using information from the
    ``HTTP_X_FORWARDED_HOST`` (if :setting:`USE_X_FORWARDED_HOST` is enabled)
    and ``HTTP_HOST`` headers, in that order. If they don't provide a value,
    the method uses a combination of ``SERVER_NAME`` and ``SERVER_PORT`` as
    detailed in :pep:`3333`.

    Example: ``"127.0.0.1:8000"``

    .. note:: The :meth:`~HttpRequest.get_host()` method fails when the host is
        behind multiple proxies. One solution is to use middleware to rewrite
        the proxy headers, as in the following example::

            from django.django.utils.deprecation import MiddlewareMixin

            class MultipleProxyMiddleware(MiddlewareMixin):
                FORWARDED_FOR_FIELDS = [
                    'HTTP_X_FORWARDED_FOR',
                    'HTTP_X_FORWARDED_HOST',
                    'HTTP_X_FORWARDED_SERVER',
                ]

                def process_request(self, request):
                    """
                    Rewrites the proxy headers so that only the most
                    recent proxy is used.
                    """
                    for field in self.FORWARDED_FOR_FIELDS:
                        if field in request.META:
                            if ',' in request.META[field]:
                                parts = request.META[field].split(',')
                                request.META[field] = parts[-1].strip()

        This middleware should be positioned before any other middleware that
        relies on the value of :meth:`~HttpRequest.get_host()` -- for instance,
        :class:`~django.middleware.common.CommonMiddleware` or
        :class:`~django.middleware.csrf.CsrfViewMiddleware`.

.. method:: HttpRequest.get_port()

    .. versionadded:: 1.9

    Returns the originating port of the request using information from the
    ``HTTP_X_FORWARDED_PORT`` (if :setting:`USE_X_FORWARDED_PORT` is enabled)
    and ``SERVER_PORT`` ``META`` variables, in that order.

.. method:: HttpRequest.get_full_path()

    Returns the ``path``, plus an appended query string, if applicable.

    Example: ``"/music/bands/the_beatles/?print=true"``

.. method:: HttpRequest.build_absolute_uri(location)

    Returns the absolute URI form of ``location``. If no location is provided,
    the location will be set to ``request.get_full_path()``.

    If the location is already an absolute URI, it will not be altered.
    Otherwise the absolute URI is built using the server variables available in
    this request.

    Example: ``"https://example.com/music/bands/the_beatles/?print=true"``

    .. note::

        Mixing HTTP and HTTPS on the same site is discouraged, therefore
        :meth:`~HttpRequest.build_absolute_uri()` will always generate an
        absolute URI with the same scheme the current request has. If you need
        to redirect users to HTTPS, it's best to let your webserver redirect
        all HTTP traffic to HTTPS.

.. method:: HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)

    Returns a cookie value for a signed cookie, or raises a
    ``django.core.signing.BadSignature`` exception if the signature is
    no longer valid. If you provide the ``default`` argument the exception
    will be suppressed and that default value will be returned instead.

    The optional ``salt`` argument can be used to provide extra protection
    against brute force attacks on your secret key. If supplied, the
    ``max_age`` argument will be checked against the signed timestamp
    attached to the cookie value to ensure the cookie is not older than
    ``max_age`` seconds.

    For example::

        >>> request.get_signed_cookie('name')
        'Tony'
        >>> request.get_signed_cookie('name', salt='name-salt')
        'Tony' # assuming cookie was set using the same salt
        >>> request.get_signed_cookie('non-existing-cookie')
        ...
        KeyError: 'non-existing-cookie'
        >>> request.get_signed_cookie('non-existing-cookie', False)
        False
        >>> request.get_signed_cookie('cookie-that-was-tampered-with')
        ...
        BadSignature: ...
        >>> request.get_signed_cookie('name', max_age=60)
        ...
        SignatureExpired: Signature age 1677.3839159 > 60 seconds
        >>> request.get_signed_cookie('name', False, max_age=60)
        False

    See :doc:`cryptographic signing </topics/signing>` for more information.

.. method:: HttpRequest.is_secure()

    Returns ``True`` if the request is secure; that is, if it was made with
    HTTPS.

.. method:: HttpRequest.is_ajax()

    Returns ``True`` if the request was made via an ``XMLHttpRequest``, by
    checking the ``HTTP_X_REQUESTED_WITH`` header for the string
    ``'XMLHttpRequest'``. Most modern JavaScript libraries send this header.
    If you write your own XMLHttpRequest call (on the browser side), you'll
    have to set this header manually if you want ``is_ajax()`` to work.

    If a response varies on whether or not it's requested via AJAX and you are
    using some form of caching like Django's :mod:`cache middleware
    <django.middleware.cache>`, you should decorate the view with
    :func:`vary_on_headers('HTTP_X_REQUESTED_WITH')
    <django.views.decorators.vary.vary_on_headers>` so that the responses are
    properly cached.

.. method:: HttpRequest.read(size=None)
.. method:: HttpRequest.readline()
.. method:: HttpRequest.readlines()
.. method:: HttpRequest.xreadlines()
.. method:: HttpRequest.__iter__()

    Methods implementing a file-like interface for reading from an
    HttpRequest instance. This makes it possible to consume an incoming
    request in a streaming fashion. A common use-case would be to process a
    big XML payload with an iterative parser without constructing a whole
    XML tree in memory.

    Given this standard interface, an HttpRequest instance can be
    passed directly to an XML parser such as ElementTree::

        import xml.etree.ElementTree as ET
        for element in ET.iterparse(request):
            process(element)


``QueryDict`` objects
=====================

.. class:: QueryDict

In an :class:`HttpRequest` object, the ``GET`` and ``POST`` attributes are
instances of ``django.http.QueryDict``, a dictionary-like class customized to
deal with multiple values for the same key. This is necessary because some HTML
form elements, notably ``<select multiple>``, pass multiple values for the same
key.

The ``QueryDict``\ s at ``request.POST`` and ``request.GET`` will be immutable
when accessed in a normal request/response cycle. To get a mutable version you
need to use ``.copy()``.

Methods
-------

:class:`QueryDict` implements all the standard dictionary methods because it's
a subclass of dictionary. Exceptions are outlined here:

.. method:: QueryDict.__init__(query_string=None, mutable=False, encoding=None)

    Instantiates a ``QueryDict`` object based on ``query_string``.

    >>> QueryDict('a=1&a=2&c=3')
    <QueryDict: {'a': ['1', '2'], 'c': ['3']}>

    If ``query_string`` is not passed in, the resulting ``QueryDict`` will be
    empty (it will have no keys or values).

    Most ``QueryDict``\ s you encounter, and in particular those at
    ``request.POST`` and ``request.GET``, will be immutable. If you are
    instantiating one yourself, you can make it mutable by passing
    ``mutable=True`` to its ``__init__()``.

    Strings for setting both keys and values will be converted from ``encoding``
    to unicode. If encoding is not set, it defaults to :setting:`DEFAULT_CHARSET`.

.. method:: QueryDict.__getitem__(key)

    Returns the value for the given key. If the key has more than one value,
    ``__getitem__()`` returns the last value. Raises
    ``django.utils.datastructures.MultiValueDictKeyError`` if the key does not
    exist. (This is a subclass of Python's standard ``KeyError``, so you can
    stick to catching ``KeyError``.)

.. method:: QueryDict.__setitem__(key, value)

    Sets the given key to ``[value]`` (a Python list whose single element is
    ``value``). Note that this, as other dictionary functions that have side
    effects, can only be called on a mutable ``QueryDict`` (such as one that
    was created via ``copy()``).

.. method:: QueryDict.__contains__(key)

    Returns ``True`` if the given key is set. This lets you do, e.g., ``if "foo"
    in request.GET``.

.. method:: QueryDict.get(key, default=None)

    Uses the same logic as ``__getitem__()`` above, with a hook for returning a
    default value if the key doesn't exist.

.. method:: QueryDict.setdefault(key, default=None)

    Just like the standard dictionary ``setdefault()`` method, except it uses
    ``__setitem__()`` internally.

.. method:: QueryDict.update(other_dict)

    Takes either a ``QueryDict`` or standard dictionary. Just like the standard
    dictionary ``update()`` method, except it *appends* to the current
    dictionary items rather than replacing them. For example::

        >>> q = QueryDict('a=1', mutable=True)
        >>> q.update({'a': '2'})
        >>> q.getlist('a')
        ['1', '2']
        >>> q['a'] # returns the last
        '2'

.. method:: QueryDict.items()

    Just like the standard dictionary ``items()`` method, except this uses the
    same last-value logic as ``__getitem__()``. For example::

        >>> q = QueryDict('a=1&a=2&a=3')
        >>> q.items()
        [('a', '3')]

.. method:: QueryDict.iteritems()

    Just like the standard dictionary ``iteritems()`` method. Like
    :meth:`QueryDict.items()` this uses the same last-value logic as
    :meth:`QueryDict.__getitem__()`.

.. method:: QueryDict.iterlists()

    Like :meth:`QueryDict.iteritems()` except it includes all values, as a list,
    for each member of the dictionary.

.. method:: QueryDict.values()

    Just like the standard dictionary ``values()`` method, except this uses the
    same last-value logic as ``__getitem__()``. For example::

        >>> q = QueryDict('a=1&a=2&a=3')
        >>> q.values()
        ['3']

.. method:: QueryDict.itervalues()

    Just like :meth:`QueryDict.values()`, except an iterator.

In addition, ``QueryDict`` has the following methods:

.. method:: QueryDict.copy()

    Returns a copy of the object, using ``copy.deepcopy()`` from the Python
    standard library. This copy will be mutable even if the original was not.

.. method:: QueryDict.getlist(key, default=None)

    Returns the data with the requested key, as a Python list. Returns an
    empty list if the key doesn't exist and no default value was provided.
    It's guaranteed to return a list of some sort unless the default value
    provided is not a list.

.. method:: QueryDict.setlist(key, list_)

    Sets the given key to ``list_`` (unlike ``__setitem__()``).

.. method:: QueryDict.appendlist(key, item)

    Appends an item to the internal list associated with key.

.. method:: QueryDict.setlistdefault(key, default_list=None)

    Just like ``setdefault``, except it takes a list of values instead of a
    single value.

.. method:: QueryDict.lists()

    Like :meth:`items()`, except it includes all values, as a list, for each
    member of the dictionary. For example::

        >>> q = QueryDict('a=1&a=2&a=3')
        >>> q.lists()
        [('a', ['1', '2', '3'])]

.. method:: QueryDict.pop(key)

    Returns a list of values for the given key and removes them from the
    dictionary. Raises ``KeyError`` if the key does not exist. For example::

        >>> q = QueryDict('a=1&a=2&a=3', mutable=True)
        >>> q.pop('a')
        ['1', '2', '3']

.. method:: QueryDict.popitem()

    Removes an arbitrary member of the dictionary (since there's no concept
    of ordering), and returns a two value tuple containing the key and a list
    of all values for the key. Raises ``KeyError`` when called on an empty
    dictionary. For example::

        >>> q = QueryDict('a=1&a=2&a=3', mutable=True)
        >>> q.popitem()
        ('a', ['1', '2', '3'])

.. method:: QueryDict.dict()

    Returns ``dict`` representation of ``QueryDict``. For every (key, list)
    pair in ``QueryDict``, ``dict`` will have (key, item), where item is one
    element of the list, using same logic as :meth:`QueryDict.__getitem__()`::

        >>> q = QueryDict('a=1&a=3&a=5')
        >>> q.dict()
        {'a': '5'}

.. method:: QueryDict.urlencode(safe=None)

    Returns a string of the data in query-string format. Example::

        >>> q = QueryDict('a=2&b=3&b=5')
        >>> q.urlencode()
        'a=2&b=3&b=5'

    Optionally, urlencode can be passed characters which
    do not require encoding. For example::

        >>> q = QueryDict(mutable=True)
        >>> q['next'] = '/a&b/'
        >>> q.urlencode(safe='/')
        'next=/a%26b/'

``HttpResponse`` objects
========================

.. class:: HttpResponse

In contrast to :class:`HttpRequest` objects, which are created automatically by
Django, :class:`HttpResponse` objects are your responsibility. Each view you
write is responsible for instantiating, populating and returning an
:class:`HttpResponse`.

The :class:`HttpResponse` class lives in the :mod:`django.http` module.

Usage
-----

Passing strings
~~~~~~~~~~~~~~~

Typical usage is to pass the contents of the page, as a string, to the
:class:`HttpResponse` constructor::

    >>> from django.http import HttpResponse
    >>> response = HttpResponse("Here's the text of the Web page.")
    >>> response = HttpResponse("Text only, please.", content_type="text/plain")

But if you want to add content incrementally, you can use ``response`` as a
file-like object::

    >>> response = HttpResponse()
    >>> response.write("<p>Here's the text of the Web page.</p>")
    >>> response.write("<p>Here's another paragraph.</p>")

Passing iterators
~~~~~~~~~~~~~~~~~

Finally, you can pass ``HttpResponse`` an iterator rather than strings.
``HttpResponse`` will consume the iterator immediately, store its content as a
string, and discard it. Objects with a ``close()`` method such as files and
generators are immediately closed.

If you need the response to be streamed from the iterator to the client, you
must use the :class:`StreamingHttpResponse` class instead.

.. versionchanged:: 1.10

    Objects with a ``close()`` method used to be closed when the WSGI server
    called ``close()`` on the response.

Setting header fields
~~~~~~~~~~~~~~~~~~~~~

To set or remove a header field in your response, treat it like a dictionary::

    >>> response = HttpResponse()
    >>> response['Age'] = 120
    >>> del response['Age']

Note that unlike a dictionary, ``del`` doesn't raise ``KeyError`` if the header
field doesn't exist.

For setting the ``Cache-Control`` and ``Vary`` header fields, it is recommended
to use the :func:`~django.utils.cache.patch_cache_control` and
:func:`~django.utils.cache.patch_vary_headers` methods from
:mod:`django.utils.cache`, since these fields can have multiple, comma-separated
values. The "patch" methods ensure that other values, e.g. added by a
middleware, are not removed.

HTTP header fields cannot contain newlines. An attempt to set a header field
containing a newline character (CR or LF) will raise ``BadHeaderError``

Telling the browser to treat the response as a file attachment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To tell the browser to treat the response as a file attachment, use the
``content_type`` argument and set the ``Content-Disposition`` header. For example,
this is how you might return a Microsoft Excel spreadsheet::

    >>> response = HttpResponse(my_data, content_type='application/vnd.ms-excel')
    >>> response['Content-Disposition'] = 'attachment; filename="foo.xls"'

There's nothing Django-specific about the ``Content-Disposition`` header, but
it's easy to forget the syntax, so we've included it here.

Attributes
----------

.. attribute:: HttpResponse.content

    A bytestring representing the content, encoded from a Unicode
    object if necessary.

.. attribute:: HttpResponse.charset

    A string denoting the charset in which the response will be encoded. If not
    given at ``HttpResponse`` instantiation time, it will be extracted from
    ``content_type`` and if that is unsuccessful, the
    :setting:`DEFAULT_CHARSET` setting will be used.

.. attribute:: HttpResponse.status_code

    The :rfc:`HTTP status code <7231#section-6>` for the response.

    .. versionchanged:: 1.9

        Unless :attr:`reason_phrase` is explicitly set, modifying the value of
        ``status_code`` outside the constructor will also modify the value of
        ``reason_phrase``.

.. attribute:: HttpResponse.reason_phrase

    The HTTP reason phrase for the response.

    .. versionchanged:: 1.9

        ``reason_phrase`` no longer defaults to all capital letters. It now
        uses the :rfc:`HTTP standard's <7231#section-6.1>` default reason
        phrases.

        Unless explicitly set, ``reason_phrase`` is determined by the current
        value of :attr:`status_code`.

.. attribute:: HttpResponse.streaming

    This is always ``False``.

    This attribute exists so middleware can treat streaming responses
    differently from regular responses.

.. attribute:: HttpResponse.closed

    ``True`` if the response has been closed.

Methods
-------

.. method:: HttpResponse.__init__(content='', content_type=None, status=200, reason=None, charset=None)

    Instantiates an ``HttpResponse`` object with the given page content and
    content type.

    ``content`` should be an iterator or a string. If it's an
    iterator, it should return strings, and those strings will be
    joined together to form the content of the response. If it is not
    an iterator or a string, it will be converted to a string when
    accessed.

    ``content_type`` is the MIME type optionally completed by a character set
    encoding and is used to fill the HTTP ``Content-Type`` header. If not
    specified, it is formed by the :setting:`DEFAULT_CONTENT_TYPE` and
    :setting:`DEFAULT_CHARSET` settings, by default: "`text/html; charset=utf-8`".

    ``status`` is the :rfc:`HTTP status code <7231#section-6>` for the response.

    ``reason`` is the HTTP response phrase. If not provided, a default phrase
    will be used.

    ``charset`` is the charset in which the response will be encoded. If not
    given it will be extracted from ``content_type``, and if that
    is unsuccessful, the :setting:`DEFAULT_CHARSET` setting will be used.

.. method:: HttpResponse.__setitem__(header, value)

    Sets the given header name to the given value. Both ``header`` and
    ``value`` should be strings.

.. method:: HttpResponse.__delitem__(header)

    Deletes the header with the given name. Fails silently if the header
    doesn't exist. Case-insensitive.

.. method:: HttpResponse.__getitem__(header)

    Returns the value for the given header name. Case-insensitive.

.. method:: HttpResponse.has_header(header)

    Returns ``True`` or ``False`` based on a case-insensitive check for a
    header with the given name.

.. method:: HttpResponse.setdefault(header, value)

    Sets a header unless it has already been set.

.. method:: HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False)

    Sets a cookie. The parameters are the same as in the
    :class:`~http.cookies.Morsel` cookie object in the Python standard library.

    * ``max_age`` should be a number of seconds, or ``None`` (default) if
      the cookie should last only as long as the client's browser session.
      If ``expires`` is not specified, it will be calculated.
    * ``expires`` should either be a string in the format
      ``"Wdy, DD-Mon-YY HH:MM:SS GMT"`` or a ``datetime.datetime`` object
      in UTC. If ``expires`` is a ``datetime`` object, the ``max_age``
      will be calculated.
    * Use ``domain`` if you want to set a cross-domain cookie. For example,
      ``domain=".lawrence.com"`` will set a cookie that is readable by
      the domains www.lawrence.com, blogs.lawrence.com and
      calendars.lawrence.com. Otherwise, a cookie will only be readable by
      the domain that set it.
    * Use ``httponly=True`` if you want to prevent client-side
      JavaScript from having access to the cookie.

      HTTPOnly_ is a flag included in a Set-Cookie HTTP response
      header. It is not part of the :rfc:`2109` standard for cookies,
      and it isn't honored consistently by all browsers. However,
      when it is honored, it can be a useful way to mitigate the
      risk of a client-side script from accessing the protected cookie
      data.

    .. _HTTPOnly: https://www.owasp.org/index.php/HTTPOnly

    .. warning::

        Both :rfc:`2109` and :rfc:`6265` state that user agents should support
        cookies of at least 4096 bytes. For many browsers this is also the
        maximum size. Django will not raise an exception if there's an attempt
        to store a cookie of more than 4096 bytes, but many browsers will not
        set the cookie correctly.

.. method:: HttpResponse.set_signed_cookie(key, value, salt='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=True)

    Like :meth:`~HttpResponse.set_cookie()`, but
    :doc:`cryptographic signing </topics/signing>` the cookie before setting
    it. Use in conjunction with :meth:`HttpRequest.get_signed_cookie`.
    You can use the optional ``salt`` argument for added key strength, but
    you will need to remember to pass it to the corresponding
    :meth:`HttpRequest.get_signed_cookie` call.

.. method:: HttpResponse.delete_cookie(key, path='/', domain=None)

    Deletes the cookie with the given key. Fails silently if the key doesn't
    exist.

    Due to the way cookies work, ``path`` and ``domain`` should be the same
    values you used in ``set_cookie()`` -- otherwise the cookie may not be
    deleted.

.. method:: HttpResponse.write(content)

    This method makes an :class:`HttpResponse` instance a file-like object.

.. method:: HttpResponse.flush()

    This method makes an :class:`HttpResponse` instance a file-like object.

.. method:: HttpResponse.tell()

    This method makes an :class:`HttpResponse` instance a file-like object.

.. method:: HttpResponse.getvalue()

    Returns the value of :attr:`HttpResponse.content`. This method makes
    an :class:`HttpResponse` instance a stream-like object.

.. method:: HttpResponse.readable()

   .. versionadded:: 1.10

    Always ``False``. This method makes an :class:`HttpResponse` instance a
    stream-like object.

.. method:: HttpResponse.seekable()

   .. versionadded:: 1.10

    Always ``False``. This method makes an :class:`HttpResponse` instance a
    stream-like object.

.. method:: HttpResponse.writable()

    Always ``True``. This method makes an :class:`HttpResponse` instance a
    stream-like object.

.. method:: HttpResponse.writelines(lines)

    Writes a list of lines to the response. Line separators are not added. This
    method makes an :class:`HttpResponse` instance a stream-like object.

.. _ref-httpresponse-subclasses:

``HttpResponse`` subclasses
---------------------------

Django includes a number of ``HttpResponse`` subclasses that handle different
types of HTTP responses. Like ``HttpResponse``, these subclasses live in
:mod:`django.http`.

.. class:: HttpResponseRedirect

    The first argument to the constructor is required -- the path to redirect
    to. This can be a fully qualified URL
    (e.g. ``'https://www.yahoo.com/search/'``), an absolute path with no domain
    (e.g. ``'/search/'``), or even a relative path (e.g. ``'search/'``). In that
    last case, the client browser will reconstruct the full URL itself
    according to the current path. See :class:`HttpResponse` for other optional
    constructor arguments. Note that this returns an HTTP status code 302.

    .. attribute:: HttpResponseRedirect.url

        This read-only attribute represents the URL the response will redirect
        to (equivalent to the ``Location`` response header).

.. class:: HttpResponsePermanentRedirect

    Like :class:`HttpResponseRedirect`, but it returns a permanent redirect
    (HTTP status code 301) instead of a "found" redirect (status code 302).

.. class:: HttpResponseNotModified

    The constructor doesn't take any arguments and no content should be added
    to this response. Use this to designate that a page hasn't been modified
    since the user's last request (status code 304).

.. class:: HttpResponseBadRequest

    Acts just like :class:`HttpResponse` but uses a 400 status code.

.. class:: HttpResponseNotFound

    Acts just like :class:`HttpResponse` but uses a 404 status code.

.. class:: HttpResponseForbidden

    Acts just like :class:`HttpResponse` but uses a 403 status code.

.. class:: HttpResponseNotAllowed

    Like :class:`HttpResponse`, but uses a 405 status code. The first argument
    to the constructor is required: a list of permitted methods (e.g.
    ``['GET', 'POST']``).

.. class:: HttpResponseGone

    Acts just like :class:`HttpResponse` but uses a 410 status code.

.. class:: HttpResponseServerError

    Acts just like :class:`HttpResponse` but uses a 500 status code.

.. note::

    If a custom subclass of :class:`HttpResponse` implements a ``render``
    method, Django will treat it as emulating a
    :class:`~django.template.response.SimpleTemplateResponse`, and the
    ``render`` method must itself return a valid response object.

``JsonResponse`` objects
========================

.. class:: JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs)

    An :class:`HttpResponse` subclass that helps to create a JSON-encoded
    response. It inherits most behavior from its superclass with a couple
    differences:

    Its default ``Content-Type`` header is set to ``application/json``.

    The first parameter, ``data``, should be a ``dict`` instance. If the
    ``safe`` parameter is set to ``False`` (see below) it can be any
    JSON-serializable object.

    The ``encoder``, which defaults to
    :class:`django.core.serializers.json.DjangoJSONEncoder`, will be used to
    serialize the data. See :ref:`JSON serialization
    <serialization-formats-json>` for more details about this serializer.

    The ``safe`` boolean parameter defaults to ``True``. If it's set to
    ``False``, any object can be passed for serialization (otherwise only
    ``dict`` instances are allowed). If ``safe`` is ``True`` and a non-``dict``
    object is passed as the first argument, a :exc:`TypeError` will be raised.

    The ``json_dumps_params`` parameter is a dictionary of keyword arguments
    to pass to the ``json.dumps()`` call used to generate the response.

    .. versionchanged:: 1.9

        The ``json_dumps_params`` argument was added.

Usage
-----

Typical usage could look like::

    >>> from django.http import JsonResponse
    >>> response = JsonResponse({'foo': 'bar'})
    >>> response.content
    b'{"foo": "bar"}'


Serializing non-dictionary objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In order to serialize objects other than ``dict`` you must set the ``safe``
parameter to ``False``::

    >>> response = JsonResponse([1, 2, 3], safe=False)

Without passing ``safe=False``, a :exc:`TypeError` will be raised.

.. warning::

    Before the `5th edition of ECMAScript
    <http://www.ecma-international.org/ecma-262/5.1/index.html#sec-11.1.4>`_
    it was possible to poison the JavaScript ``Array`` constructor. For this
    reason, Django does not allow passing non-dict objects to the
    :class:`~django.http.JsonResponse` constructor by default.  However, most
    modern browsers implement EcmaScript 5 which removes this attack vector.
    Therefore it is possible to disable this security precaution.

Changing the default JSON encoder
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you need to use a different JSON encoder class you can pass the ``encoder``
parameter to the constructor method::

    >>> response = JsonResponse(data, encoder=MyJSONEncoder)

.. _httpresponse-streaming:

``StreamingHttpResponse`` objects
=================================

.. class:: StreamingHttpResponse

The :class:`StreamingHttpResponse` class is used to stream a response from
Django to the browser. You might want to do this if generating the response
takes too long or uses too much memory. For instance, it's useful for
:ref:`generating large CSV files <streaming-csv-files>`.

.. admonition:: Performance considerations

    Django is designed for short-lived requests. Streaming responses will tie
    a worker process for the entire duration of the response. This may result
    in poor performance.

    Generally speaking, you should perform expensive tasks outside of the
    request-response cycle, rather than resorting to a streamed response.

The :class:`StreamingHttpResponse` is not a subclass of :class:`HttpResponse`,
because it features a slightly different API. However, it is almost identical,
with the following notable differences:

* It should be given an iterator that yields strings as content.

* You cannot access its content, except by iterating the response object
  itself. This should only occur when the response is returned to the client.

* It has no ``content`` attribute. Instead, it has a
  :attr:`~StreamingHttpResponse.streaming_content` attribute.

* You cannot use the file-like object ``tell()`` or ``write()`` methods.
  Doing so will raise an exception.

:class:`StreamingHttpResponse` should only be used in situations where it is
absolutely required that the whole content isn't iterated before transferring
the data to the client. Because the content can't be accessed, many
middlewares can't function normally. For example the ``ETag`` and ``Content-
Length`` headers can't be generated for streaming responses.

Attributes
----------

.. attribute:: StreamingHttpResponse.streaming_content

    An iterator of strings representing the content.

.. attribute:: StreamingHttpResponse.status_code

    The :rfc:`HTTP status code <7231#section-6>` for the response.

    .. versionchanged:: 1.9

        Unless :attr:`reason_phrase` is explicitly set, modifying the value of
        ``status_code`` outside the constructor will also modify the value of
        ``reason_phrase``.

.. attribute:: StreamingHttpResponse.reason_phrase

    The HTTP reason phrase for the response.

    .. versionchanged:: 1.9

        ``reason_phrase`` no longer defaults to all capital letters. It now
        uses the :rfc:`HTTP standard's <7231#section-6.1>` default reason
        phrases.

        Unless explicitly set, ``reason_phrase`` is determined by the current
        value of :attr:`status_code`.

.. attribute:: StreamingHttpResponse.streaming

    This is always ``True``.

``FileResponse`` objects
========================

.. class:: FileResponse

:class:`FileResponse` is a subclass of :class:`StreamingHttpResponse` optimized
for binary files. It uses `wsgi.file_wrapper`_ if provided by the wsgi server,
otherwise it streams the file out in small chunks.

.. _wsgi.file_wrapper: https://www.python.org/dev/peps/pep-3333/#optional-platform-specific-file-handling

``FileResponse`` expects a file open in binary mode like so::

    >>> from django.http import FileResponse
    >>> response = FileResponse(open('myfile.png', 'rb'))

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Schema Editor (`大一小学期/Week_3-Python/exam/2016/docs/ref/schema-editor.txt`)

================
``SchemaEditor``
================

.. module:: django.db.backends.base.schema

.. class:: BaseDatabaseSchemaEditor

Django's migration system is split into two parts; the logic for calculating
and storing what operations should be run (``django.db.migrations``), and the
database abstraction layer that turns things like "create a model" or
"delete a field" into SQL - which is the job of the ``SchemaEditor``.

It's unlikely that you will want to interact directly with ``SchemaEditor`` as
a normal developer using Django, but if you want to write your own migration
system, or have more advanced needs, it's a lot nicer than writing SQL.

Each database backend in Django supplies its own version of ``SchemaEditor``,
and it's always accessible via the ``connection.schema_editor()`` context
manager::

    with connection.schema_editor() as schema_editor:
        schema_editor.delete_model(MyModel)

It must be used via the context manager as this allows it to manage things
like transactions and deferred SQL (like creating ``ForeignKey`` constraints).

It exposes all possible operations as methods, that should be called in
the order you wish changes to be applied. Some possible operations or types
of change are not possible on all databases - for example, MyISAM does not
support foreign key constraints.

If you are writing or maintaining a third-party database backend for Django,
you will need to provide a ``SchemaEditor`` implementation in order to work with
1.7's migration functionality - however, as long as your database is relatively
standard in its use of SQL and relational design, you should be able to
subclass one of the built-in Django ``SchemaEditor`` classes and just tweak the
syntax a little. Also note that there are a few new database features that
migrations will look for: ``can_rollback_ddl`` and
``supports_combined_alters`` are the most important.

Methods
=======

``execute()``
-------------

.. method:: BaseDatabaseSchemaEditor.execute(sql, params=[])

Executes the SQL statement passed in, with parameters if supplied. This
is a simple wrapper around the normal database cursors that allows
capture of the SQL to a ``.sql`` file if the user wishes.

``create_model()``
------------------

.. method:: BaseDatabaseSchemaEditor.create_model(model)

Creates a new table in the database for the provided model, along with any
unique constraints or indexes it requires.

``delete_model()``
------------------

.. method:: BaseDatabaseSchemaEditor.delete_model(model)

Drops the model's table in the database along with any unique constraints
or indexes it has.

``alter_unique_together()``
---------------------------

.. method:: BaseDatabaseSchemaEditor.alter_unique_together(model, old_unique_together, new_unique_together)

Changes a model's :attr:`~django.db.models.Options.unique_together` value; this
will add or remove unique constraints from the model's table until they match
the new value.

``alter_index_together()``
--------------------------

.. method:: BaseDatabaseSchemaEditor.alter_index_together(model, old_index_together, new_index_together)

Changes a model's :attr:`~django.db.models.Options.index_together` value; this
will add or remove indexes from the model's table until they match the new
value.

``alter_db_table()``
--------------------

.. method:: BaseDatabaseSchemaEditor.alter_db_table(model, old_db_table, new_db_table)

Renames the model's table from ``old_db_table`` to ``new_db_table``.

``alter_db_tablespace()``
-------------------------

.. method:: BaseDatabaseSchemaEditor.alter_db_tablespace(model, old_db_tablespace, new_db_tablespace)

Moves the model's table from one tablespace to another.

``add_field()``
---------------

.. method:: BaseDatabaseSchemaEditor.add_field(model, field)

Adds a column (or sometimes multiple) to the model's table to represent the
field. This will also add indexes or a unique constraint
if the field has ``db_index=True`` or ``unique=True``.

If the field is a ``ManyToManyField`` without a value for ``through``, instead
of creating a column, it will make a table to represent the relationship. If
``through`` is provided, it is a no-op.

If the field is a ``ForeignKey``, this will also add the foreign key
constraint to the column.

``remove_field()``
------------------

.. method:: BaseDatabaseSchemaEditor.remove_field(model, field)

Removes the column(s) representing the field from the model's table, along
with any unique constraints, foreign key constraints, or indexes caused by
that field.

If the field is a ManyToManyField without a value for ``through``, it will
remove the table created to track the relationship. If
``through`` is provided, it is a no-op.

``alter_field()``
-----------------

.. method:: BaseDatabaseSchemaEditor.alter_field(model, old_field, new_field, strict=False)

This transforms the field on the model from the old field to the new one. This
includes changing the name of the column (the
:attr:`~django.db.models.Field.db_column` attribute), changing the type of the
field (if the field class changes), changing the ``NULL`` status of the field,
adding or removing field-only unique constraints and indexes, changing primary
key, and changing the destination of ``ForeignKey`` constraints.

The most common transformation this cannot do is transforming a
``ManyToManyField`` into a normal Field or vice-versa; Django cannot do this
without losing data, and so it will refuse to do it. Instead,
:meth:`.remove_field` and :meth:`.add_field` should be called separately.

If the database has the ``supports_combined_alters``, Django will try and
do as many of these in a single database call as possible; otherwise, it will
issue a separate ALTER statement for each change, but will not issue ALTERs
where no change is required (as South often did).

Attributes
==========

All attributes should be considered read-only unless stated otherwise.

``connection``
--------------

.. attribute:: SchemaEditor.connection

A connection object to the database. A useful attribute of the connection is
``alias`` which can be used to determine the name of the database being
accessed.

This is useful when doing data migrations for :ref:`migrations with multiple
databases <data-migrations-and-multiple-databases>`.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Settings (`大一小学期/Week_3-Python/exam/2016/docs/ref/settings.txt`)

========
Settings
========

.. contents::
    :local:
    :depth: 1

.. warning::

    Be careful when you override settings, especially when the default value
    is a non-empty list or dictionary, such as :setting:`MIDDLEWARE_CLASSES`
    and :setting:`STATICFILES_FINDERS`. Make sure you keep the components
    required by the features of Django you wish to use.

Core Settings
=============

Here's a list of settings available in Django core and their default values.
Settings provided by contrib apps are listed below, followed by a topical index
of the core settings. For introductory material, see the :doc:`settings topic
guide </topics/settings>`.

.. setting:: ABSOLUTE_URL_OVERRIDES

``ABSOLUTE_URL_OVERRIDES``
--------------------------

Default: ``{}`` (Empty dictionary)

A dictionary mapping ``"app_label.model_name"`` strings to functions that take
a model object and return its URL. This is a way of inserting or overriding
``get_absolute_url()`` methods on a per-installation basis. Example::

    ABSOLUTE_URL_OVERRIDES = {
        'blogs.weblog': lambda o: "/blogs/%s/" % o.slug,
        'news.story': lambda o: "/stories/%s/%s/" % (o.pub_year, o.slug),
    }

Note that the model name used in this setting should be all lower-case, regardless
of the case of the actual model class name.

.. setting:: ADMINS

``ADMINS``
----------

Default: ``[]`` (Empty list)

A list of all the people who get code error notifications. When
``DEBUG=False`` and a view raises an exception, Django will email these people
with the full exception information. Each item in the list should be a tuple
of (Full name, email address). Example::

    [('John', 'john@example.com'), ('Mary', 'mary@example.com')]

Note that Django will email *all* of these people whenever an error happens.
See :doc:`/howto/error-reporting` for more information.

.. setting:: ALLOWED_HOSTS

``ALLOWED_HOSTS``
-----------------

Default: ``[]`` (Empty list)

A list of strings representing the host/domain names that this Django site can
serve. This is a security measure to prevent :ref:`HTTP Host header attacks
<host-headers-virtual-hosting>`, which are possible even under many
seemingly-safe web server configurations.

Values in this list can be fully qualified names (e.g. ``'www.example.com'``),
in which case they will be matched against the request's ``Host`` header
exactly (case-insensitive, not including port). A value beginning with a period
can be used as a subdomain wildcard: ``'.example.com'`` will match
``example.com``, ``www.example.com``, and any other subdomain of
``example.com``. A value of ``'*'`` will match anything; in this case you are
responsible to provide your own validation of the ``Host`` header (perhaps in a
middleware; if so this middleware must be listed first in
:setting:`MIDDLEWARE`).

Django also allows the `fully qualified domain name (FQDN)`_ of any entries.
Some browsers include a trailing dot in the ``Host`` header which Django
strips when performing host validation.

.. _`fully qualified domain name (FQDN)`: https://en.wikipedia.org/wiki/Fully_qualified_domain_name

If the ``Host`` header (or ``X-Forwarded-Host`` if
:setting:`USE_X_FORWARDED_HOST` is enabled) does not match any value in this
list, the :meth:`django.http.HttpRequest.get_host()` method will raise
:exc:`~django.core.exceptions.SuspiciousOperation`.

When :setting:`DEBUG` is ``True`` or when running tests, host validation is
disabled; any host will be accepted. Thus it's usually only necessary to set it
in production.

This validation only applies via :meth:`~django.http.HttpRequest.get_host()`;
if your code accesses the ``Host`` header directly from ``request.META`` you
are bypassing this security protection.

.. setting:: APPEND_SLASH

``APPEND_SLASH``
----------------

Default: ``True``

When set to ``True``, if the request URL does not match any of the patterns
in the URLconf and it doesn't end in a slash, an HTTP redirect is issued to the
same URL with a slash appended. Note that the redirect may cause any data
submitted in a POST request to be lost.

The :setting:`APPEND_SLASH` setting is only used if
:class:`~django.middleware.common.CommonMiddleware` is installed
(see :doc:`/topics/http/middleware`). See also :setting:`PREPEND_WWW`.

.. setting:: CACHES

``CACHES``
----------

Default::

    {
        'default': {
            'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        }
    }

A dictionary containing the settings for all caches to be used with
Django. It is a nested dictionary whose contents maps cache aliases
to a dictionary containing the options for an individual cache.

The :setting:`CACHES` setting must configure a ``default`` cache;
any number of additional caches may also be specified. If you
are using a cache backend other than the local memory cache, or
you need to define multiple caches, other options will be required.
The following cache options are available.

.. setting:: CACHES-BACKEND

``BACKEND``
~~~~~~~~~~~

Default: ``''`` (Empty string)

The cache backend to use. The built-in cache backends are:

* ``'django.core.cache.backends.db.DatabaseCache'``
* ``'django.core.cache.backends.dummy.DummyCache'``
* ``'django.core.cache.backends.filebased.FileBasedCache'``
* ``'django.core.cache.backends.locmem.LocMemCache'``
* ``'django.core.cache.backends.memcached.MemcachedCache'``
* ``'django.core.cache.backends.memcached.PyLibMCCache'``

You can use a cache backend that doesn't ship with Django by setting
:setting:`BACKEND <CACHES-BACKEND>` to a fully-qualified path of a cache
backend class (i.e. ``mypackage.backends.whatever.WhateverCache``).

.. setting:: CACHES-KEY_FUNCTION

``KEY_FUNCTION``
~~~~~~~~~~~~~~~~

A string containing a dotted path to a function (or any callable) that defines how to
compose a prefix, version and key into a final cache key. The default
implementation is equivalent to the function::

    def make_key(key, key_prefix, version):
        return ':'.join([key_prefix, str(version), key])

You may use any key function you want, as long as it has the same
argument signature.

See the :ref:`cache documentation <cache_key_transformation>` for more
information.

.. setting:: CACHES-KEY_PREFIX

``KEY_PREFIX``
~~~~~~~~~~~~~~

Default: ``''`` (Empty string)

A string that will be automatically included (prepended by default) to
all cache keys used by the Django server.

See the :ref:`cache documentation <cache_key_prefixing>` for more information.

.. setting:: CACHES-LOCATION

``LOCATION``
~~~~~~~~~~~~

Default: ``''`` (Empty string)

The location of the cache to use. This might be the directory for a
file system cache, a host and port for a memcache server, or simply an
identifying name for a local memory cache. e.g.::

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
            'LOCATION': '/var/tmp/django_cache',
        }
    }

.. setting:: CACHES-OPTIONS

``OPTIONS``
~~~~~~~~~~~

Default: ``None``

Extra parameters to pass to the cache backend. Available parameters
vary depending on your cache backend.

Some information on available parameters can be found in the
:ref:`cache arguments <cache_arguments>` documentation. For more information,
consult your backend module's own documentation.

.. setting:: CACHES-TIMEOUT

``TIMEOUT``
~~~~~~~~~~~

Default: ``300``

The number of seconds before a cache entry is considered stale. If the value of
this settings is ``None``, cache entries will not expire.

.. setting:: CACHES-VERSION

``VERSION``
~~~~~~~~~~~

Default: ``1``

The default version number for cache keys generated by the Django server.

See the :ref:`cache documentation <cache_versioning>` for more information.

.. setting:: CACHE_MIDDLEWARE_ALIAS

``CACHE_MIDDLEWARE_ALIAS``
--------------------------

Default: ``default``

The cache connection to use for the :ref:`cache middleware
<the-per-site-cache>`.

.. setting:: CACHE_MIDDLEWARE_KEY_PREFIX

``CACHE_MIDDLEWARE_KEY_PREFIX``
-------------------------------

Default: ``''`` (Empty string)

A string which will be prefixed to the cache keys generated by the :ref:`cache
middleware <the-per-site-cache>`. This prefix is combined with the
:setting:`KEY_PREFIX <CACHES-KEY_PREFIX>` setting; it does not replace it.

See :doc:`/topics/cache`.

.. setting:: CACHE_MIDDLEWARE_SECONDS

``CACHE_MIDDLEWARE_SECONDS``
----------------------------

Default: ``600``

The default number of seconds to cache a page for the :ref:`cache middleware
<the-per-site-cache>`.

See :doc:`/topics/cache`.

.. _settings-csrf:

.. setting:: CSRF_COOKIE_AGE

``CSRF_COOKIE_AGE``
-------------------

Default: ``31449600`` (approximately 1 year, in seconds)

The age of CSRF cookies, in seconds.

The reason for setting a long-lived expiration time is to avoid problems in
the case of a user closing a browser or bookmarking a page and then loading
that page from a browser cache. Without persistent cookies, the form submission
would fail in this case.

Some browsers (specifically Internet Explorer) can disallow the use of
persistent cookies or can have the indexes to the cookie jar corrupted on disk,
thereby causing CSRF protection checks to (sometimes intermittently) fail.
Change this setting to ``None`` to use session-based CSRF cookies, which
keep the cookies in-memory instead of on persistent storage.

.. setting:: CSRF_COOKIE_DOMAIN

``CSRF_COOKIE_DOMAIN``
----------------------

Default: ``None``

The domain to be used when setting the CSRF cookie.  This can be useful for
easily allowing cross-subdomain requests to be excluded from the normal cross
site request forgery protection.  It should be set to a string such as
``".example.com"`` to allow a POST request from a form on one subdomain to be
accepted by a view served from another subdomain.

Please note that the presence of this setting does not imply that Django's CSRF
protection is safe from cross-subdomain attacks by default - please see the
:ref:`CSRF limitations <csrf-limitations>` section.

.. setting:: CSRF_COOKIE_HTTPONLY

``CSRF_COOKIE_HTTPONLY``
------------------------

Default: ``False``

Whether to use ``HttpOnly`` flag on the CSRF cookie. If this is set to
``True``, client-side JavaScript will not to be able to access the CSRF cookie.

This can help prevent malicious JavaScript from bypassing CSRF protection. If
you enable this and need to send the value of the CSRF token with Ajax requests,
your JavaScript will need to pull the value from a hidden CSRF token form input
on the page instead of from the cookie.

See :setting:`SESSION_COOKIE_HTTPONLY` for details on ``HttpOnly``.

.. setting:: CSRF_COOKIE_NAME

``CSRF_COOKIE_NAME``
--------------------

Default: ``'csrftoken'``

The name of the cookie to use for the CSRF authentication token. This can be
whatever you want (as long as it's different from the other cookie names in
your application). See :doc:`/ref/csrf`.

.. setting:: CSRF_COOKIE_PATH

``CSRF_COOKIE_PATH``
--------------------

Default: ``'/'``

The path set on the CSRF cookie. This should either match the URL path of your
Django installation or be a parent of that path.

This is useful if you have multiple Django instances running under the same
hostname. They can use different cookie paths, and each instance will only see
its own CSRF cookie.

.. setting:: CSRF_COOKIE_SECURE

``CSRF_COOKIE_SECURE``
----------------------

Default: ``False``

Whether to use a secure cookie for the CSRF cookie. If this is set to ``True``,
the cookie will be marked as "secure," which means browsers may ensure that the
cookie is only sent with an HTTPS connection.

.. setting:: CSRF_FAILURE_VIEW

``CSRF_FAILURE_VIEW``
---------------------

Default: ``'django.views.csrf.csrf_failure'``

A dotted path to the view function to be used when an incoming request is
rejected by the :doc:`CSRF protection </ref/csrf>`. The function should have
this signature::

    def csrf_failure(request, reason=""):
        ...

where ``reason`` is a short message (intended for developers or logging, not
for end users) indicating the reason the request was rejected. It should return
an :class:`~django.http.HttpResponseForbidden`.

``django.views.csrf.csrf_failure()`` accepts an additional ``template_name``
parameter that defaults to ``'403_csrf.html'``. If a template with that name
exists, it will be used to render the page.

.. versionchanged:: 1.10

   The ``template_name`` parameter and the behavior of searching for a template
   called ``403_csrf.html`` were added to ``csrf_failure()``.

.. setting:: CSRF_HEADER_NAME

``CSRF_HEADER_NAME``
--------------------

.. versionadded:: 1.9

Default: ``'HTTP_X_CSRFTOKEN'``

The name of the request header used for CSRF authentication.

As with other HTTP headers in ``request.META``, the header name received from
the server is normalized by converting all characters to uppercase, replacing
any hyphens with underscores, and adding an ``'HTTP_'`` prefix to the name.
For example, if your client sends a ``'X-XSRF-TOKEN'`` header, the setting
should be ``'HTTP_X_XSRF_TOKEN'``.

.. setting:: CSRF_TRUSTED_ORIGINS

``CSRF_TRUSTED_ORIGINS``
------------------------

.. versionadded:: 1.9

Default: ``[]`` (Empty list)

A list of hosts which are trusted origins for unsafe requests (e.g. ``POST``).
For a :meth:`secure <django.http.HttpRequest.is_secure>` unsafe
request, Django's CSRF protection requires that the request have a ``Referer``
header that matches the origin present in the ``Host`` header. This prevents,
for example, a ``POST`` request from ``subdomain.example.com`` from succeeding
against ``api.example.com``. If you need cross-origin unsafe requests over
HTTPS, continuing the example, add ``"subdomain.example.com"`` to this list.
The setting also supports subdomains, so you could add ``".example.com"``, for
example, to allow access from all subdomains of ``example.com``.

.. setting:: DATABASES

``DATABASES``
-------------

Default: ``{}`` (Empty dictionary)

A dictionary containing the settings for all databases to be used with
Django. It is a nested dictionary whose contents map a database alias
to a dictionary containing the options for an individual database.

The :setting:`DATABASES` setting must configure a ``default`` database;
any number of additional databases may also be specified.

The simplest possible settings file is for a single-database setup using
SQLite. This can be configured using the following::

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': 'mydatabase',
        }
    }

When connecting to other database backends, such as MySQL, Oracle, or
PostgreSQL, additional connection parameters will be required. See
the :setting:`ENGINE <DATABASE-ENGINE>` setting below on how to specify
other database types. This example is for PostgreSQL::

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': 'mydatabase',
            'USER': 'mydatabaseuser',
            'PASSWORD': 'mypassword',
            'HOST': '127.0.0.1',
            'PORT': '5432',
        }
    }

The following inner options that may be required for more complex
configurations are available:

.. setting:: DATABASE-ATOMIC_REQUESTS

``ATOMIC_REQUESTS``
~~~~~~~~~~~~~~~~~~~

Default: ``False``

Set this to ``True`` to wrap each view in a transaction on this database. See
:ref:`tying-transactions-to-http-requests`.

.. setting:: DATABASE-AUTOCOMMIT

``AUTOCOMMIT``
~~~~~~~~~~~~~~

Default: ``True``

Set this to ``False`` if you want to :ref:`disable Django's transaction
management <deactivate-transaction-management>` and implement your own.

.. setting:: DATABASE-ENGINE

``ENGINE``
~~~~~~~~~~

Default: ``''`` (Empty string)

The database backend to use. The built-in database backends are:

* ``'django.db.backends.postgresql'``
* ``'django.db.backends.mysql'``
* ``'django.db.backends.sqlite3'``
* ``'django.db.backends.oracle'``

You can use a database backend that doesn't ship with Django by setting
``ENGINE`` to a fully-qualified path (i.e. ``mypackage.backends.whatever``).

.. versionchanged:: 1.9

    The ``django.db.backends.postgresql`` backend is named
    ``django.db.backends.postgresql_psycopg2`` in older releases. For backwards
    compatibility, the old name still works in newer versions.

.. setting:: HOST

``HOST``
~~~~~~~~

Default: ``''`` (Empty string)

Which host to use when connecting to the database. An empty string means
localhost. Not used with SQLite.

If this value starts with a forward slash (``'/'``) and you're using MySQL,
MySQL will connect via a Unix socket to the specified socket. For example::

    "HOST": '/var/run/mysql'

If you're using MySQL and this value *doesn't* start with a forward slash, then
this value is assumed to be the host.

If you're using PostgreSQL, by default (empty :setting:`HOST`), the connection
to the database is done through UNIX domain sockets ('local' lines in
``pg_hba.conf``). If your UNIX domain socket is not in the standard location,
use the same value of ``unix_socket_directory`` from ``postgresql.conf``.
If you want to connect through TCP sockets, set :setting:`HOST` to 'localhost'
or '127.0.0.1' ('host' lines in ``pg_hba.conf``).
On Windows, you should always define :setting:`HOST`, as UNIX domain sockets
are not available.

.. setting:: NAME

``NAME``
~~~~~~~~

Default: ``''`` (Empty string)

The name of the database to use. For SQLite, it's the full path to the database
file. When specifying the path, always use forward slashes, even on Windows
(e.g. ``C:/homes/user/mysite/sqlite3.db``).

.. setting:: CONN_MAX_AGE

``CONN_MAX_AGE``
~~~~~~~~~~~~~~~~

Default: ``0``

The lifetime of a database connection, in seconds. Use ``0`` to close database
connections at the end of each request — Django's historical behavior — and
``None`` for unlimited persistent connections.

.. setting:: OPTIONS

``OPTIONS``
~~~~~~~~~~~

Default: ``{}`` (Empty dictionary)

Extra parameters to use when connecting to the database. Available parameters
vary depending on your database backend.

Some information on available parameters can be found in the
:doc:`Database Backends </ref/databases>` documentation. For more information,
consult your backend module's own documentation.

.. setting:: PASSWORD

``PASSWORD``
~~~~~~~~~~~~

Default: ``''`` (Empty string)

The password to use when connecting to the database. Not used with SQLite.

.. setting:: PORT

``PORT``
~~~~~~~~

Default: ``''`` (Empty string)

The port to use when connecting to the database. An empty string means the
default port. Not used with SQLite.

.. setting:: DATABASE-TIME_ZONE

``TIME_ZONE``
~~~~~~~~~~~~~

.. versionadded:: 1.9

Default: ``None``

A string representing the time zone for datetimes stored in this database
(assuming that it doesn't support time zones) or ``None``. The same values are
accepted as in the general :setting:`TIME_ZONE` setting.

This allows interacting with third-party databases that store datetimes in
local time rather than UTC. To avoid issues around DST changes, you shouldn't
set this option for databases managed by Django.

Setting this option requires installing pytz_.

When :setting:`USE_TZ` is ``True`` and the database doesn't support time zones
(e.g. SQLite, MySQL, Oracle), Django reads and writes datetimes in local time
according to this option if it is set and in UTC if it isn't.

When :setting:`USE_TZ` is ``True`` and the database supports time zones (e.g.
PostgreSQL), it is an error to set this option.

.. versionchanged:: 1.9

    Before Django 1.9, the PostgreSQL database backend accepted an
    undocumented ``TIME_ZONE`` option, which caused data corruption.

When :setting:`USE_TZ` is ``False``, it is an error to set this option.

.. _pytz: http://pytz.sourceforge.net/

.. setting:: USER

``USER``
~~~~~~~~

Default: ``''`` (Empty string)

The username to use when connecting to the database. Not used with SQLite.

.. setting:: DATABASE-TEST

``TEST``
~~~~~~~~

Default: ``{}`` (Empty dictionary)

A dictionary of settings for test databases; for more details about the
creation and use of test databases, see :ref:`the-test-database`.

Here's an example with a test database configuration::

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'USER': 'mydatabaseuser',
            'NAME': 'mydatabase',
            'TEST': {
                'NAME': 'mytestdatabase',
            },
        },
    }

The following keys in the ``TEST`` dictionary are available:

.. setting:: TEST_CHARSET

``CHARSET``
^^^^^^^^^^^

Default: ``None``

The character set encoding used to create the test database. The value of this
string is passed directly through to the database, so its format is
backend-specific.

Supported by the PostgreSQL_ (``postgresql``) and MySQL_ (``mysql``) backends.

.. _PostgreSQL: http://www.postgresql.org/docs/current/static/multibyte.html
.. _MySQL: https://dev.mysql.com/doc/refman/5.6/en/charset-database.html

.. setting:: TEST_COLLATION

``COLLATION``
^^^^^^^^^^^^^

Default: ``None``

The collation order to use when creating the test database. This value is
passed directly to the backend, so its format is backend-specific.

Only supported for the ``mysql`` backend (see the `MySQL manual`_ for details).

.. _MySQL manual: MySQL_

.. setting:: TEST_DEPENDENCIES

``DEPENDENCIES``
^^^^^^^^^^^^^^^^

Default: ``['default']``, for all databases other than ``default``,
which has no dependencies.

The creation-order dependencies of the database. See the documentation
on :ref:`controlling the creation order of test databases
<topics-testing-creation-dependencies>` for details.

.. setting:: TEST_MIRROR

``MIRROR``
^^^^^^^^^^

Default: ``None``

The alias of the database that this database should mirror during
testing.

This setting exists to allow for testing of primary/replica
(referred to as master/slave by some databases)
configurations of multiple databases. See the documentation on
:ref:`testing primary/replica configurations
<topics-testing-primaryreplica>` for details.

.. setting:: TEST_NAME

``NAME``
^^^^^^^^

Default: ``None``

The name of database to use when running the test suite.

If the default value (``None``) is used with the SQLite database engine, the
tests will use a memory resident database. For all other database engines the
test database will use the name ``'test_' + DATABASE_NAME``.

See :ref:`the-test-database`.

.. setting:: TEST_SERIALIZE

``SERIALIZE``
^^^^^^^^^^^^^

Boolean value to control whether or not the default test runner serializes the
database into an in-memory JSON string before running tests (used to restore
the database state between tests if you don't have transactions). You can set
this to ``False`` to speed up creation time if you don't have any test classes
with :ref:`serialized_rollback=True <test-case-serialized-rollback>`.

.. setting:: TEST_CREATE

``CREATE_DB``
^^^^^^^^^^^^^

Default: ``True``

This is an Oracle-specific setting.

If it is set to ``False``, the test tablespaces won't be automatically created
at the beginning of the tests or dropped at the end.

.. setting:: TEST_USER_CREATE

``CREATE_USER``
^^^^^^^^^^^^^^^

Default: ``True``

This is an Oracle-specific setting.

If it is set to ``False``, the test user won't be automatically created at the
beginning of the tests and dropped at the end.

.. setting:: TEST_USER

``USER``
^^^^^^^^

Default: ``None``

This is an Oracle-specific setting.

The username to use when connecting to the Oracle database that will be used
when running tests. If not provided, Django will use ``'test_' + USER``.

.. setting:: TEST_PASSWD

``PASSWORD``
^^^^^^^^^^^^

Default: ``None``

This is an Oracle-specific setting.

The password to use when connecting to the Oracle database that will be used
when running tests. If not provided, Django will use a hardcoded default value.

.. setting:: TEST_TBLSPACE

``TBLSPACE``
^^^^^^^^^^^^

Default: ``None``

This is an Oracle-specific setting.

The name of the tablespace that will be used when running tests. If not
provided, Django will use ``'test_' + USER``.

.. setting:: TEST_TBLSPACE_TMP

``TBLSPACE_TMP``
^^^^^^^^^^^^^^^^

Default: ``None``

This is an Oracle-specific setting.

The name of the temporary tablespace that will be used when running tests. If
not provided, Django will use ``'test_' + USER + '_temp'``.

.. setting:: DATAFILE

``DATAFILE``
^^^^^^^^^^^^

Default: ``None``

This is an Oracle-specific setting.

The name of the datafile to use for the TBLSPACE. If not provided, Django will
use ``TBLSPACE + '.dbf'``.

.. setting:: DATAFILE_TMP

``DATAFILE_TMP``
^^^^^^^^^^^^^^^^

Default: ``None``

This is an Oracle-specific setting.

The name of the datafile to use for the TBLSPACE_TMP. If not provided, Django
will use ``TBLSPACE_TMP + '.dbf'``.

.. setting:: DATAFILE_MAXSIZE

``DATAFILE_MAXSIZE``
^^^^^^^^^^^^^^^^^^^^

Default: ``'500M'``

This is an Oracle-specific setting.

The maximum size that the DATAFILE is allowed to grow to.

.. setting:: DATAFILE_TMP_MAXSIZE

``DATAFILE_TMP_MAXSIZE``
^^^^^^^^^^^^^^^^^^^^^^^^

Default: ``'500M'``

This is an Oracle-specific setting.

The maximum size that the DATAFILE_TMP is allowed to grow to.

.. setting:: DATA_UPLOAD_MAX_MEMORY_SIZE

DATA_UPLOAD_MAX_MEMORY_SIZE
---------------------------

.. versionadded:: 1.10

Default: ``2621440`` (i.e. 2.5 MB).

The maximum size in bytes that a request body may be before a
:exc:`~django.core.exceptions.SuspiciousOperation` (``RequestDataTooBig``) is
raised. The check is done when accessing ``request.body`` or ``request.POST``
and is calculated against the total request size excluding any file upload
data. You can set this to ``None`` to disable the check. Applications that are
expected to receive unusually large form posts should tune this setting.

The amount of request data is correlated to the amount of memory needed to
process the request and populate the GET and POST dictionaries. Large requests
could be used as a denial-of-service attack vector if left unchecked. Since web
servers don't typically perform deep request inspection, it's not possible to
perform a similar check at that level.

See also :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE`.

.. setting:: DATA_UPLOAD_MAX_NUMBER_FIELDS

DATA_UPLOAD_MAX_NUMBER_FIELDS
-----------------------------

.. versionadded:: 1.10

Default: ``1000``

The maximum number of parameters that may be received via GET or POST before a
:exc:`~django.core.exceptions.SuspiciousOperation` (``TooManyFields``) is
raised. You can set this to ``None`` to disable the check. Applications that
are expected to receive an unusually large number of form fields should tune
this setting.

The number of request parameters is correlated to the amount of time needed to
process the request and populate the GET and POST dictionaries. Large requests
could be used as a denial-of-service attack vector if left unchecked. Since web
servers don't typically perform deep request inspection, it's not possible to
perform a similar check at that level.

.. setting:: DATABASE_ROUTERS

``DATABASE_ROUTERS``
--------------------

Default: ``[]`` (Empty list)

The list of routers that will be used to determine which database
to use when performing a database query.

See the documentation on :ref:`automatic database routing in multi
database configurations <topics-db-multi-db-routing>`.

.. setting:: DATE_FORMAT

``DATE_FORMAT``
---------------

Default: ``'N j, Y'`` (e.g. ``Feb. 4, 2003``)

The default formatting to use for displaying date fields in any part of the
system. Note that if :setting:`USE_L10N` is set to ``True``, then the
locale-dictated format has higher precedence and will be applied instead. See
:tfilter:`allowed date format strings <date>`.

See also :setting:`DATETIME_FORMAT`, :setting:`TIME_FORMAT` and :setting:`SHORT_DATE_FORMAT`.

.. setting:: DATE_INPUT_FORMATS

``DATE_INPUT_FORMATS``
----------------------

Default::

    [
        '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
        '%b %d %Y', '%b %d, %Y',            # 'Oct 25 2006', 'Oct 25, 2006'
        '%d %b %Y', '%d %b, %Y',            # '25 Oct 2006', '25 Oct, 2006'
        '%B %d %Y', '%B %d, %Y',            # 'October 25 2006', 'October 25, 2006'
        '%d %B %Y', '%d %B, %Y',            # '25 October 2006', '25 October, 2006'
    ]

A list of formats that will be accepted when inputting data on a date field.
Formats will be tried in order, using the first valid one. Note that these
format strings use Python's :ref:`datetime module syntax
<strftime-strptime-behavior>`, not the format strings from the :tfilter:`date`
template filter.

When :setting:`USE_L10N` is ``True``, the locale-dictated format has higher
precedence and will be applied instead.

See also :setting:`DATETIME_INPUT_FORMATS` and :setting:`TIME_INPUT_FORMATS`.

.. setting:: DATETIME_FORMAT

``DATETIME_FORMAT``
-------------------

Default: ``'N j, Y, P'`` (e.g. ``Feb. 4, 2003, 4 p.m.``)

The default formatting to use for displaying datetime fields in any part of the
system. Note that if :setting:`USE_L10N` is set to ``True``, then the
locale-dictated format has higher precedence and will be applied instead. See
:tfilter:`allowed date format strings <date>`.

See also :setting:`DATE_FORMAT`, :setting:`TIME_FORMAT` and :setting:`SHORT_DATETIME_FORMAT`.

.. setting:: DATETIME_INPUT_FORMATS

``DATETIME_INPUT_FORMATS``
--------------------------

Default::

    [
        '%Y-%m-%d %H:%M:%S',     # '2006-10-25 14:30:59'
        '%Y-%m-%d %H:%M:%S.%f',  # '2006-10-25 14:30:59.000200'
        '%Y-%m-%d %H:%M',        # '2006-10-25 14:30'
        '%Y-%m-%d',              # '2006-10-25'
        '%m/%d/%Y %H:%M:%S',     # '10/25/2006 14:30:59'
        '%m/%d/%Y %H:%M:%S.%f',  # '10/25/2006 14:30:59.000200'
        '%m/%d/%Y %H:%M',        # '10/25/2006 14:30'
        '%m/%d/%Y',              # '10/25/2006'
        '%m/%d/%y %H:%M:%S',     # '10/25/06 14:30:59'
        '%m/%d/%y %H:%M:%S.%f',  # '10/25/06 14:30:59.000200'
        '%m/%d/%y %H:%M',        # '10/25/06 14:30'
        '%m/%d/%y',              # '10/25/06'
    ]

A list of formats that will be accepted when inputting data on a datetime
field. Formats will be tried in order, using the first valid one. Note that
these format strings use Python's :ref:`datetime module syntax
<strftime-strptime-behavior>`, not the format strings from the :tfilter:`date`
template filter.

When :setting:`USE_L10N` is ``True``, the locale-dictated format has higher
precedence and will be applied instead.

See also :setting:`DATE_INPUT_FORMATS` and :setting:`TIME_INPUT_FORMATS`.

.. setting:: DEBUG

``DEBUG``
---------

Default: ``False``

A boolean that turns on/off debug mode.

Never deploy a site into production with :setting:`DEBUG` turned on.

Did you catch that? NEVER deploy a site into production with :setting:`DEBUG`
turned on.

One of the main features of debug mode is the display of detailed error pages.
If your app raises an exception when :setting:`DEBUG` is ``True``, Django will
display a detailed traceback, including a lot of metadata about your
environment, such as all the currently defined Django settings (from
``settings.py``).

As a security measure, Django will *not* include settings that might be
sensitive, such as :setting:`SECRET_KEY`. Specifically, it will exclude any
setting whose name includes any of the following:

* ``'API'``
* ``'KEY'``
* ``'PASS'``
* ``'SECRET'``
* ``'SIGNATURE'``
* ``'TOKEN'``

Note that these are *partial* matches. ``'PASS'`` will also match PASSWORD,
just as ``'TOKEN'`` will also match TOKENIZED and so on.

Still, note that there are always going to be sections of your debug output
that are inappropriate for public consumption. File paths, configuration
options and the like all give attackers extra information about your server.

It is also important to remember that when running with :setting:`DEBUG`
turned on, Django will remember every SQL query it executes. This is useful
when you're debugging, but it'll rapidly consume memory on a production server.

Finally, if :setting:`DEBUG` is ``False``, you also need to properly set
the :setting:`ALLOWED_HOSTS` setting. Failing to do so will result in all
requests being returned as "Bad Request (400)".

.. note::

    The default :file:`settings.py` file created by :djadmin:`django-admin
    startproject <startproject>` sets ``DEBUG = True`` for convenience.

.. _django/views/debug.py: https://github.com/django/django/blob/master/django/views/debug.py

.. setting:: DEBUG_PROPAGATE_EXCEPTIONS

``DEBUG_PROPAGATE_EXCEPTIONS``
------------------------------

Default: ``False``

If set to True, Django's normal exception handling of view functions
will be suppressed, and exceptions will propagate upwards.  This can
be useful for some test setups, and should never be used on a live
site.

.. setting:: DECIMAL_SEPARATOR

``DECIMAL_SEPARATOR``
---------------------

Default: ``'.'`` (Dot)

Default decimal separator used when formatting decimal numbers.

Note that if :setting:`USE_L10N` is set to ``True``, then the locale-dictated
format has higher precedence and will be applied instead.

See also :setting:`NUMBER_GROUPING`, :setting:`THOUSAND_SEPARATOR` and
:setting:`USE_THOUSAND_SEPARATOR`.


.. setting:: DEFAULT_CHARSET

``DEFAULT_CHARSET``
-------------------

Default: ``'utf-8'``

Default charset to use for all ``HttpResponse`` objects, if a MIME type isn't
manually specified. Used with :setting:`DEFAULT_CONTENT_TYPE` to construct the
``Content-Type`` header.

.. setting:: DEFAULT_CONTENT_TYPE

``DEFAULT_CONTENT_TYPE``
------------------------

Default: ``'text/html'``

Default content type to use for all ``HttpResponse`` objects, if a MIME type
isn't manually specified. Used with :setting:`DEFAULT_CHARSET` to construct
the ``Content-Type`` header.

.. setting:: DEFAULT_EXCEPTION_REPORTER_FILTER

``DEFAULT_EXCEPTION_REPORTER_FILTER``
-------------------------------------

Default: ``'``:class:`django.views.debug.SafeExceptionReporterFilter`\ ``'``

Default exception reporter filter class to be used if none has been assigned to
the :class:`~django.http.HttpRequest` instance yet.
See :ref:`Filtering error reports<filtering-error-reports>`.

.. setting:: DEFAULT_FILE_STORAGE

``DEFAULT_FILE_STORAGE``
------------------------

Default: ``'``:class:`django.core.files.storage.FileSystemStorage`\ ``'``

Default file storage class to be used for any file-related operations that don't
specify a particular storage system. See :doc:`/topics/files`.

.. setting:: DEFAULT_FROM_EMAIL

``DEFAULT_FROM_EMAIL``
----------------------

Default: ``'webmaster@localhost'``

Default email address to use for various automated correspondence from the
site manager(s). This doesn't include error messages sent to :setting:`ADMINS`
and :setting:`MANAGERS`; for that, see :setting:`SERVER_EMAIL`.

.. setting:: DEFAULT_INDEX_TABLESPACE

``DEFAULT_INDEX_TABLESPACE``
----------------------------

Default: ``''`` (Empty string)

Default tablespace to use for indexes on fields that don't specify
one, if the backend supports it (see :doc:`/topics/db/tablespaces`).

.. setting:: DEFAULT_TABLESPACE

``DEFAULT_TABLESPACE``
----------------------

Default: ``''`` (Empty string)

Default tablespace to use for models that don't specify one, if the
backend supports it (see :doc:`/topics/db/tablespaces`).

.. setting:: DISALLOWED_USER_AGENTS

``DISALLOWED_USER_AGENTS``
--------------------------

Default: ``[]`` (Empty list)

List of compiled regular expression objects representing User-Agent strings that
are not allowed to visit any page, systemwide. Use this for bad robots/crawlers.
This is only used if ``CommonMiddleware`` is installed (see
:doc:`/topics/http/middleware`).

.. setting:: EMAIL_BACKEND

``EMAIL_BACKEND``
-----------------

Default: ``'``:class:`django.core.mail.backends.smtp.EmailBackend`\ ``'``

The backend to use for sending emails. For the list of available backends see
:doc:`/topics/email`.

.. setting:: EMAIL_FILE_PATH

``EMAIL_FILE_PATH``
-------------------

Default: Not defined

The directory used by the ``file`` email backend to store output files.

.. setting:: EMAIL_HOST

``EMAIL_HOST``
--------------

Default: ``'localhost'``

The host to use for sending email.

See also :setting:`EMAIL_PORT`.

.. setting:: EMAIL_HOST_PASSWORD

``EMAIL_HOST_PASSWORD``
-----------------------

Default: ``''`` (Empty string)

Password to use for the SMTP server defined in :setting:`EMAIL_HOST`. This
setting is used in conjunction with :setting:`EMAIL_HOST_USER` when
authenticating to the SMTP server. If either of these settings is empty,
Django won't attempt authentication.

See also :setting:`EMAIL_HOST_USER`.

.. setting:: EMAIL_HOST_USER

``EMAIL_HOST_USER``
-------------------

Default: ``''`` (Empty string)

Username to use for the SMTP server defined in :setting:`EMAIL_HOST`.
If empty, Django won't attempt authentication.

See also :setting:`EMAIL_HOST_PASSWORD`.

.. setting:: EMAIL_PORT

``EMAIL_PORT``
--------------

Default: ``25``

Port to use for the SMTP server defined in :setting:`EMAIL_HOST`.

.. setting:: EMAIL_SUBJECT_PREFIX

``EMAIL_SUBJECT_PREFIX``
------------------------

Default: ``'[Django] '``

Subject-line prefix for email messages sent with ``django.core.mail.mail_admins``
or ``django.core.mail.mail_managers``. You'll probably want to include the
trailing space.

.. setting:: EMAIL_USE_TLS

``EMAIL_USE_TLS``
-----------------

Default: ``False``

Whether to use a TLS (secure) connection when talking to the SMTP server.
This is used for explicit TLS connections, generally on port 587. If you are
experiencing hanging connections, see the implicit TLS setting
:setting:`EMAIL_USE_SSL`.

.. setting:: EMAIL_USE_SSL

``EMAIL_USE_SSL``
-----------------

Default: ``False``

Whether to use an implicit TLS (secure) connection when talking to the SMTP
server. In most email documentation this type of TLS connection is referred
to as SSL. It is generally used on port 465. If you are experiencing problems,
see the explicit TLS setting :setting:`EMAIL_USE_TLS`.

Note that :setting:`EMAIL_USE_TLS`/:setting:`EMAIL_USE_SSL` are mutually
exclusive, so only set one of those settings to ``True``.

.. setting:: EMAIL_SSL_CERTFILE

``EMAIL_SSL_CERTFILE``
----------------------

Default: ``None``

If :setting:`EMAIL_USE_SSL` or :setting:`EMAIL_USE_TLS` is ``True``, you can
optionally specify the path to a PEM-formatted certificate chain file to use
for the SSL connection.

.. setting:: EMAIL_SSL_KEYFILE

``EMAIL_SSL_KEYFILE``
---------------------

Default: ``None``

If :setting:`EMAIL_USE_SSL` or :setting:`EMAIL_USE_TLS` is ``True``, you can
optionally specify the path to a PEM-formatted private key file to use for the
SSL connection.

Note that setting :setting:`EMAIL_SSL_CERTFILE` and :setting:`EMAIL_SSL_KEYFILE`
doesn't result in any certificate checking. They're passed to the underlying SSL
connection. Please refer to the documentation of Python's
:func:`python:ssl.wrap_socket` function for details on how the certificate chain
file and private key file are handled.

.. setting:: EMAIL_TIMEOUT

``EMAIL_TIMEOUT``
-----------------

Default: ``None``

Specifies a timeout in seconds for blocking operations like the connection
attempt.

.. setting:: FILE_CHARSET

``FILE_CHARSET``
----------------

Default: ``'utf-8'``

The character encoding used to decode any files read from disk. This includes
template files and initial SQL data files.

.. setting:: FILE_UPLOAD_HANDLERS

``FILE_UPLOAD_HANDLERS``
------------------------

Default::

    [
        'django.core.files.uploadhandler.MemoryFileUploadHandler',
        'django.core.files.uploadhandler.TemporaryFileUploadHandler',
    ]

A list of handlers to use for uploading. Changing this setting allows complete
customization -- even replacement -- of Django's upload process.

See :doc:`/topics/files` for details.

.. setting:: FILE_UPLOAD_MAX_MEMORY_SIZE

``FILE_UPLOAD_MAX_MEMORY_SIZE``
-------------------------------

Default: ``2621440`` (i.e. 2.5 MB).

The maximum size (in bytes) that an upload will be before it gets streamed to
the file system. See :doc:`/topics/files` for details.

See also :setting:`DATA_UPLOAD_MAX_MEMORY_SIZE`.

.. setting:: FILE_UPLOAD_DIRECTORY_PERMISSIONS

``FILE_UPLOAD_DIRECTORY_PERMISSIONS``
-------------------------------------

Default: ``None``

The numeric mode to apply to directories created in the process of uploading
files.

This setting also determines the default permissions for collected static
directories when using the :djadmin:`collectstatic` management command. See
:djadmin:`collectstatic` for details on overriding it.

This value mirrors the functionality and caveats of the
:setting:`FILE_UPLOAD_PERMISSIONS` setting.

.. setting:: FILE_UPLOAD_PERMISSIONS

``FILE_UPLOAD_PERMISSIONS``
---------------------------

Default: ``None``

The numeric mode (i.e. ``0o644``) to set newly uploaded files to. For
more information about what these modes mean, see the documentation for
:func:`os.chmod`.

If this isn't given or is ``None``, you'll get operating-system
dependent behavior. On most platforms, temporary files will have a mode
of ``0o600``, and files saved from memory will be saved using the
system's standard umask.

For security reasons, these permissions aren't applied to the temporary files
that are stored in :setting:`FILE_UPLOAD_TEMP_DIR`.

This setting also determines the default permissions for collected static files
when using the :djadmin:`collectstatic` management command. See
:djadmin:`collectstatic` for details on overriding it.

.. warning::

    **Always prefix the mode with a 0.**

    If you're not familiar with file modes, please note that the leading
    ``0`` is very important: it indicates an octal number, which is the
    way that modes must be specified. If you try to use ``644``, you'll
    get totally incorrect behavior.

.. setting:: FILE_UPLOAD_TEMP_DIR

``FILE_UPLOAD_TEMP_DIR``
------------------------

Default: ``None``

The directory to store data to (typically files larger than
:setting:`FILE_UPLOAD_MAX_MEMORY_SIZE`) temporarily while uploading files.
If ``None``, Django will use the standard temporary directory for the operating
system. For example, this will default to ``/tmp`` on \*nix-style operating
systems.

See :doc:`/topics/files` for details.

.. setting:: FIRST_DAY_OF_WEEK

``FIRST_DAY_OF_WEEK``
---------------------

Default: ``0`` (Sunday)

A number representing the first day of the week. This is especially useful
when displaying a calendar. This value is only used when not using
format internationalization, or when a format cannot be found for the
current locale.

The value must be an integer from 0 to 6, where 0 means Sunday, 1 means
Monday and so on.

.. setting:: FIXTURE_DIRS

``FIXTURE_DIRS``
-----------------

Default: ``[]`` (Empty list)

List of directories searched for fixture files, in addition to the
``fixtures`` directory of each application, in search order.

Note that these paths should use Unix-style forward slashes, even on Windows.

See :ref:`initial-data-via-fixtures` and :ref:`topics-testing-fixtures`.

.. setting:: FORCE_SCRIPT_NAME

``FORCE_SCRIPT_NAME``
---------------------

Default: ``None``

If not ``None``, this will be used as the value of the ``SCRIPT_NAME``
environment variable in any HTTP request. This setting can be used to override
the server-provided value of ``SCRIPT_NAME``, which may be a rewritten version
of the preferred value or not supplied at all. It is also used by
:func:`django.setup()` to set the URL resolver script prefix outside of the
request/response cycle (e.g. in management commands and standalone scripts) to
generate correct URLs when ``SCRIPT_NAME`` is not ``/``.

.. versionchanged:: 1.10

    The setting's use in :func:`django.setup()` was added.

.. setting:: FORMAT_MODULE_PATH

``FORMAT_MODULE_PATH``
----------------------

Default: ``None``

A full Python path to a Python package that contains format definitions for
project locales. If not ``None``, Django will check for a ``formats.py``
file, under the directory named as the current locale, and will use the
formats defined in this file.

For example, if :setting:`FORMAT_MODULE_PATH` is set to ``mysite.formats``,
and current language is ``en`` (English), Django will expect a directory tree
like::

    mysite/
        formats/
            __init__.py
            en/
                __init__.py
                formats.py

You can also set this setting to a list of Python paths, for example::

    FORMAT_MODULE_PATH = [
        'mysite.formats',
        'some_app.formats',
    ]

When Django searches for a certain format, it will go through all given Python
paths until it finds a module that actually defines the given format. This
means that formats defined in packages farther up in the list will take
precedence over the same formats in packages farther down.

Available formats are :setting:`DATE_FORMAT`, :setting:`TIME_FORMAT`,
:setting:`DATETIME_FORMAT`, :setting:`YEAR_MONTH_FORMAT`,
:setting:`MONTH_DAY_FORMAT`, :setting:`SHORT_DATE_FORMAT`,
:setting:`SHORT_DATETIME_FORMAT`, :setting:`FIRST_DAY_OF_WEEK`,
:setting:`DECIMAL_SEPARATOR`, :setting:`THOUSAND_SEPARATOR` and
:setting:`NUMBER_GROUPING`.

.. setting:: IGNORABLE_404_URLS

``IGNORABLE_404_URLS``
----------------------

Default: ``[]`` (Empty list)

List of compiled regular expression objects describing URLs that should be
ignored when reporting HTTP 404 errors via email (see
:doc:`/howto/error-reporting`). Regular expressions are matched against
:meth:`request's full paths <django.http.HttpRequest.get_full_path>` (including
query string, if any). Use this if your site does not provide a commonly
requested file such as ``favicon.ico`` or ``robots.txt``, or if it gets
hammered by script kiddies.

This is only used if
:class:`~django.middleware.common.BrokenLinkEmailsMiddleware` is enabled (see
:doc:`/topics/http/middleware`).

.. setting:: INSTALLED_APPS

``INSTALLED_APPS``
------------------

Default: ``[]`` (Empty list)

A list of strings designating all applications that are enabled in this
Django installation. Each string should be a dotted Python path to:

* an application configuration class (preferred), or
* a package containing an application.

:doc:`Learn more about application configurations </ref/applications>`.

.. admonition:: Use the application registry for introspection

    Your code should never access :setting:`INSTALLED_APPS` directly. Use
    :attr:`django.apps.apps` instead.

.. admonition:: Application names and labels must be unique in
                :setting:`INSTALLED_APPS`

    Application :attr:`names <django.apps.AppConfig.name>` — the dotted Python
    path to the application package — must be unique. There is no way to
    include the same application twice, short of duplicating its code under
    another name.

    Application :attr:`labels <django.apps.AppConfig.label>` — by default the
    final part of the name — must be unique too. For example, you can't
    include both ``django.contrib.auth`` and ``myproject.auth``. However, you
    can relabel an application with a custom configuration that defines a
    different :attr:`~django.apps.AppConfig.label`.

    These rules apply regardless of whether :setting:`INSTALLED_APPS`
    references application configuration classes or application packages.

When several applications provide different versions of the same resource
(template, static file, management command, translation), the application
listed first in :setting:`INSTALLED_APPS` has precedence.

.. setting:: INTERNAL_IPS

``INTERNAL_IPS``
----------------

Default: ``[]`` (Empty list)

A list of IP addresses, as strings, that:

* Allow the :func:`~django.template.context_processors.debug` context processor
  to add some variables to the template context.
* Can use the :ref:`admindocs bookmarklets <admindocs-bookmarklets>` even if
  not logged in as a staff user.
* Are marked as "internal" (as opposed to "EXTERNAL") in
  :class:`~django.utils.log.AdminEmailHandler` emails.

.. setting:: LANGUAGE_CODE

``LANGUAGE_CODE``
-----------------

Default: ``'en-us'``

A string representing the language code for this installation. This should be in
standard :term:`language ID format <language code>`. For example, U.S. English
is ``"en-us"``. See also the `list of language identifiers`_ and
:doc:`/topics/i18n/index`.

:setting:`USE_I18N` must be active for this setting to have any effect.

It serves two purposes:

* If the locale middleware isn't in use, it decides which translation is served
  to all users.
* If the locale middleware is active, it provides a fallback language in case the
  user's preferred language can't be determined or is not supported by the
  website. It also provides the fallback translation when a translation for a
  given literal doesn't exist for the user's preferred language.

See :ref:`how-django-discovers-language-preference` for more details.

.. _list of language identifiers: http://www.i18nguy.com/unicode/language-identifiers.html

.. setting:: LANGUAGE_COOKIE_AGE

``LANGUAGE_COOKIE_AGE``
-----------------------

Default: ``None`` (expires at browser close)

The age of the language cookie, in seconds.

.. setting:: LANGUAGE_COOKIE_DOMAIN

``LANGUAGE_COOKIE_DOMAIN``
--------------------------

Default: ``None``

The domain to use for the language cookie. Set this to a string such as
``".example.com"`` (note the leading dot!) for cross-domain cookies, or use
``None`` for a standard domain cookie.

Be cautious when updating this setting on a production site. If you update
this setting to enable cross-domain cookies on a site that previously used
standard domain cookies, existing user cookies that have the old domain
will not be updated. This will result in site users being unable to switch
the language as long as these cookies persist. The only safe and reliable
option to perform the switch is to change the language cookie name
permanently (via the :setting:`LANGUAGE_COOKIE_NAME` setting) and to add
a middleware that copies the value from the old cookie to a new one and then
deletes the old one.

.. setting:: LANGUAGE_COOKIE_NAME

``LANGUAGE_COOKIE_NAME``
------------------------

Default: ``'django_language'``

The name of the cookie to use for the language cookie. This can be whatever
you want (as long as it's different from the other cookie names in your
application). See :doc:`/topics/i18n/index`.

.. setting:: LANGUAGE_COOKIE_PATH

``LANGUAGE_COOKIE_PATH``
------------------------

Default: ``'/'``

The path set on the language cookie. This should either match the URL path of your
Django installation or be a parent of that path.

This is useful if you have multiple Django instances running under the same
hostname. They can use different cookie paths and each instance will only see
its own language cookie.

Be cautious when updating this setting on a production site. If you update this
setting to use a deeper path than it previously used, existing user cookies that
have the old path will not be updated. This will result in site users being
unable to switch the language as long as these cookies persist. The only safe
and reliable option to perform the switch is to change the language cookie name
permanently (via the :setting:`LANGUAGE_COOKIE_NAME` setting), and to add
a middleware that copies the value from the old cookie to a new one and then
deletes the one.

.. setting:: LANGUAGES

``LANGUAGES``
-------------

Default: A list of all available languages. This list is continually growing
and including a copy here would inevitably become rapidly out of date. You can
see the current list of translated languages by looking in
``django/conf/global_settings.py`` (or view the `online source`_).

.. _online source: https://github.com/django/django/blob/master/django/conf/global_settings.py

The list is a list of two-tuples in the format
(:term:`language code<language code>`, ``language name``) -- for example,
``('ja', 'Japanese')``.
This specifies which languages are available for language selection. See
:doc:`/topics/i18n/index`.

Generally, the default value should suffice. Only set this setting if you want
to restrict language selection to a subset of the Django-provided languages.

If you define a custom :setting:`LANGUAGES` setting, you can mark the
language names as translation strings using the
:func:`~django.utils.translation.ugettext_lazy` function.

Here's a sample settings file::

    from django.utils.translation import ugettext_lazy as _

    LANGUAGES = [
        ('de', _('German')),
        ('en', _('English')),
    ]

.. setting:: LOCALE_PATHS

``LOCALE_PATHS``
----------------

Default: ``[]`` (Empty list)

A list of directories where Django looks for translation files.
See :ref:`how-django-discovers-translations`.

Example::

    LOCALE_PATHS = [
        '/home/www/project/common_files/locale',
        '/var/local/translations/locale',
    ]

Django will look within each of these paths for the ``<locale_code>/LC_MESSAGES``
directories containing the actual translation files.

.. setting:: LOGGING

``LOGGING``
-----------

Default: A logging configuration dictionary.

A data structure containing configuration information. The contents of
this data structure will be passed as the argument to the
configuration method described in :setting:`LOGGING_CONFIG`.

Among other things, the default logging configuration passes HTTP 500 server
errors to an email log handler when :setting:`DEBUG` is ``False``. See also
:ref:`configuring-logging`.

You can see the default logging configuration by looking in
``django/utils/log.py`` (or view the `online source`__).

__ https://github.com/django/django/blob/master/django/utils/log.py

.. setting:: LOGGING_CONFIG

``LOGGING_CONFIG``
------------------

Default: ``'logging.config.dictConfig'``

A path to a callable that will be used to configure logging in the
Django project. Points at a instance of Python's :ref:`dictConfig
<logging-config-dictschema>` configuration method by default.

If you set :setting:`LOGGING_CONFIG` to ``None``, the logging
configuration process will be skipped.

.. setting:: MANAGERS

``MANAGERS``
------------

Default: ``[]`` (Empty list)

A list in the same format as :setting:`ADMINS` that specifies who should get
broken link notifications when
:class:`~django.middleware.common.BrokenLinkEmailsMiddleware` is enabled.

.. setting:: MEDIA_ROOT

``MEDIA_ROOT``
--------------

Default: ``''`` (Empty string)

Absolute filesystem path to the directory that will hold :doc:`user-uploaded
files </topics/files>`.

Example: ``"/var/www/example.com/media/"``

See also :setting:`MEDIA_URL`.

.. warning::

    :setting:`MEDIA_ROOT` and :setting:`STATIC_ROOT` must have different
    values. Before :setting:`STATIC_ROOT` was introduced, it was common to
    rely or fallback on :setting:`MEDIA_ROOT` to also serve static files;
    however, since this can have serious security implications, there is a
    validation check to prevent it.

.. setting:: MEDIA_URL

``MEDIA_URL``
-------------

Default: ``''`` (Empty string)

URL that handles the media served from :setting:`MEDIA_ROOT`, used
for :doc:`managing stored files </topics/files>`. It must end in a slash if set
to a non-empty value. You will need to :ref:`configure these files to be served
<serving-uploaded-files-in-development>` in both development and production
environments.

If you want to use ``{{ MEDIA_URL }}`` in your templates, add
``'django.template.context_processors.media'`` in the ``'context_processors'``
option of :setting:`TEMPLATES`.

Example: ``"http://media.example.com/"``

.. warning::

    There are security risks if you are accepting uploaded content from
    untrusted users! See the security guide's topic on
    :ref:`user-uploaded-content-security` for mitigation details.

.. warning::

    :setting:`MEDIA_URL` and :setting:`STATIC_URL` must have different
    values. See :setting:`MEDIA_ROOT` for more details.

.. setting:: MIDDLEWARE

``MIDDLEWARE``
--------------

.. versionadded:: 1.10

Default:: ``None``

A list of middleware to use. See :doc:`/topics/http/middleware`.

.. setting:: MIDDLEWARE_CLASSES

``MIDDLEWARE_CLASSES``
----------------------

.. deprecated:: 1.10

    Old-style middleware that uses  ``settings.MIDDLEWARE_CLASSES`` are
    deprecated. :ref:`Adapt old, custom middleware <upgrading-middleware>` and
    use the :setting:`MIDDLEWARE` setting.

Default::

    [
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
    ]

A list of middleware classes to use. This was the default setting used in
Django 1.9 and earlier. Django 1.10 introduced a new style of middleware. If
you have an older project using this setting you should :ref:`update any
middleware you've written yourself <upgrading-middleware>` to the new style
and then use the :setting:`MIDDLEWARE` setting.

.. setting:: MIGRATION_MODULES

``MIGRATION_MODULES``
---------------------

Default: ``{}`` (Empty dictionary)

A dictionary specifying the package where migration modules can be found on a
per-app basis. The default value of this setting is an empty dictionary, but
the default package name for migration modules is ``migrations``.

Example::

    {'blog': 'blog.db_migrations'}

In this case, migrations pertaining to the ``blog`` app will be contained in
the ``blog.db_migrations`` package.

If you provide the ``app_label`` argument, :djadmin:`makemigrations` will
automatically create the package if it doesn't already exist.

.. versionadded:: 1.9

When you supply ``None`` as a value for an app, Django will consider the app as
an app without migrations regardless of an existing ``migrations`` submodule.
This can be used, for example, in a test settings file to skip migrations while
testing (tables will still be created for the apps' models). If this is used in
your general project settings, remember to use the :option:`migrate
--run-syncdb` option if you want to create tables for the app.

.. setting:: MONTH_DAY_FORMAT

``MONTH_DAY_FORMAT``
--------------------

Default: ``'F j'``

The default formatting to use for date fields on Django admin change-list
pages -- and, possibly, by other parts of the system -- in cases when only the
month and day are displayed.

For example, when a Django admin change-list page is being filtered by a date
drilldown, the header for a given day displays the day and month. Different
locales have different formats. For example, U.S. English would say
"January 1," whereas Spanish might say "1 Enero."

Note that if :setting:`USE_L10N` is set to ``True``, then the corresponding
locale-dictated format has higher precedence and will be applied.

See :tfilter:`allowed date format strings <date>`. See also
:setting:`DATE_FORMAT`, :setting:`DATETIME_FORMAT`,
:setting:`TIME_FORMAT` and :setting:`YEAR_MONTH_FORMAT`.

.. setting:: NUMBER_GROUPING

``NUMBER_GROUPING``
--------------------

Default: ``0``

Number of digits grouped together on the integer part of a number.

Common use is to display a thousand separator. If this setting is ``0``, then
no grouping will be applied to the number. If this setting is greater than
``0``, then :setting:`THOUSAND_SEPARATOR` will be used as the separator between
those groups.

Note that if :setting:`USE_L10N` is set to ``True``, then the locale-dictated
format has higher precedence and will be applied instead.

See also :setting:`DECIMAL_SEPARATOR`, :setting:`THOUSAND_SEPARATOR` and
:setting:`USE_THOUSAND_SEPARATOR`.

.. setting:: PREPEND_WWW

``PREPEND_WWW``
---------------

Default: ``False``

Whether to prepend the "www." subdomain to URLs that don't have it. This is only
used if :class:`~django.middleware.common.CommonMiddleware` is installed
(see :doc:`/topics/http/middleware`). See also :setting:`APPEND_SLASH`.

.. setting:: ROOT_URLCONF

``ROOT_URLCONF``
----------------

Default: Not defined

A string representing the full Python import path to your root URLconf. For example:
``"mydjangoapps.urls"``. Can be overridden on a per-request basis by
setting the attribute ``urlconf`` on the incoming ``HttpRequest``
object. See :ref:`how-django-processes-a-request` for details.

.. setting:: SECRET_KEY

``SECRET_KEY``
--------------

Default: ``''`` (Empty string)

A secret key for a particular Django installation. This is used to provide
:doc:`cryptographic signing </topics/signing>`, and should be set to a unique,
unpredictable value.

:djadmin:`django-admin startproject <startproject>` automatically adds a
randomly-generated ``SECRET_KEY`` to each new project.

Django will refuse to start if :setting:`SECRET_KEY` is not set.

.. warning::

    **Keep this value secret.**

    Running Django with a known :setting:`SECRET_KEY` defeats many of Django's
    security protections, and can lead to privilege escalation and remote code
    execution vulnerabilities.

The secret key is used for:

* All :doc:`sessions </topics/http/sessions>` if you are using
  any other session backend than ``django.contrib.sessions.backends.cache``,
  or are using the default
  :meth:`~django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash()`.
* All :doc:`messages </ref/contrib/messages>` if you are using
  :class:`~django.contrib.messages.storage.cookie.CookieStorage` or
  :class:`~django.contrib.messages.storage.fallback.FallbackStorage`.
* All :func:`~django.contrib.auth.views.password_reset` tokens.
* Any usage of :doc:`cryptographic signing </topics/signing>`, unless a
  different key is provided.

If you rotate your secret key, all of the above will be invalidated.
Secret keys are not used for passwords of users and key rotation will not
affect them.

.. note::

    The default :file:`settings.py` file created by :djadmin:`django-admin
    startproject <startproject>` creates a unique ``SECRET_KEY`` for
    convenience.

.. setting:: SECURE_BROWSER_XSS_FILTER

``SECURE_BROWSER_XSS_FILTER``
-----------------------------

Default: ``False``

If ``True``, the :class:`~django.middleware.security.SecurityMiddleware` sets
the :ref:`x-xss-protection` header on all responses that do not already have it.

.. setting:: SECURE_CONTENT_TYPE_NOSNIFF

``SECURE_CONTENT_TYPE_NOSNIFF``
-------------------------------

Default: ``False``

If ``True``, the :class:`~django.middleware.security.SecurityMiddleware`
sets the :ref:`x-content-type-options` header on all responses that do not
already have it.

.. setting:: SECURE_HSTS_INCLUDE_SUBDOMAINS

``SECURE_HSTS_INCLUDE_SUBDOMAINS``
----------------------------------

Default: ``False``

If ``True``, the :class:`~django.middleware.security.SecurityMiddleware` adds
the ``includeSubDomains`` directive to the :ref:`http-strict-transport-security`
header. It has no effect unless :setting:`SECURE_HSTS_SECONDS` is set to a
non-zero value.

.. warning::
    Setting this incorrectly can irreversibly (for the value of
    :setting:`SECURE_HSTS_SECONDS`) break your site. Read the
    :ref:`http-strict-transport-security` documentation first.

.. setting:: SECURE_HSTS_SECONDS

``SECURE_HSTS_SECONDS``
-----------------------

Default: ``0``

If set to a non-zero integer value, the
:class:`~django.middleware.security.SecurityMiddleware` sets the
:ref:`http-strict-transport-security` header on all responses that do not
already have it.

.. warning::
    Setting this incorrectly can irreversibly (for some time) break your site.
    Read the :ref:`http-strict-transport-security` documentation first.

.. setting:: SECURE_PROXY_SSL_HEADER

``SECURE_PROXY_SSL_HEADER``
---------------------------

Default: ``None``

A tuple representing a HTTP header/value combination that signifies a request
is secure. This controls the behavior of the request object's ``is_secure()``
method.

This takes some explanation. By default, ``is_secure()`` is able to determine
whether a request is secure by looking at whether the requested URL uses
"https://". This is important for Django's CSRF protection, and may be used
by your own code or third-party apps.

If your Django app is behind a proxy, though, the proxy may be "swallowing" the
fact that a request is HTTPS, using a non-HTTPS connection between the proxy
and Django. In this case, ``is_secure()`` would always return ``False`` -- even
for requests that were made via HTTPS by the end user.

In this situation, you'll want to configure your proxy to set a custom HTTP
header that tells Django whether the request came in via HTTPS, and you'll want
to set ``SECURE_PROXY_SSL_HEADER`` so that Django knows what header to look
for.

You'll need to set a tuple with two elements -- the name of the header to look
for and the required value. For example::

    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

Here, we're telling Django that we trust the ``X-Forwarded-Proto`` header
that comes from our proxy, and any time its value is ``'https'``, then the
request is guaranteed to be secure (i.e., it originally came in via HTTPS).
Obviously, you should *only* set this setting if you control your proxy or
have some other guarantee that it sets/strips this header appropriately.

Note that the header needs to be in the format as used by ``request.META`` --
all caps and likely starting with ``HTTP_``. (Remember, Django automatically
adds ``'HTTP_'`` to the start of x-header names before making the header
available in ``request.META``.)

.. warning::

    **You will probably open security holes in your site if you set this
    without knowing what you're doing. And if you fail to set it when you
    should. Seriously.**

    Make sure ALL of the following are true before setting this (assuming the
    values from the example above):

    * Your Django app is behind a proxy.
    * Your proxy strips the ``X-Forwarded-Proto`` header from all incoming
      requests. In other words, if end users include that header in their
      requests, the proxy will discard it.
    * Your proxy sets the ``X-Forwarded-Proto`` header and sends it to Django,
      but only for requests that originally come in via HTTPS.

    If any of those are not true, you should keep this setting set to ``None``
    and find another way of determining HTTPS, perhaps via custom middleware.

.. setting:: SECURE_REDIRECT_EXEMPT

``SECURE_REDIRECT_EXEMPT``
--------------------------

Default: ``[]`` (Empty list)

If a URL path matches a regular expression in this list, the request will not be
redirected to HTTPS. If :setting:`SECURE_SSL_REDIRECT` is ``False``, this
setting has no effect.

.. setting:: SECURE_SSL_HOST

``SECURE_SSL_HOST``
-------------------

Default: ``None``

If a string (e.g. ``secure.example.com``), all SSL redirects will be directed
to this host rather than the originally-requested host
(e.g. ``www.example.com``). If :setting:`SECURE_SSL_REDIRECT` is ``False``, this
setting has no effect.

.. setting:: SECURE_SSL_REDIRECT

``SECURE_SSL_REDIRECT``
-----------------------

Default: ``False``

If ``True``, the :class:`~django.middleware.security.SecurityMiddleware`
:ref:`redirects <ssl-redirect>` all non-HTTPS requests to HTTPS (except for
those URLs matching a regular expression listed in
:setting:`SECURE_REDIRECT_EXEMPT`).

.. note::

   If turning this to ``True`` causes infinite redirects, it probably means
   your site is running behind a proxy and can't tell which requests are secure
   and which are not. Your proxy likely sets a header to indicate secure
   requests; you can correct the problem by finding out what that header is and
   configuring the :setting:`SECURE_PROXY_SSL_HEADER` setting accordingly.

.. setting:: SERIALIZATION_MODULES

``SERIALIZATION_MODULES``
-------------------------

Default: Not defined

A dictionary of modules containing serializer definitions (provided as
strings), keyed by a string identifier for that serialization type. For
example, to define a YAML serializer, use::

    SERIALIZATION_MODULES = {'yaml': 'path.to.yaml_serializer'}

.. setting:: SERVER_EMAIL

``SERVER_EMAIL``
----------------

Default: ``'root@localhost'``

The email address that error messages come from, such as those sent to
:setting:`ADMINS` and :setting:`MANAGERS`.

.. admonition:: Why are my emails sent from a different address?

    This address is used only for error messages. It is *not* the address that
    regular email messages sent with :meth:`~django.core.mail.send_mail()`
    come from; for that, see :setting:`DEFAULT_FROM_EMAIL`.

.. setting:: SHORT_DATE_FORMAT

``SHORT_DATE_FORMAT``
---------------------

Default: ``'m/d/Y'`` (e.g. ``12/31/2003``)

An available formatting that can be used for displaying date fields on
templates. Note that if :setting:`USE_L10N` is set to ``True``, then the
corresponding locale-dictated format has higher precedence and will be applied.
See :tfilter:`allowed date format strings <date>`.

See also :setting:`DATE_FORMAT` and :setting:`SHORT_DATETIME_FORMAT`.

.. setting:: SHORT_DATETIME_FORMAT

``SHORT_DATETIME_FORMAT``
-------------------------

Default: ``'m/d/Y P'`` (e.g. ``12/31/2003 4 p.m.``)

An available formatting that can be used for displaying datetime fields on
templates. Note that if :setting:`USE_L10N` is set to ``True``, then the
corresponding locale-dictated format has higher precedence and will be applied.
See :tfilter:`allowed date format strings <date>`.

See also :setting:`DATE_FORMAT` and :setting:`SHORT_DATE_FORMAT`.

.. setting:: SIGNING_BACKEND

``SIGNING_BACKEND``
-------------------

Default: ``'django.core.signing.TimestampSigner'``

The backend used for signing cookies and other data.

See also the :doc:`/topics/signing` documentation.

.. setting:: SILENCED_SYSTEM_CHECKS

``SILENCED_SYSTEM_CHECKS``
--------------------------

Default: ``[]`` (Empty list)

A list of identifiers of messages generated by the system check framework
(i.e. ``["models.W001"]``) that you wish to permanently acknowledge and ignore.
Silenced checks will not be output to the console.

.. versionchanged:: 1.9

    In older versions, silenced messages of ``ERROR`` level or higher were
    printed to the console.

See also the :doc:`/ref/checks` documentation.

.. setting:: TEMPLATES

``TEMPLATES``
-------------

Default: ``[]`` (Empty list)

A list containing the settings for all template engines to be used with
Django. Each item of the list is a dictionary containing the options for an
individual engine.

Here's a simple setup that tells the Django template engine to load templates
from the ``templates`` subdirectory inside each installed application::

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'APP_DIRS': True,
        },
    ]

The following options are available for all backends.

.. setting:: TEMPLATES-BACKEND

``BACKEND``
~~~~~~~~~~~

Default: Not defined

The template backend to use. The built-in template backends are:

* ``'django.template.backends.django.DjangoTemplates'``
* ``'django.template.backends.jinja2.Jinja2'``

You can use a template backend that doesn't ship with Django by setting
``BACKEND`` to a fully-qualified path (i.e. ``'mypackage.whatever.Backend'``).

.. setting:: TEMPLATES-NAME

``NAME``
~~~~~~~~

Default: see below

The alias for this particular template engine. It's an identifier that allows
selecting an engine for rendering. Aliases must be unique across all
configured template engines.

It defaults to the name of the module defining the engine class, i.e. the
next to last piece of :setting:`BACKEND <TEMPLATES-BACKEND>`, when it isn't
provided. For example if the backend is ``'mypackage.whatever.Backend'`` then
its default name is ``'whatever'``.

.. setting:: TEMPLATES-DIRS

``DIRS``
~~~~~~~~

Default: ``[]`` (Empty list)

Directories where the engine should look for template source files, in search
order.

.. setting:: TEMPLATES-APP_DIRS

``APP_DIRS``
~~~~~~~~~~~~

Default: ``False``

Whether the engine should look for template source files inside installed
applications.

.. note::

    The default :file:`settings.py` file created by :djadmin:`django-admin
    startproject <startproject>` sets ``'APP_DIRS': True``.

.. setting:: TEMPLATES-OPTIONS

``OPTIONS``
~~~~~~~~~~~

Default: ``{}`` (Empty dict)

Extra parameters to pass to the template backend. Available parameters vary
depending on the template backend. See
:class:`~django.template.backends.django.DjangoTemplates` and
:class:`~django.template.backends.jinja2.Jinja2` for the options of the
built-in backends.

.. setting:: TEST_RUNNER

``TEST_RUNNER``
---------------

Default: ``'django.test.runner.DiscoverRunner'``

The name of the class to use for starting the test suite. See
:ref:`other-testing-frameworks`.

.. setting:: TEST_NON_SERIALIZED_APPS

``TEST_NON_SERIALIZED_APPS``
----------------------------

Default: ``[]`` (Empty list)

In order to restore the database state between tests for
``TransactionTestCase``\s and database backends without transactions, Django
will :ref:`serialize the contents of all apps <test-case-serialized-rollback>`
when it starts the test run so it can then reload from that copy before running
tests that need it.

This slows down the startup time of the test runner; if you have apps that
you know don't need this feature, you can add their full names in here (e.g.
``'django.contrib.contenttypes'``) to exclude them from this serialization
process.

.. setting:: THOUSAND_SEPARATOR

``THOUSAND_SEPARATOR``
----------------------

Default: ``','`` (Comma)

Default thousand separator used when formatting numbers. This setting is
used only when :setting:`USE_THOUSAND_SEPARATOR` is ``True`` and
:setting:`NUMBER_GROUPING` is greater than ``0``.

Note that if :setting:`USE_L10N` is set to ``True``, then the locale-dictated
format has higher precedence and will be applied instead.

See also :setting:`NUMBER_GROUPING`, :setting:`DECIMAL_SEPARATOR` and
:setting:`USE_THOUSAND_SEPARATOR`.

.. setting:: TIME_FORMAT

``TIME_FORMAT``
---------------

Default: ``'P'`` (e.g. ``4 p.m.``)

The default formatting to use for displaying time fields in any part of the
system. Note that if :setting:`USE_L10N` is set to ``True``, then the
locale-dictated format has higher precedence and will be applied instead. See
:tfilter:`allowed date format strings <date>`.

See also :setting:`DATE_FORMAT` and :setting:`DATETIME_FORMAT`.

.. setting:: TIME_INPUT_FORMATS

``TIME_INPUT_FORMATS``
----------------------

Default::

    [
        '%H:%M:%S',     # '14:30:59'
        '%H:%M:%S.%f',  # '14:30:59.000200'
        '%H:%M',        # '14:30'
    ]

A list of formats that will be accepted when inputting data on a time field.
Formats will be tried in order, using the first valid one. Note that these
format strings use Python's :ref:`datetime module syntax
<strftime-strptime-behavior>`, not the format strings from the :tfilter:`date`
template filter.

When :setting:`USE_L10N` is ``True``, the locale-dictated format has higher
precedence and will be applied instead.

See also :setting:`DATE_INPUT_FORMATS` and :setting:`DATETIME_INPUT_FORMATS`.

.. setting:: TIME_ZONE

``TIME_ZONE``
-------------

Default: ``'America/Chicago'``

A string representing the time zone for this installation, or ``None``. See
the `list of time zones`_.

.. note::
    Since Django was first released with the :setting:`TIME_ZONE` set to
    ``'America/Chicago'``, the global setting (used if nothing is defined in
    your project's ``settings.py``) remains ``'America/Chicago'`` for backwards
    compatibility. New project templates default to ``'UTC'``.

Note that this isn't necessarily the time zone of the server. For example, one
server may serve multiple Django-powered sites, each with a separate time zone
setting.

When :setting:`USE_TZ` is ``False``, this is the time zone in which Django
will store all datetimes. When :setting:`USE_TZ` is ``True``, this is the
default time zone that Django will use to display datetimes in templates and
to interpret datetimes entered in forms.

Django sets the ``os.environ['TZ']`` variable to the time zone you specify in
the :setting:`TIME_ZONE` setting. Thus, all your views and models will
automatically operate in this time zone. However, Django won't set the ``TZ``
environment variable under the following conditions:

* If you're using the manual configuration option as described in
  :ref:`manually configuring settings
  <settings-without-django-settings-module>`, or

* If you specify ``TIME_ZONE = None``. This will cause Django to fall back to
  using the system timezone. However, this is discouraged when :setting:`USE_TZ
  = True <USE_TZ>`, because it makes conversions between local time and UTC
  less reliable.

If Django doesn't set the ``TZ`` environment variable, it's up to you
to ensure your processes are running in the correct environment.

.. note::
    Django cannot reliably use alternate time zones in a Windows environment.
    If you're running Django on Windows, :setting:`TIME_ZONE` must be set to
    match the system time zone.

.. _list of time zones: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

.. setting:: USE_ETAGS

``USE_ETAGS``
-------------

Default: ``False``

A boolean that specifies whether to output the "Etag" header. This saves
bandwidth but slows down performance. This is used by the ``CommonMiddleware``
(see :doc:`/topics/http/middleware`) and in the``Cache Framework``
(see :doc:`/topics/cache`).

.. setting:: USE_I18N

``USE_I18N``
------------

Default: ``True``

A boolean that specifies whether Django's translation system should be enabled.
This provides an easy way to turn it off, for performance. If this is set to
``False``, Django will make some optimizations so as not to load the
translation machinery.

See also :setting:`LANGUAGE_CODE`, :setting:`USE_L10N` and :setting:`USE_TZ`.

.. note::

    The default :file:`settings.py` file created by :djadmin:`django-admin
    startproject <startproject>` includes ``USE_I18N = True`` for convenience.

.. setting:: USE_L10N

``USE_L10N``
------------

Default: ``False``

A boolean that specifies if localized formatting of data will be enabled by
default or not. If this is set to ``True``, e.g. Django will display numbers and
dates using the format of the current locale.

See also :setting:`LANGUAGE_CODE`, :setting:`USE_I18N` and :setting:`USE_TZ`.

.. note::

    The default :file:`settings.py` file created by :djadmin:`django-admin
    startproject <startproject>` includes ``USE_L10N = True`` for convenience.

.. setting:: USE_THOUSAND_SEPARATOR

``USE_THOUSAND_SEPARATOR``
--------------------------

Default: ``False``

A boolean that specifies whether to display numbers using a thousand separator.
When :setting:`USE_L10N` is set to ``True`` and if this is also set to
``True``, Django will use the values of :setting:`THOUSAND_SEPARATOR` and
:setting:`NUMBER_GROUPING` to format numbers unless the locale already has an
existing thousands separator. If there is a thousands separator in the locale
format, it will have higher precedence and will be applied instead.

See also :setting:`DECIMAL_SEPARATOR`, :setting:`NUMBER_GROUPING` and
:setting:`THOUSAND_SEPARATOR`.

.. setting:: USE_TZ

``USE_TZ``
----------

Default: ``False``

A boolean that specifies if datetimes will be timezone-aware by default or not.
If this is set to ``True``, Django will use timezone-aware datetimes internally.
Otherwise, Django will use naive datetimes in local time.

See also :setting:`TIME_ZONE`, :setting:`USE_I18N` and :setting:`USE_L10N`.

.. note::

    The default :file:`settings.py` file created by
    :djadmin:`django-admin startproject <startproject>` includes
    ``USE_TZ = True`` for convenience.

.. setting:: USE_X_FORWARDED_HOST

``USE_X_FORWARDED_HOST``
------------------------

Default: ``False``

A boolean that specifies whether to use the ``X-Forwarded-Host`` header in
preference to the ``Host`` header. This should only be enabled if a proxy
which sets this header is in use.

This setting takes priority over :setting:`USE_X_FORWARDED_PORT`. Per
:rfc:`7239#page-7`, the ``X-Forwarded-Host`` header can include the port
number, in which case you shouldn't use :setting:`USE_X_FORWARDED_PORT`.

.. setting:: USE_X_FORWARDED_PORT

``USE_X_FORWARDED_PORT``
------------------------

.. versionadded:: 1.9

Default: ``False``

A boolean that specifies whether to use the ``X-Forwarded-Port`` header in
preference to the ``SERVER_PORT`` ``META`` variable. This should only be
enabled if a proxy which sets this header is in use.

:setting:`USE_X_FORWARDED_HOST` takes priority over this setting.

.. setting:: WSGI_APPLICATION

``WSGI_APPLICATION``
--------------------

Default: ``None``

The full Python path of the WSGI application object that Django's built-in
servers (e.g. :djadmin:`runserver`) will use. The :djadmin:`django-admin
startproject <startproject>` management command will create a simple
``wsgi.py`` file with an ``application`` callable in it, and point this setting
to that ``application``.

If not set, the return value of ``django.core.wsgi.get_wsgi_application()``
will be used. In this case, the behavior of :djadmin:`runserver` will be
identical to previous Django versions.

.. setting:: YEAR_MONTH_FORMAT

``YEAR_MONTH_FORMAT``
---------------------

Default: ``'F Y'``

The default formatting to use for date fields on Django admin change-list
pages -- and, possibly, by other parts of the system -- in cases when only the
year and month are displayed.

For example, when a Django admin change-list page is being filtered by a date
drilldown, the header for a given month displays the month and the year.
Different locales have different formats. For example, U.S. English would say
"January 2006," whereas another locale might say "2006/January."

Note that if :setting:`USE_L10N` is set to ``True``, then the corresponding
locale-dictated format has higher precedence and will be applied.

See :tfilter:`allowed date format strings <date>`. See also
:setting:`DATE_FORMAT`, :setting:`DATETIME_FORMAT`, :setting:`TIME_FORMAT`
and :setting:`MONTH_DAY_FORMAT`.

.. setting:: X_FRAME_OPTIONS

``X_FRAME_OPTIONS``
-------------------

Default: ``'SAMEORIGIN'``

The default value for the X-Frame-Options header used by
:class:`~django.middleware.clickjacking.XFrameOptionsMiddleware`. See the
:doc:`clickjacking protection </ref/clickjacking/>` documentation.


Auth
====

Settings for :mod:`django.contrib.auth`.

.. setting:: AUTHENTICATION_BACKENDS

``AUTHENTICATION_BACKENDS``
---------------------------

Default: ``['django.contrib.auth.backends.ModelBackend']``

A list of authentication backend classes (as strings) to use when attempting to
authenticate a user. See the :ref:`authentication backends documentation
<authentication-backends>` for details.

.. setting:: AUTH_USER_MODEL

``AUTH_USER_MODEL``
-------------------

Default: ``'auth.User'``

The model to use to represent a User. See :ref:`auth-custom-user`.

.. warning::
    You cannot change the AUTH_USER_MODEL setting during the lifetime of
    a project (i.e. once you have made and migrated models that depend on it)
    without serious effort. It is intended to be set at the project start,
    and the model it refers to must be available in the first migration of
    the app that it lives in.
    See :ref:`auth-custom-user` for more details.

.. setting:: LOGIN_REDIRECT_URL

``LOGIN_REDIRECT_URL``
----------------------

Default: ``'/accounts/profile/'``

The URL where requests are redirected after login when the
``contrib.auth.login`` view gets no ``next`` parameter.

This is used by the :func:`~django.contrib.auth.decorators.login_required`
decorator, for example.

This setting also accepts :ref:`named URL patterns <naming-url-patterns>` which
can be used to reduce configuration duplication since you don't have to define
the URL in two places (``settings`` and URLconf).

.. setting:: LOGIN_URL

``LOGIN_URL``
-------------

Default: ``'/accounts/login/'``

The URL where requests are redirected for login, especially when using the
:func:`~django.contrib.auth.decorators.login_required` decorator.

This setting also accepts :ref:`named URL patterns <naming-url-patterns>` which
can be used to reduce configuration duplication since you don't have to define
the URL in two places (``settings`` and URLconf).

.. setting:: LOGOUT_REDIRECT_URL

``LOGOUT_REDIRECT_URL``
-----------------------

.. versionadded:: 1.10

Default: ``None``

The URL where requests are redirected after a user logs out using the
:func:`~django.contrib.auth.views.logout` view (if the view doesn't get a
``next_page`` argument).

If ``None``, no redirect will be performed and the logout view will be
rendered.

This setting also accepts :ref:`named URL patterns <naming-url-patterns>` which
can be used to reduce configuration duplication since you don't have to define
the URL in two places (``settings`` and URLconf).

.. setting:: PASSWORD_RESET_TIMEOUT_DAYS

``PASSWORD_RESET_TIMEOUT_DAYS``
-------------------------------

Default: ``3``

The number of days a password reset link is valid for. Used by the
:mod:`django.contrib.auth` password reset mechanism.

.. setting:: PASSWORD_HASHERS

``PASSWORD_HASHERS``
--------------------

See :ref:`auth_password_storage`.

Default::

    [
        'django.contrib.auth.hashers.PBKDF2PasswordHasher',
        'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
        'django.contrib.auth.hashers.Argon2PasswordHasher',
        'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
        'django.contrib.auth.hashers.BCryptPasswordHasher',
    ]

.. versionchanged:: 1.10

    The following hashers were removed from the defaults::

        'django.contrib.auth.hashers.SHA1PasswordHasher'
        'django.contrib.auth.hashers.MD5PasswordHasher'
        'django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher'
        'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher'
        'django.contrib.auth.hashers.CryptPasswordHasher'

    Consider using a :ref:`wrapped password hasher <wrapping-password-hashers>`
    to strengthen the hashes in your database. If that's not feasible, add this
    setting to your project and add back any hashers that you need.

    Also, the ``Argon2PasswordHasher`` was added.

.. setting:: AUTH_PASSWORD_VALIDATORS

``AUTH_PASSWORD_VALIDATORS``
----------------------------

.. versionadded:: 1.9

Default: ``[]`` (Empty list)

The list of validators that are used to check the strength of user's passwords.
See :ref:`password-validation` for more details. By default, no validation is
performed and all passwords are accepted.

.. _settings-messages:

Messages
========

Settings for :mod:`django.contrib.messages`.

.. setting:: MESSAGE_LEVEL

``MESSAGE_LEVEL``
-----------------

Default: ``messages.INFO``

Sets the minimum message level that will be recorded by the messages
framework. See :ref:`message levels <message-level>` for more details.

.. admonition:: Important

   If you override ``MESSAGE_LEVEL`` in your settings file and rely on any of
   the built-in constants, you must import the constants module directly to
   avoid the potential for circular imports, e.g.::

       from django.contrib.messages import constants as message_constants
       MESSAGE_LEVEL = message_constants.DEBUG

   If desired, you may specify the numeric values for the constants directly
   according to the values in the above :ref:`constants table
   <message-level-constants>`.

.. setting:: MESSAGE_STORAGE

``MESSAGE_STORAGE``
-------------------

Default: ``'django.contrib.messages.storage.fallback.FallbackStorage'``

Controls where Django stores message data. Valid values are:

* ``'django.contrib.messages.storage.fallback.FallbackStorage'``
* ``'django.contrib.messages.storage.session.SessionStorage'``
* ``'django.contrib.messages.storage.cookie.CookieStorage'``

See :ref:`message storage backends <message-storage-backends>` for more details.

The backends that use cookies --
:class:`~django.contrib.messages.storage.cookie.CookieStorage` and
:class:`~django.contrib.messages.storage.fallback.FallbackStorage` --
use the value of :setting:`SESSION_COOKIE_DOMAIN`, :setting:`SESSION_COOKIE_SECURE`
and :setting:`SESSION_COOKIE_HTTPONLY` when setting their cookies.

.. setting:: MESSAGE_TAGS

``MESSAGE_TAGS``
----------------

Default::

    {
        messages.DEBUG: 'debug',
        messages.INFO: 'info',
        messages.SUCCESS: 'success',
        messages.WARNING: 'warning',
        messages.ERROR: 'error',
    }

This sets the mapping of message level to message tag, which is typically
rendered as a CSS class in HTML. If you specify a value, it will extend
the default. This means you only have to specify those values which you need
to override. See :ref:`message-displaying` above for more details.

.. admonition:: Important

   If you override ``MESSAGE_TAGS`` in your settings file and rely on any of
   the built-in constants, you must import the ``constants`` module directly to
   avoid the potential for circular imports, e.g.::

       from django.contrib.messages import constants as message_constants
       MESSAGE_TAGS = {message_constants.INFO: ''}

   If desired, you may specify the numeric values for the constants directly
   according to the values in the above :ref:`constants table
   <message-level-constants>`.

.. _settings-sessions:

Sessions
========

Settings for :mod:`django.contrib.sessions`.

.. setting:: SESSION_CACHE_ALIAS

``SESSION_CACHE_ALIAS``
-----------------------

Default: ``'default'``

If you're using :ref:`cache-based session storage <cached-sessions-backend>`,
this selects the cache to use.

.. setting:: SESSION_COOKIE_AGE

``SESSION_COOKIE_AGE``
----------------------

Default: ``1209600`` (2 weeks, in seconds)

The age of session cookies, in seconds.

.. setting:: SESSION_COOKIE_DOMAIN

``SESSION_COOKIE_DOMAIN``
-------------------------

Default: ``None``

The domain to use for session cookies. Set this to a string such as
``".example.com"`` (note the leading dot!) for cross-domain cookies, or use
``None`` for a standard domain cookie.

Be cautious when updating this setting on a production site. If you update
this setting to enable cross-domain cookies on a site that previously used
standard domain cookies, existing user cookies will be set to the old
domain. This may result in them being unable to log in as long as these cookies
persist.

This setting also affects cookies set by :mod:`django.contrib.messages`.

.. setting:: SESSION_COOKIE_HTTPONLY

``SESSION_COOKIE_HTTPONLY``
---------------------------

Default: ``True``

Whether to use ``HTTPOnly`` flag on the session cookie. If this is set to
``True``, client-side JavaScript will not to be able to access the
session cookie.

HTTPOnly_ is a flag included in a Set-Cookie HTTP response header. It
is not part of the :rfc:`2109` standard for cookies, and it isn't honored
consistently by all browsers. However, when it is honored, it can be a
useful way to mitigate the risk of client side script accessing the
protected cookie data.

Turning it on makes it less trivial for an attacker to escalate a cross-site
scripting vulnerability into full hijacking of a user's session. There's not
much excuse for leaving this off, either: if your code depends on reading
session cookies from JavaScript, you're probably doing it wrong.

.. _HTTPOnly: https://www.owasp.org/index.php/HTTPOnly

.. setting:: SESSION_COOKIE_NAME

``SESSION_COOKIE_NAME``
-----------------------

Default: ``'sessionid'``

The name of the cookie to use for sessions. This can be whatever you want
(as long as it's different from the other cookie names in your application).

.. setting:: SESSION_COOKIE_PATH

``SESSION_COOKIE_PATH``
-----------------------

Default: ``'/'``

The path set on the session cookie. This should either match the URL path of your
Django installation or be parent of that path.

This is useful if you have multiple Django instances running under the same
hostname. They can use different cookie paths, and each instance will only see
its own session cookie.

.. setting:: SESSION_COOKIE_SECURE

``SESSION_COOKIE_SECURE``
-------------------------

Default: ``False``

Whether to use a secure cookie for the session cookie. If this is set to
``True``, the cookie will be marked as "secure," which means browsers may
ensure that the cookie is only sent under an HTTPS connection.

Since it's trivial for a packet sniffer (e.g. `Firesheep`_) to hijack a user's
session if the session cookie is sent unencrypted, there's really no good
excuse to leave this off. It will prevent you from using sessions on insecure
requests and that's a good thing.

.. _Firesheep: http://codebutler.com/firesheep

.. setting:: SESSION_ENGINE

``SESSION_ENGINE``
------------------

Default: ``'django.contrib.sessions.backends.db'``

Controls where Django stores session data. Included engines are:

* ``'django.contrib.sessions.backends.db'``
* ``'django.contrib.sessions.backends.file'``
* ``'django.contrib.sessions.backends.cache'``
* ``'django.contrib.sessions.backends.cached_db'``
* ``'django.contrib.sessions.backends.signed_cookies'``

See :ref:`configuring-sessions` for more details.

.. setting:: SESSION_EXPIRE_AT_BROWSER_CLOSE

``SESSION_EXPIRE_AT_BROWSER_CLOSE``
-----------------------------------

Default: ``False``

Whether to expire the session when the user closes their browser. See
:ref:`browser-length-vs-persistent-sessions`.

.. setting:: SESSION_FILE_PATH

``SESSION_FILE_PATH``
---------------------

Default: ``None``

If you're using file-based session storage, this sets the directory in
which Django will store session data. When the default value (``None``) is
used, Django will use the standard temporary directory for the system.


.. setting:: SESSION_SAVE_EVERY_REQUEST

``SESSION_SAVE_EVERY_REQUEST``
------------------------------

Default: ``False``

Whether to save the session data on every request. If this is ``False``
(default), then the session data will only be saved if it has been modified --
that is, if any of its dictionary values have been assigned or deleted. Empty
sessions won't be created, even if this setting is active.

.. setting:: SESSION_SERIALIZER

``SESSION_SERIALIZER``
----------------------

Default: ``'django.contrib.sessions.serializers.JSONSerializer'``

Full import path of a serializer class to use for serializing session data.
Included serializers are:

* ``'django.contrib.sessions.serializers.PickleSerializer'``
* ``'django.contrib.sessions.serializers.JSONSerializer'``

See :ref:`session_serialization` for details, including a warning regarding
possible remote code execution when using
:class:`~django.contrib.sessions.serializers.PickleSerializer`.

Sites
=====

Settings for :mod:`django.contrib.sites`.

.. setting:: SITE_ID

``SITE_ID``
-----------

Default: Not defined

The ID, as an integer, of the current site in the ``django_site`` database
table. This is used so that application data can hook into specific sites
and a single database can manage content for multiple sites.


.. _settings-staticfiles:

Static Files
============

Settings for :mod:`django.contrib.staticfiles`.

.. setting:: STATIC_ROOT

``STATIC_ROOT``
---------------

Default: ``None``

The absolute path to the directory where :djadmin:`collectstatic` will collect
static files for deployment.

Example: ``"/var/www/example.com/static/"``

If the :doc:`staticfiles</ref/contrib/staticfiles>` contrib app is enabled
(default) the :djadmin:`collectstatic` management command will collect static
files into this directory. See the howto on :doc:`managing static
files</howto/static-files/index>` for more details about usage.

.. warning::

    This should be an initially empty destination directory for collecting
    your static files from their permanent locations into one directory for
    ease of deployment; it is **not** a place to store your static files
    permanently. You should do that in directories that will be found by
    :doc:`staticfiles</ref/contrib/staticfiles>`’s
    :setting:`finders<STATICFILES_FINDERS>`, which by default, are
    ``'static/'`` app sub-directories and any directories you include in
    :setting:`STATICFILES_DIRS`).

.. setting:: STATIC_URL

``STATIC_URL``
--------------

Default: ``None``

URL to use when referring to static files located in :setting:`STATIC_ROOT`.

Example: ``"/static/"`` or ``"http://static.example.com/"``

If not ``None``, this will be used as the base path for
:ref:`asset definitions<form-asset-paths>` (the ``Media`` class) and the
:doc:`staticfiles app</ref/contrib/staticfiles>`.

It must end in a slash if set to a non-empty value.

You may need to :ref:`configure these files to be served in development
<serving-static-files-in-development>` and will definitely need to do so
:doc:`in production </howto/static-files/deployment>`.

.. setting:: STATICFILES_DIRS

``STATICFILES_DIRS``
--------------------

Default: ``[]`` (Empty list)

This setting defines the additional locations the staticfiles app will traverse
if the ``FileSystemFinder`` finder is enabled, e.g. if you use the
:djadmin:`collectstatic` or :djadmin:`findstatic` management command or use the
static file serving view.

This should be set to a list of strings that contain full paths to
your additional files directory(ies) e.g.::

    STATICFILES_DIRS = [
        "/home/special.polls.com/polls/static",
        "/home/polls.com/polls/static",
        "/opt/webfiles/common",
    ]

Note that these paths should use Unix-style forward slashes, even on Windows
(e.g. ``"C:/Users/user/mysite/extra_static_content"``).

Prefixes (optional)
~~~~~~~~~~~~~~~~~~~

In case you want to refer to files in one of the locations with an additional
namespace, you can **optionally** provide a prefix as ``(prefix, path)``
tuples, e.g.::

    STATICFILES_DIRS = [
        # ...
        ("downloads", "/opt/webfiles/stats"),
    ]

For example, assuming you have :setting:`STATIC_URL` set to ``'/static/'``, the
:djadmin:`collectstatic` management command would collect the "stats" files
in a ``'downloads'`` subdirectory of :setting:`STATIC_ROOT`.

This would allow you to refer to the local file
``'/opt/webfiles/stats/polls_20101022.tar.gz'`` with
``'/static/downloads/polls_20101022.tar.gz'`` in your templates, e.g.:

.. code-block:: html+django

    <a href="{% static "downloads/polls_20101022.tar.gz" %}">

.. setting:: STATICFILES_STORAGE

``STATICFILES_STORAGE``
-----------------------

Default: ``'django.contrib.staticfiles.storage.StaticFilesStorage'``

The file storage engine to use when collecting static files with the
:djadmin:`collectstatic` management command.

A ready-to-use instance of the storage backend defined in this setting
can be found at ``django.contrib.staticfiles.storage.staticfiles_storage``.

For an example, see :ref:`staticfiles-from-cdn`.

.. setting:: STATICFILES_FINDERS

``STATICFILES_FINDERS``
-----------------------

Default::

    [
        'django.contrib.staticfiles.finders.FileSystemFinder',
        'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    ]

The list of finder backends that know how to find static files in
various locations.

The default will find files stored in the :setting:`STATICFILES_DIRS` setting
(using ``django.contrib.staticfiles.finders.FileSystemFinder``) and in a
``static`` subdirectory of each app (using
``django.contrib.staticfiles.finders.AppDirectoriesFinder``). If multiple
files with the same name are present, the first file that is found will be
used.

One finder is disabled by default:
``django.contrib.staticfiles.finders.DefaultStorageFinder``. If added to
your :setting:`STATICFILES_FINDERS` setting, it will look for static files in
the default file storage as defined by the :setting:`DEFAULT_FILE_STORAGE`
setting.

.. note::

    When using the ``AppDirectoriesFinder`` finder, make sure your apps
    can be found by staticfiles. Simply add the app to the
    :setting:`INSTALLED_APPS` setting of your site.

Static file finders are currently considered a private interface, and this
interface is thus undocumented.

Core Settings Topical Index
===========================

Cache
-----
* :setting:`CACHES`
* :setting:`CACHE_MIDDLEWARE_ALIAS`
* :setting:`CACHE_MIDDLEWARE_KEY_PREFIX`
* :setting:`CACHE_MIDDLEWARE_SECONDS`

Database
--------
* :setting:`DATABASES`
* :setting:`DATABASE_ROUTERS`
* :setting:`DEFAULT_INDEX_TABLESPACE`
* :setting:`DEFAULT_TABLESPACE`

Debugging
---------
* :setting:`DEBUG`
* :setting:`DEBUG_PROPAGATE_EXCEPTIONS`

Email
-----
* :setting:`ADMINS`
* :setting:`DEFAULT_CHARSET`
* :setting:`DEFAULT_FROM_EMAIL`
* :setting:`EMAIL_BACKEND`
* :setting:`EMAIL_FILE_PATH`
* :setting:`EMAIL_HOST`
* :setting:`EMAIL_HOST_PASSWORD`
* :setting:`EMAIL_HOST_USER`
* :setting:`EMAIL_PORT`
* :setting:`EMAIL_SSL_CERTFILE`
* :setting:`EMAIL_SSL_KEYFILE`
* :setting:`EMAIL_SUBJECT_PREFIX`
* :setting:`EMAIL_TIMEOUT`
* :setting:`EMAIL_USE_TLS`
* :setting:`MANAGERS`
* :setting:`SERVER_EMAIL`

Error reporting
---------------
* :setting:`DEFAULT_EXCEPTION_REPORTER_FILTER`
* :setting:`IGNORABLE_404_URLS`
* :setting:`MANAGERS`
* :setting:`SILENCED_SYSTEM_CHECKS`

.. _file-upload-settings:

File uploads
------------
* :setting:`DEFAULT_FILE_STORAGE`
* :setting:`FILE_CHARSET`
* :setting:`FILE_UPLOAD_HANDLERS`
* :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE`
* :setting:`FILE_UPLOAD_PERMISSIONS`
* :setting:`FILE_UPLOAD_TEMP_DIR`
* :setting:`MEDIA_ROOT`
* :setting:`MEDIA_URL`

Globalization (``i18n``/``l10n``)
---------------------------------
* :setting:`DATE_FORMAT`
* :setting:`DATE_INPUT_FORMATS`
* :setting:`DATETIME_FORMAT`
* :setting:`DATETIME_INPUT_FORMATS`
* :setting:`DECIMAL_SEPARATOR`
* :setting:`FIRST_DAY_OF_WEEK`
* :setting:`FORMAT_MODULE_PATH`
* :setting:`LANGUAGE_CODE`
* :setting:`LANGUAGE_COOKIE_AGE`
* :setting:`LANGUAGE_COOKIE_DOMAIN`
* :setting:`LANGUAGE_COOKIE_NAME`
* :setting:`LANGUAGE_COOKIE_PATH`
* :setting:`LANGUAGES`
* :setting:`LOCALE_PATHS`
* :setting:`MONTH_DAY_FORMAT`
* :setting:`NUMBER_GROUPING`
* :setting:`SHORT_DATE_FORMAT`
* :setting:`SHORT_DATETIME_FORMAT`
* :setting:`THOUSAND_SEPARATOR`
* :setting:`TIME_FORMAT`
* :setting:`TIME_INPUT_FORMATS`
* :setting:`TIME_ZONE`
* :setting:`USE_I18N`
* :setting:`USE_L10N`
* :setting:`USE_THOUSAND_SEPARATOR`
* :setting:`USE_TZ`
* :setting:`YEAR_MONTH_FORMAT`

HTTP
----
* :setting:`DATA_UPLOAD_MAX_MEMORY_SIZE`
* :setting:`DATA_UPLOAD_MAX_NUMBER_FIELDS`
* :setting:`DEFAULT_CHARSET`
* :setting:`DEFAULT_CONTENT_TYPE`
* :setting:`DISALLOWED_USER_AGENTS`
* :setting:`FORCE_SCRIPT_NAME`
* :setting:`INTERNAL_IPS`
* :setting:`MIDDLEWARE`
* :setting:`MIDDLEWARE_CLASSES`
* Security

  * :setting:`SECURE_BROWSER_XSS_FILTER`
  * :setting:`SECURE_CONTENT_TYPE_NOSNIFF`
  * :setting:`SECURE_HSTS_INCLUDE_SUBDOMAINS`
  * :setting:`SECURE_HSTS_SECONDS`
  * :setting:`SECURE_PROXY_SSL_HEADER`
  * :setting:`SECURE_REDIRECT_EXEMPT`
  * :setting:`SECURE_SSL_HOST`
  * :setting:`SECURE_SSL_REDIRECT`
* :setting:`SIGNING_BACKEND`
* :setting:`USE_ETAGS`
* :setting:`USE_X_FORWARDED_HOST`
* :setting:`USE_X_FORWARDED_PORT`
* :setting:`WSGI_APPLICATION`

Logging
-------
* :setting:`LOGGING`
* :setting:`LOGGING_CONFIG`

Models
------
* :setting:`ABSOLUTE_URL_OVERRIDES`
* :setting:`FIXTURE_DIRS`
* :setting:`INSTALLED_APPS`

Security
--------
* Cross Site Request Forgery Protection

  * :setting:`CSRF_COOKIE_DOMAIN`
  * :setting:`CSRF_COOKIE_NAME`
  * :setting:`CSRF_COOKIE_PATH`
  * :setting:`CSRF_COOKIE_SECURE`
  * :setting:`CSRF_FAILURE_VIEW`
  * :setting:`CSRF_HEADER_NAME`
  * :setting:`CSRF_TRUSTED_ORIGINS`

* :setting:`SECRET_KEY`
* :setting:`X_FRAME_OPTIONS`

Serialization
-------------
* :setting:`DEFAULT_CHARSET`
* :setting:`SERIALIZATION_MODULES`

Templates
---------
* :setting:`TEMPLATES`

Testing
-------
* Database: :setting:`TEST <DATABASE-TEST>`
* :setting:`TEST_NON_SERIALIZED_APPS`
* :setting:`TEST_RUNNER`

URLs
----
* :setting:`APPEND_SLASH`
* :setting:`PREPEND_WWW`
* :setting:`ROOT_URLCONF`

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Signals (`大一小学期/Week_3-Python/exam/2016/docs/ref/signals.txt`)

=======
Signals
=======

A list of all the signals that Django sends. All built-in signals are sent
using the :meth:`~django.dispatch.Signal.send` method.

.. seealso::

    See the documentation on the :doc:`signal dispatcher </topics/signals>` for
    information regarding how to register for and receive signals.

    The :doc:`authentication framework </topics/auth/index>` sends :ref:`signals when
    a user is logged in / out <topics-auth-signals>`.

Model signals
=============

.. module:: django.db.models.signals
   :synopsis: Signals sent by the model system.

The :mod:`django.db.models.signals` module defines a set of signals sent by the
model system.

.. warning::

    Many of these signals are sent by various model methods like
    ``__init__()`` or :meth:`~django.db.models.Model.save` that you can
    override in your own code.

    If you override these methods on your model, you must call the parent class'
    methods for this signals to be sent.

    Note also that Django stores signal handlers as weak references by default,
    so if your handler is a local function, it may be garbage collected.  To
    prevent this, pass ``weak=False`` when you call the signal's :meth:`~django.dispatch.Signal.connect`.

.. note::

    Model signals ``sender`` model can be lazily referenced when connecting a
    receiver by specifying its full application label. For example, an
    ``Answer`` model defined in the ``polls`` application could be referenced
    as ``'polls.Answer'``. This sort of reference can be quite handy when
    dealing with circular import dependencies and swappable models.

``pre_init``
------------

.. attribute:: django.db.models.signals.pre_init
   :module:

.. ^^^^^^^ this :module: hack keeps Sphinx from prepending the module.

Whenever you instantiate a Django model, this signal is sent at the beginning
of the model's ``__init__()`` method.

Arguments sent with this signal:

``sender``
    The model class that just had an instance created.

``args``
    A list of positional arguments passed to ``__init__()``:

``kwargs``
    A dictionary of keyword arguments passed to ``__init__()``:

For example, the :doc:`tutorial </intro/tutorial01>` has this line::

    p = Poll(question="What's up?", pub_date=datetime.now())

The arguments sent to a :data:`pre_init` handler would be:

==========  ===============================================================
Argument    Value
==========  ===============================================================
``sender``  ``Poll`` (the class itself)

``args``    ``[]`` (an empty list because there were no positional
            arguments passed to ``__init__()``.)

``kwargs``  ``{'question': "What's up?", 'pub_date': datetime.now()}``
==========  ===============================================================

``post_init``
-------------

.. data:: django.db.models.signals.post_init
   :module:

Like pre_init, but this one is sent when the ``__init__()`` method finishes.

Arguments sent with this signal:

``sender``
    As above: the model class that just had an instance created.

``instance``
    The actual instance of the model that's just been created.

``pre_save``
------------

.. data:: django.db.models.signals.pre_save
   :module:

This is sent at the beginning of a model's :meth:`~django.db.models.Model.save`
method.

Arguments sent with this signal:

``sender``
    The model class.

``instance``
    The actual instance being saved.

``raw``
    A boolean; ``True`` if the model is saved exactly as presented
    (i.e. when loading a fixture). One should not query/modify other
    records in the database as the database might not be in a
    consistent state yet.

``using``
    The database alias being used.

``update_fields``
    The set of fields to update as passed to :meth:`.Model.save`, or ``None``
    if ``update_fields`` wasn't passed to ``save()``.

``post_save``
-------------

.. data:: django.db.models.signals.post_save
   :module:

Like :data:`pre_save`, but sent at the end of the
:meth:`~django.db.models.Model.save` method.

Arguments sent with this signal:

``sender``
    The model class.

``instance``
    The actual instance being saved.

``created``
    A boolean; ``True`` if a new record was created.

``raw``
    A boolean; ``True`` if the model is saved exactly as presented
    (i.e. when loading a fixture). One should not query/modify other
    records in the database as the database might not be in a
    consistent state yet.

``using``
    The database alias being used.

``update_fields``
    The set of fields to update as passed to :meth:`.Model.save`, or ``None``
    if ``update_fields`` wasn't passed to ``save()``.

``pre_delete``
--------------

.. data:: django.db.models.signals.pre_delete
   :module:

Sent at the beginning of a model's :meth:`~django.db.models.Model.delete`
method and a queryset's :meth:`~django.db.models.query.QuerySet.delete` method.

Arguments sent with this signal:

``sender``
    The model class.

``instance``
    The actual instance being deleted.

``using``
    The database alias being used.

``post_delete``
---------------

.. data:: django.db.models.signals.post_delete
   :module:

Like :data:`pre_delete`, but sent at the end of a model's
:meth:`~django.db.models.Model.delete` method and a queryset's
:meth:`~django.db.models.query.QuerySet.delete` method.

Arguments sent with this signal:

``sender``
    The model class.

``instance``
    The actual instance being deleted.

    Note that the object will no longer be in the database, so be very
    careful what you do with this instance.

``using``
    The database alias being used.

``m2m_changed``
---------------

.. data:: django.db.models.signals.m2m_changed
   :module:

Sent when a :class:`~django.db.models.ManyToManyField` is changed on a model
instance. Strictly speaking, this is not a model signal since it is sent by the
:class:`~django.db.models.ManyToManyField`, but since it complements the
:data:`pre_save`/:data:`post_save` and :data:`pre_delete`/:data:`post_delete`
when it comes to tracking changes to models, it is included here.

Arguments sent with this signal:

``sender``
    The intermediate model class describing the
    :class:`~django.db.models.ManyToManyField`. This class is automatically
    created when a many-to-many field is defined; you can access it using the
    ``through`` attribute on the many-to-many field.

``instance``
    The instance whose many-to-many relation is updated. This can be an
    instance of the ``sender``, or of the class the
    :class:`~django.db.models.ManyToManyField` is related to.

``action``
    A string indicating the type of update that is done on the relation.
    This can be one of the following:

    ``"pre_add"``
        Sent *before* one or more objects are added to the relation.
    ``"post_add"``
        Sent *after* one or more objects are added to the relation.
    ``"pre_remove"``
        Sent *before* one or more objects are removed from the relation.
    ``"post_remove"``
        Sent *after* one or more objects are removed from the relation.
    ``"pre_clear"``
        Sent *before* the relation is cleared.
    ``"post_clear"``
        Sent *after* the relation is cleared.

``reverse``
    Indicates which side of the relation is updated (i.e., if it is the
    forward or reverse relation that is being modified).

``model``
    The class of the objects that are added to, removed from or cleared
    from the relation.

``pk_set``
    For the ``pre_add``, ``post_add``, ``pre_remove`` and ``post_remove``
    actions, this is a set of primary key values that have been added to
    or removed from the relation.

    For the ``pre_clear`` and ``post_clear`` actions, this is ``None``.

``using``
    The database alias being used.

For example, if a ``Pizza`` can have multiple ``Topping`` objects, modeled
like this::

    class Topping(models.Model):
        # ...
        pass

    class Pizza(models.Model):
        # ...
        toppings = models.ManyToManyField(Topping)

If we connected a handler like this::

    from django.db.models.signals import m2m_changed

    def toppings_changed(sender, **kwargs):
        # Do something
        pass

    m2m_changed.connect(toppings_changed, sender=Pizza.toppings.through)

and then did something like this::

    >>> p = Pizza.objects.create(...)
    >>> t = Topping.objects.create(...)
    >>> p.toppings.add(t)

the arguments sent to a :data:`m2m_changed` handler (``toppings_changed`` in
the example above) would be:

==============  ============================================================
Argument        Value
==============  ============================================================
``sender``      ``Pizza.toppings.through`` (the intermediate m2m class)

``instance``    ``p`` (the ``Pizza`` instance being modified)

``action``      ``"pre_add"`` (followed by a separate signal with ``"post_add"``)

``reverse``     ``False`` (``Pizza`` contains the
                :class:`~django.db.models.ManyToManyField`, so this call
                modifies the forward relation)

``model``       ``Topping`` (the class of the objects added to the
                ``Pizza``)

``pk_set``      ``{t.id}`` (since only ``Topping t`` was added to the relation)

``using``       ``"default"`` (since the default router sends writes here)
==============  ============================================================

And if we would then do something like this::

    >>> t.pizza_set.remove(p)

the arguments sent to a :data:`m2m_changed` handler would be:

==============  ============================================================
Argument        Value
==============  ============================================================
``sender``      ``Pizza.toppings.through`` (the intermediate m2m class)

``instance``    ``t`` (the ``Topping`` instance being modified)

``action``      ``"pre_remove"`` (followed by a separate signal with ``"post_remove"``)

``reverse``     ``True`` (``Pizza`` contains the
                :class:`~django.db.models.ManyToManyField`, so this call
                modifies the reverse relation)

``model``       ``Pizza`` (the class of the objects removed from the
                ``Topping``)

``pk_set``      ``{p.id}`` (since only ``Pizza p`` was removed from the
                relation)

``using``       ``"default"`` (since the default router sends writes here)
==============  ============================================================

``class_prepared``
------------------

.. data:: django.db.models.signals.class_prepared
   :module:

Sent whenever a model class has been "prepared" -- that is, once model has
been defined and registered with Django's model system. Django uses this
signal internally; it's not generally used in third-party applications.

Since this signal is sent during the app registry population process, and
:meth:`AppConfig.ready() <django.apps.AppConfig.ready>` runs after the app
registry is fully populated, receivers cannot be connected in that method.
One possibility is to connect them ``AppConfig.__init__()`` instead, taking
care not to import models or trigger calls to the app registry.

Arguments that are sent with this signal:

``sender``
    The model class which was just prepared.

Management signals
==================

Signals sent by :doc:`django-admin </ref/django-admin>`.

``pre_migrate``
---------------

.. data:: django.db.models.signals.pre_migrate
   :module:

Sent by the :djadmin:`migrate` command before it starts to install an
application. It's not emitted for applications that lack a ``models`` module.

Arguments sent with this signal:

``sender``
    An :class:`~django.apps.AppConfig` instance for the application about to
    be migrated/synced.

``app_config``
    Same as ``sender``.

``verbosity``
    Indicates how much information manage.py is printing on screen. See
    the :option:`--verbosity` flag for details.

    Functions which listen for :data:`pre_migrate` should adjust what they
    output to the screen based on the value of this argument.

``interactive``
    If ``interactive`` is ``True``, it's safe to prompt the user to input
    things on the command line. If ``interactive`` is ``False``, functions
    which listen for this signal should not try to prompt for anything.

    For example, the :mod:`django.contrib.auth` app only prompts to create a
    superuser when ``interactive`` is ``True``.

``using``
    The alias of database on which a command will operate.

``plan``
    .. versionadded:: 1.10

    The migration plan that is going to be used for the migration run. While
    the plan is not public API, this allows for the rare cases when it is
    necessary to know the plan. A plan is a list of two-tuples with the first
    item being the instance of a migration class and the second item showing
    if the migration was rolled back (``True``) or applied (``False``).

``apps``
    .. versionadded:: 1.10

    An instance of :data:`Apps <django.apps>` containing the state of the
    project before the migration run. It should be used instead of the global
    :attr:`apps <django.apps.apps>` registry to retrieve the models you
    want to perform operations on.

``post_migrate``
----------------

.. data:: django.db.models.signals.post_migrate
   :module:

Sent by the :djadmin:`migrate` command after it installs an application, and the
:djadmin:`flush` command. It's not emitted for applications that lack a
``models`` module.

It is important that handlers of this signal perform idempotent changes (e.g.
no database alterations) as this may cause the :djadmin:`flush` management
command to fail if it also ran during the :djadmin:`migrate` command.

Arguments sent with this signal:

``sender``
    An :class:`~django.apps.AppConfig` instance for the application that was
    just installed.

``app_config``
    Same as ``sender``.

``verbosity``
    Indicates how much information manage.py is printing on screen. See
    the :option:`--verbosity` flag for details.

    Functions which listen for :data:`post_migrate` should adjust what they
    output to the screen based on the value of this argument.

``interactive``
    If ``interactive`` is ``True``, it's safe to prompt the user to input
    things on the command line. If ``interactive`` is ``False``, functions
    which listen for this signal should not try to prompt for anything.

    For example, the :mod:`django.contrib.auth` app only prompts to create a
    superuser when ``interactive`` is ``True``.

``using``
    The database alias used for synchronization. Defaults to the ``default``
    database.

``plan``
    .. versionadded:: 1.10

    The migration plan that was used for the migration run. While the plan is
    not public API, this allows for the rare cases when it is necessary to
    know the plan. A plan is a list of two-tuples with the first item being
    the instance of a migration class and the second item showing if the
    migration was rolled back (``True``) or applied (``False``).

``apps``
    .. versionadded:: 1.10

    An instance of :data:`Apps <django.apps.apps>` containing the state of the
    project after the migration run. It should be used instead of the global
    :attr:`apps <django.apps.apps>` registry to retrieve the models you
    want to perform operations on.

For example, you could register a callback in an
:class:`~django.apps.AppConfig` like this::

    from django.apps import AppConfig
    from django.db.models.signals import post_migrate

    def my_callback(sender, **kwargs):
        # Your specific logic here
        pass

    class MyAppConfig(AppConfig):
        ...

        def ready(self):
            post_migrate.connect(my_callback, sender=self)

.. note::

    If you provide an :class:`~django.apps.AppConfig` instance as the sender
    argument, please ensure that the signal is registered in
    :meth:`~django.apps.AppConfig.ready`. ``AppConfig``\s are recreated for
    tests that run with a modified set of :setting:`INSTALLED_APPS` (such as
    when settings are overridden) and such signals should be connected for each
    new ``AppConfig`` instance.

Request/response signals
========================

.. module:: django.core.signals
   :synopsis: Core signals sent by the request/response system.

Signals sent by the core framework when processing a request.

``request_started``
-------------------

.. data:: django.core.signals.request_started
   :module:

Sent when Django begins processing an HTTP request.

Arguments sent with this signal:

``sender``
    The handler class -- e.g. ``django.core.handlers.wsgi.WsgiHandler`` -- that
    handled the request.
``environ``
    The ``environ`` dictionary provided to the request.

``request_finished``
--------------------

.. data:: django.core.signals.request_finished
   :module:

Sent when Django finishes delivering an HTTP response to the client.

.. note::

    Some WSGI servers and middleware do not always call ``close`` on the
    response object after handling a request, most notably uWSGI prior to 1.2.6
    and Sentry's error reporting middleware up to 2.0.7. In those cases this
    signal isn't sent at all. This can result in idle connections to database
    and memcache servers.

Arguments sent with this signal:

``sender``
    The handler class, as above.

``got_request_exception``
-------------------------

.. data:: django.core.signals.got_request_exception
   :module:

This signal is sent whenever Django encounters an exception while processing an incoming HTTP request.

Arguments sent with this signal:

``sender``
    The handler class, as above.

``request``
    The :class:`~django.http.HttpRequest` object.

Test signals
============

.. module:: django.test.signals
   :synopsis: Signals sent during testing.

Signals only sent when :ref:`running tests <running-tests>`.

``setting_changed``
-------------------

.. data:: django.test.signals.setting_changed
   :module:

This signal is sent when the value of a setting is changed through the
``django.test.TestCase.settings()`` context manager or the
:func:`django.test.override_settings` decorator/context manager.

It's actually sent twice: when the new value is applied ("setup") and when the
original value is restored ("teardown"). Use the ``enter`` argument to
distinguish between the two.

You can also import this signal from ``django.core.signals`` to avoid importing
from ``django.test`` in non-test situations.

Arguments sent with this signal:

``sender``
    The settings handler.

``setting``
    The name of the setting.

``value``
    The value of the setting after the change. For settings that initially
    don't exist, in the "teardown" phase, ``value`` is ``None``.

``enter``
    A boolean; ``True`` if the setting is applied, ``False`` if restored.

``template_rendered``
---------------------

.. data:: django.test.signals.template_rendered
   :module:

Sent when the test system renders a template. This signal is not emitted during
normal operation of a Django server -- it is only available during testing.

Arguments sent with this signal:

``sender``
    The :class:`~django.template.Template` object which was rendered.

``template``
    Same as sender

``context``
    The :class:`~django.template.Context` with which the template was
    rendered.

Database Wrappers
=================

.. module:: django.db.backends
   :synopsis: Core signals sent by the database wrapper.

Signals sent by the database wrapper when a database connection is
initiated.

``connection_created``
----------------------

.. data:: django.db.backends.signals.connection_created
   :module:

Sent when the database wrapper makes the initial connection to the
database.  This is particularly useful if you'd like to send any post
connection commands to the SQL backend.

Arguments sent with this signal:

``sender``
    The database wrapper class -- i.e.
    ``django.db.backends.postgresql.DatabaseWrapper`` or
    ``django.db.backends.mysql.DatabaseWrapper``, etc.

``connection``
    The database connection that was opened. This can be used in a
    multiple-database configuration to differentiate connection signals
    from different databases.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Template Response (`大一小学期/Week_3-Python/exam/2016/docs/ref/template-response.txt`)

===================================================
``TemplateResponse`` and ``SimpleTemplateResponse``
===================================================

.. module:: django.template.response
   :synopsis: Classes dealing with lazy-rendered HTTP responses.

Standard :class:`~django.http.HttpResponse` objects are static structures.
They are provided with a block of pre-rendered content at time of
construction, and while that content can be modified, it isn't in a form that
makes it easy to perform modifications.

However, it can sometimes be beneficial to allow decorators or
middleware to modify a response *after* it has been constructed by the
view. For example, you may want to change the template that is used,
or put additional data into the context.

TemplateResponse provides a way to do just that. Unlike basic
:class:`~django.http.HttpResponse` objects, TemplateResponse objects retain
the details of the template and context that was provided by the view to
compute the response. The final output of the response is not computed until
it is needed, later in the response process.

``SimpleTemplateResponse`` objects
==================================

.. class:: SimpleTemplateResponse()

Attributes
----------

.. attribute:: SimpleTemplateResponse.template_name

    The name of the template to be rendered. Accepts a backend-dependent
    template object (such as those returned by
    :func:`~django.template.loader.get_template()`), the name of a template,
    or a list of template names.

    Example: ``['foo.html', 'path/to/bar.html']``

.. attribute:: SimpleTemplateResponse.context_data

    The context data to be used when rendering the template. It must be a
    :class:`dict`.

    Example: ``{'foo': 123}``

.. attribute:: SimpleTemplateResponse.rendered_content

    The current rendered value of the response content, using the current
    template and context data.

.. attribute:: SimpleTemplateResponse.is_rendered

    A boolean indicating whether the response content has been rendered.

Methods
-------

.. method:: SimpleTemplateResponse.__init__(template, context=None, content_type=None, status=None, charset=None, using=None)

    Instantiates a :class:`~django.template.response.SimpleTemplateResponse`
    object with the given template, context, content type, HTTP status, and
    charset.

    ``template``
        A backend-dependent template object (such as those returned by
        :func:`~django.template.loader.get_template()`), the name of a template,
        or a list of template names.

    ``context``
        A :class:`dict` of values to add to the template context. By default,
        this is an empty dictionary.

    ``content_type``
        The value included in the HTTP ``Content-Type`` header, including the
        MIME type specification and the character set encoding. If
        ``content_type`` is specified, then its value is used. Otherwise,
        :setting:`DEFAULT_CONTENT_TYPE` is used.

    ``status``
        The HTTP status code for the response.

    ``charset``
        The charset in which the response will be encoded. If not given it will
        be extracted from ``content_type``, and if that is unsuccessful, the
        :setting:`DEFAULT_CHARSET` setting will be used.

    ``using``
        The :setting:`NAME <TEMPLATES-NAME>` of a template engine to use for
        loading the template.

.. method:: SimpleTemplateResponse.resolve_context(context)

    Preprocesses context data that will be used for rendering a template.
    Accepts a :class:`dict` of context data. By default, returns the same
    :class:`dict`.

    Override this method in order to customize the context.

.. method:: SimpleTemplateResponse.resolve_template(template)

    Resolves the template instance to use for rendering. Accepts a
    backend-dependent template object (such as those returned by
    :func:`~django.template.loader.get_template()`), the name of a template,
    or a list of template names.

    Returns the backend-dependent template object instance to be rendered.

    Override this method in order to customize template loading.

.. method:: SimpleTemplateResponse.add_post_render_callback()

    Add a callback that will be invoked after rendering has taken
    place. This hook can be used to defer certain processing
    operations (such as caching) until after rendering has occurred.

    If the :class:`~django.template.response.SimpleTemplateResponse`
    has already been rendered, the callback will be invoked
    immediately.

    When called, callbacks will be passed a single argument -- the
    rendered :class:`~django.template.response.SimpleTemplateResponse`
    instance.

    If the callback returns a value that is not ``None``, this will be
    used as the response instead of the original response object (and
    will be passed to the next post rendering callback etc.)

.. method:: SimpleTemplateResponse.render()

    Sets ``response.content`` to the result obtained by
    :attr:`SimpleTemplateResponse.rendered_content`, runs all post-rendering
    callbacks, and returns the resulting response object.

    ``render()`` will only have an effect the first time it is called. On
    subsequent calls, it will return the result obtained from the first call.


``TemplateResponse`` objects
============================

.. class:: TemplateResponse()

    ``TemplateResponse`` is a subclass of
    :class:`~django.template.response.SimpleTemplateResponse` that knows about
    the current :class:`~django.http.HttpRequest`.

Methods
-------

.. method:: TemplateResponse.__init__(request, template, context=None, content_type=None, status=None, charset=None, using=None)

    Instantiates a :class:`~django.template.response.TemplateResponse` object
    with the given request, template, context, content type, HTTP status, and
    charset.

    ``request``
        An :class:`~django.http.HttpRequest` instance.

    ``template``
        A backend-dependent template object (such as those returned by
        :func:`~django.template.loader.get_template()`), the name of a template,
        or a list of template names.

    ``context``
        A :class:`dict` of values to add to the template context. By default,
        this is an empty dictionary.

    ``content_type``
        The value included in the HTTP ``Content-Type`` header, including the
        MIME type specification and the character set encoding. If
        ``content_type`` is specified, then its value is used. Otherwise,
        :setting:`DEFAULT_CONTENT_TYPE` is used.

    ``status``
        The HTTP status code for the response.

    ``charset``
        The charset in which the response will be encoded. If not given it will
        be extracted from ``content_type``, and if that is unsuccessful, the
        :setting:`DEFAULT_CHARSET` setting will be used.

    ``using``
        The :setting:`NAME <TEMPLATES-NAME>` of a template engine to use for
        loading the template.

The rendering process
=====================

Before a :class:`~django.template.response.TemplateResponse` instance can be
returned to the client, it must be rendered. The rendering process takes the
intermediate representation of template and context, and turns it into the
final byte stream that can be served to the client.

There are three circumstances under which a ``TemplateResponse`` will be
rendered:

* When the ``TemplateResponse`` instance is explicitly rendered, using
  the :meth:`SimpleTemplateResponse.render()` method.

* When the content of the response is explicitly set by assigning
  ``response.content``.

* After passing through template response middleware, but before
  passing through response middleware.

A ``TemplateResponse`` can only be rendered once. The first call to
:meth:`SimpleTemplateResponse.render` sets the content of the response;
subsequent rendering calls do not change the response content.

However, when ``response.content`` is explicitly assigned, the
change is always applied. If you want to force the content to be
re-rendered, you can re-evaluate the rendered content, and assign
the content of the response manually::

    # Set up a rendered TemplateResponse
    >>> from django.template.response import TemplateResponse
    >>> t = TemplateResponse(request, 'original.html', {})
    >>> t.render()
    >>> print(t.content)
    Original content

    # Re-rendering doesn't change content
    >>> t.template_name = 'new.html'
    >>> t.render()
    >>> print(t.content)
    Original content

    # Assigning content does change, no render() call required
    >>> t.content = t.rendered_content
    >>> print(t.content)
    New content

Post-render callbacks
---------------------

Some operations -- such as caching -- cannot be performed on an
unrendered template. They must be performed on a fully complete and
rendered response.

If you're using middleware, the solution is easy. Middleware provides
multiple opportunities to process a response on exit from a view. If
you put behavior in the response middleware, it's guaranteed to execute
after template rendering has taken place.

However, if you're using a decorator, the same opportunities do not
exist. Any behavior defined in a decorator is handled immediately.

To compensate for this (and any other analogous use cases),
:class:`TemplateResponse` allows you to register callbacks that will
be invoked when rendering has completed. Using this callback, you can
defer critical processing until a point where you can guarantee that
rendered content will be available.

To define a post-render callback, just define a function that takes
a single argument -- response -- and register that function with
the template response::

    from django.template.response import TemplateResponse

    def my_render_callback(response):
        # Do content-sensitive processing
        do_post_processing()

    def my_view(request):
        # Create a response
        response = TemplateResponse(request, 'mytemplate.html', {})
        # Register the callback
        response.add_post_render_callback(my_render_callback)
        # Return the response
        return response

``my_render_callback()`` will be invoked after the ``mytemplate.html``
has been rendered, and will be provided the fully rendered
:class:`TemplateResponse` instance as an argument.

If the template has already been rendered, the callback will be
invoked immediately.

Using ``TemplateResponse`` and ``SimpleTemplateResponse``
=========================================================

A :class:`TemplateResponse` object can be used anywhere that a normal
:class:`django.http.HttpResponse` can be used. It can also be used as an
alternative to calling :func:`~django.shortcuts.render()`.

For example, the following simple view returns a :class:`TemplateResponse`
with a simple template and a context containing a queryset::

    from django.template.response import TemplateResponse

    def blog_index(request):
        return TemplateResponse(request, 'entry_list.html', {'entries': Entry.objects.all()})

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Unicode (`大一小学期/Week_3-Python/exam/2016/docs/ref/unicode.txt`)

============
Unicode data
============

Django natively supports Unicode data everywhere. Providing your database can
somehow store the data, you can safely pass around Unicode strings to
templates, models and the database.

This document tells you what you need to know if you're writing applications
that use data or templates that are encoded in something other than ASCII.

Creating the database
=====================

Make sure your database is configured to be able to store arbitrary string
data. Normally, this means giving it an encoding of UTF-8 or UTF-16. If you use
a more restrictive encoding -- for example, latin1 (iso8859-1) -- you won't be
able to store certain characters in the database, and information will be lost.

* MySQL users, refer to the `MySQL manual`_ for details on how to set or alter
  the database character set encoding.

* PostgreSQL users, refer to the `PostgreSQL manual`_ (section 22.3.2 in
  PostgreSQL 9) for details on creating databases with the correct encoding.

* Oracle users, refer to the `Oracle manual`_ for details on how to set
  (`section 2`_) or alter (`section 11`_) the database character set encoding.

* SQLite users, there is nothing you need to do. SQLite always uses UTF-8
  for internal encoding.

.. _MySQL manual: https://dev.mysql.com/doc/refman/5.6/en/charset-database.html
.. _PostgreSQL manual: http://www.postgresql.org/docs/current/static/multibyte.html
.. _Oracle manual: https://docs.oracle.com/cd/E11882_01/server.112/e10729/toc.htm
.. _section 2: https://docs.oracle.com/cd/E11882_01/server.112/e10729/ch2charset.htm#NLSPG002
.. _section 11: https://docs.oracle.com/cd/E11882_01/server.112/e10729/ch11charsetmig.htm#NLSPG011

All of Django's database backends automatically convert Unicode strings into
the appropriate encoding for talking to the database. They also automatically
convert strings retrieved from the database into Python Unicode strings. You
don't even need to tell Django what encoding your database uses: that is
handled transparently.

For more, see the section "The database API" below.

General string handling
=======================

Whenever you use strings with Django -- e.g., in database lookups, template
rendering or anywhere else -- you have two choices for encoding those strings.
You can use Unicode strings, or you can use normal strings (sometimes called
"bytestrings") that are encoded using UTF-8.

In Python 3, the logic is reversed, that is normal strings are Unicode, and
when you want to specifically create a bytestring, you have to prefix the
string with a 'b'. As we are doing in Django code from version 1.5,
we recommend that you import ``unicode_literals`` from the __future__ library
in your code. Then, when you specifically want to create a bytestring literal,
prefix the string with 'b'.

Python 2 legacy::

    my_string = "This is a bytestring"
    my_unicode = u"This is an Unicode string"

Python 2 with unicode literals or Python 3::

    from __future__ import unicode_literals

    my_string = b"This is a bytestring"
    my_unicode = "This is an Unicode string"

See also :doc:`Python 3 compatibility </topics/python3>`.

.. warning::

    A bytestring does not carry any information with it about its encoding.
    For that reason, we have to make an assumption, and Django assumes that all
    bytestrings are in UTF-8.

    If you pass a string to Django that has been encoded in some other format,
    things will go wrong in interesting ways. Usually, Django will raise a
    ``UnicodeDecodeError`` at some point.

If your code only uses ASCII data, it's safe to use your normal strings,
passing them around at will, because ASCII is a subset of UTF-8.

Don't be fooled into thinking that if your :setting:`DEFAULT_CHARSET` setting is set
to something other than ``'utf-8'`` you can use that other encoding in your
bytestrings! :setting:`DEFAULT_CHARSET` only applies to the strings generated as
the result of template rendering (and email). Django will always assume UTF-8
encoding for internal bytestrings. The reason for this is that the
:setting:`DEFAULT_CHARSET` setting is not actually under your control (if you are the
application developer). It's under the control of the person installing and
using your application -- and if that person chooses a different setting, your
code must still continue to work. Ergo, it cannot rely on that setting.

In most cases when Django is dealing with strings, it will convert them to
Unicode strings before doing anything else. So, as a general rule, if you pass
in a bytestring, be prepared to receive a Unicode string back in the result.

Translated strings
------------------

Aside from Unicode strings and bytestrings, there's a third type of string-like
object you may encounter when using Django. The framework's
internationalization features introduce the concept of a "lazy translation" --
a string that has been marked as translated but whose actual translation result
isn't determined until the object is used in a string. This feature is useful
in cases where the translation locale is unknown until the string is used, even
though the string might have originally been created when the code was first
imported.

Normally, you won't have to worry about lazy translations. Just be aware that
if you examine an object and it claims to be a
``django.utils.functional.__proxy__`` object, it is a lazy translation.
Calling ``unicode()`` with the lazy translation as the argument will generate a
Unicode string in the current locale.

For more details about lazy translation objects, refer to the
:doc:`internationalization </topics/i18n/index>` documentation.

Useful utility functions
------------------------

Because some string operations come up again and again, Django ships with a few
useful functions that should make working with Unicode and bytestring objects
a bit easier.

Conversion functions
~~~~~~~~~~~~~~~~~~~~

The ``django.utils.encoding`` module contains a few functions that are handy
for converting back and forth between Unicode and bytestrings.

* ``smart_text(s, encoding='utf-8', strings_only=False, errors='strict')``
  converts its input to a Unicode string. The ``encoding`` parameter
  specifies the input encoding. (For example, Django uses this internally
  when processing form input data, which might not be UTF-8 encoded.) The
  ``strings_only`` parameter, if set to True, will result in Python
  numbers, booleans and ``None`` not being converted to a string (they keep
  their original types). The ``errors`` parameter takes any of the values
  that are accepted by Python's ``unicode()`` function for its error
  handling.

  If you pass ``smart_text()`` an object that has a ``__unicode__``
  method, it will use that method to do the conversion.

* ``force_text(s, encoding='utf-8', strings_only=False,
  errors='strict')`` is identical to ``smart_text()`` in almost all
  cases. The difference is when the first argument is a :ref:`lazy
  translation <lazy-translations>` instance. While ``smart_text()``
  preserves lazy translations, ``force_text()`` forces those objects to a
  Unicode string (causing the translation to occur). Normally, you'll want
  to use ``smart_text()``. However, ``force_text()`` is useful in
  template tags and filters that absolutely *must* have a string to work
  with, not just something that can be converted to a string.

* ``smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict')``
  is essentially the opposite of ``smart_text()``. It forces the first
  argument to a bytestring. The ``strings_only`` parameter has the same
  behavior as for ``smart_text()`` and ``force_text()``. This is
  slightly different semantics from Python's builtin ``str()`` function,
  but the difference is needed in a few places within Django's internals.

Normally, you'll only need to use ``smart_text()``. Call it as early as
possible on any input data that might be either Unicode or a bytestring, and
from then on, you can treat the result as always being Unicode.

.. _uri-and-iri-handling:

URI and IRI handling
~~~~~~~~~~~~~~~~~~~~

Web frameworks have to deal with URLs (which are a type of IRI_). One
requirement of URLs is that they are encoded using only ASCII characters.
However, in an international environment, you might need to construct a
URL from an IRI_ -- very loosely speaking, a URI_ that can contain Unicode
characters. Quoting and converting an IRI to URI can be a little tricky, so
Django provides some assistance.

* The function :func:`django.utils.encoding.iri_to_uri()` implements the
  conversion from IRI to URI as required by the specification (:rfc:`3987#section-3.1`).

* The functions :func:`django.utils.http.urlquote()` and
  :func:`django.utils.http.urlquote_plus()` are versions of Python's standard
  ``urllib.quote()`` and ``urllib.quote_plus()`` that work with non-ASCII
  characters. (The data is converted to UTF-8 prior to encoding.)

These two groups of functions have slightly different purposes, and it's
important to keep them straight. Normally, you would use ``urlquote()`` on the
individual portions of the IRI or URI path so that any reserved characters
such as '&' or '%' are correctly encoded. Then, you apply ``iri_to_uri()`` to
the full IRI and it converts any non-ASCII characters to the correct encoded
values.

.. note::
    Technically, it isn't correct to say that ``iri_to_uri()`` implements the
    full algorithm in the IRI specification. It doesn't (yet) perform the
    international domain name encoding portion of the algorithm.

The ``iri_to_uri()`` function will not change ASCII characters that are
otherwise permitted in a URL. So, for example, the character '%' is not
further encoded when passed to ``iri_to_uri()``. This means you can pass a
full URL to this function and it will not mess up the query string or anything
like that.

An example might clarify things here::

    >>> urlquote('Paris & Orléans')
    'Paris%20%26%20Orl%C3%A9ans'
    >>> iri_to_uri('/favorites/François/%s' % urlquote('Paris & Orléans'))
    '/favorites/Fran%C3%A7ois/Paris%20%26%20Orl%C3%A9ans'

If you look carefully, you can see that the portion that was generated by
``urlquote()`` in the second example was not double-quoted when passed to
``iri_to_uri()``. This is a very important and useful feature. It means that
you can construct your IRI without worrying about whether it contains
non-ASCII characters and then, right at the end, call ``iri_to_uri()`` on the
result.

Similarly, Django provides :func:`django.utils.encoding.uri_to_iri()` which
implements the conversion from URI to IRI as per :rfc:`3987#section-3.2`.
It decodes all percent-encodings except those that don't represent a valid
UTF-8 sequence.

An example to demonstrate::

    >>> uri_to_iri('/%E2%99%A5%E2%99%A5/?utf8=%E2%9C%93')
    '/♥♥/?utf8=✓'
    >>> uri_to_iri('%A9helloworld')
    '%A9helloworld'

In the first example, the UTF-8 characters and reserved characters are
unquoted. In the second, the percent-encoding remains unchanged because it
lies outside the valid UTF-8 range.

Both ``iri_to_uri()`` and ``uri_to_iri()`` functions are idempotent, which means the
following is always true::

    iri_to_uri(iri_to_uri(some_string)) == iri_to_uri(some_string)
    uri_to_iri(uri_to_iri(some_string)) == uri_to_iri(some_string)

So you can safely call it multiple times on the same URI/IRI without risking
double-quoting problems.

.. _URI: https://www.ietf.org/rfc/rfc2396.txt
.. _IRI: https://www.ietf.org/rfc/rfc3987.txt

Models
======

Because all strings are returned from the database as Unicode strings, model
fields that are character based (CharField, TextField, URLField, etc.) will
contain Unicode values when Django retrieves data from the database. This
is *always* the case, even if the data could fit into an ASCII bytestring.

You can pass in bytestrings when creating a model or populating a field, and
Django will convert it to Unicode when it needs to.

Choosing between ``__str__()`` and ``__unicode__()``
----------------------------------------------------

.. note::

    If you are on Python 3, you can skip this section because you'll always
    create ``__str__()`` rather than ``__unicode__()``. If you'd like
    compatibility with Python 2, you can decorate your model class with
    :func:`~django.utils.encoding.python_2_unicode_compatible`.

One consequence of using Unicode by default is that you have to take some care
when printing data from the model.

In particular, rather than giving your model a ``__str__()`` method, we
recommended you implement a ``__unicode__()`` method. In the ``__unicode__()``
method, you can quite safely return the values of all your fields without
having to worry about whether they fit into a bytestring or not. (The way
Python works, the result of ``__str__()`` is *always* a bytestring, even if you
accidentally try to return a Unicode object).

You can still create a ``__str__()`` method on your models if you want, of
course, but you shouldn't need to do this unless you have a good reason.
Django's ``Model`` base class automatically provides a ``__str__()``
implementation that calls ``__unicode__()`` and encodes the result into UTF-8.
This means you'll normally only need to implement a ``__unicode__()`` method
and let Django handle the coercion to a bytestring when required.

Taking care in ``get_absolute_url()``
-------------------------------------

URLs can only contain ASCII characters. If you're constructing a URL from
pieces of data that might be non-ASCII, be careful to encode the results in a
way that is suitable for a URL. The :func:`~django.urls.reverse` function
handles this for you automatically.

If you're constructing a URL manually (i.e., *not* using the ``reverse()``
function), you'll need to take care of the encoding yourself. In this case,
use the ``iri_to_uri()`` and ``urlquote()`` functions that were documented
above_. For example::

    from django.utils.encoding import iri_to_uri
    from django.utils.http import urlquote

    def get_absolute_url(self):
        url = '/person/%s/?x=0&y=0' % urlquote(self.location)
        return iri_to_uri(url)

This function returns a correctly encoded URL even if ``self.location`` is
something like "Jack visited Paris & Orléans". (In fact, the ``iri_to_uri()``
call isn't strictly necessary in the above example, because all the
non-ASCII characters would have been removed in quoting in the first line.)

.. _above: `URI and IRI handling`_

The database API
================

You can pass either Unicode strings or UTF-8 bytestrings as arguments to
``filter()`` methods and the like in the database API. The following two
querysets are identical::

    from __future__ import unicode_literals

    qs = People.objects.filter(name__contains='Å')
    qs = People.objects.filter(name__contains=b'\xc3\x85') # UTF-8 encoding of Å

Templates
=========

You can use either Unicode or bytestrings when creating templates manually::

    from __future__ import unicode_literals
    from django.template import Template
    t1 = Template(b'This is a bytestring template.')
    t2 = Template('This is a Unicode template.')

But the common case is to read templates from the filesystem, and this creates
a slight complication: not all filesystems store their data encoded as UTF-8.
If your template files are not stored with a UTF-8 encoding, set the :setting:`FILE_CHARSET`
setting to the encoding of the files on disk. When Django reads in a template
file, it will convert the data from this encoding to Unicode. (:setting:`FILE_CHARSET`
is set to ``'utf-8'`` by default.)

The :setting:`DEFAULT_CHARSET` setting controls the encoding of rendered templates.
This is set to UTF-8 by default.

Template tags and filters
-------------------------

A couple of tips to remember when writing your own template tags and filters:

* Always return Unicode strings from a template tag's ``render()`` method
  and from template filters.

* Use ``force_text()`` in preference to ``smart_text()`` in these
  places. Tag rendering and filter calls occur as the template is being
  rendered, so there is no advantage to postponing the conversion of lazy
  translation objects into strings. It's easier to work solely with Unicode
  strings at that point.

.. _unicode-files:

Files
=====

If you intend to allow users to upload files, you must ensure that the
environment used to run Django is configured to work with non-ASCII file names.
If your environment isn't configured correctly, you'll encounter
``UnicodeEncodeError`` exceptions when saving files with file names that
contain non-ASCII characters.

Filesystem support for UTF-8 file names varies and might depend on the
environment. Check your current configuration in an interactive Python shell by
running::

    import sys
    sys.getfilesystemencoding()

This should output "UTF-8".

The ``LANG`` environment variable is responsible for setting the expected
encoding on Unix platforms. Consult the documentation for your operating system
and application server for the appropriate syntax and location to set this
variable.

In your development environment, you might need to add a setting to your
``~.bashrc`` analogous to:::

    export LANG="en_US.UTF-8"

Email
=====

Django's email framework (in ``django.core.mail``) supports Unicode
transparently. You can use Unicode data in the message bodies and any headers.
However, you're still obligated to respect the requirements of the email
specifications, so, for example, email addresses should use only ASCII
characters.

The following code example demonstrates that everything except email addresses
can be non-ASCII::

    from __future__ import unicode_literals
    from django.core.mail import EmailMessage

    subject = 'My visit to Sør-Trøndelag'
    sender = 'Arnbjörg Ráðormsdóttir <arnbjorg@example.com>'
    recipients = ['Fred <fred@example.com']
    body = '...'
    msg = EmailMessage(subject, body, sender, recipients)
    msg.attach("Une pièce jointe.pdf", "%PDF-1.4.%...", mimetype="application/pdf")
    msg.send()

Form submission
===============

HTML form submission is a tricky area. There's no guarantee that the
submission will include encoding information, which means the framework might
have to guess at the encoding of submitted data.

Django adopts a "lazy" approach to decoding form data. The data in an
``HttpRequest`` object is only decoded when you access it. In fact, most of
the data is not decoded at all. Only the ``HttpRequest.GET`` and
``HttpRequest.POST`` data structures have any decoding applied to them. Those
two fields will return their members as Unicode data. All other attributes and
methods of ``HttpRequest`` return data exactly as it was submitted by the
client.

By default, the :setting:`DEFAULT_CHARSET` setting is used as the assumed encoding
for form data. If you need to change this for a particular form, you can set
the ``encoding`` attribute on an ``HttpRequest`` instance. For example::

    def some_view(request):
        # We know that the data must be encoded as KOI8-R (for some reason).
        request.encoding = 'koi8-r'
        ...

You can even change the encoding after having accessed ``request.GET`` or
``request.POST``, and all subsequent accesses will use the new encoding.

Most developers won't need to worry about changing form encoding, but this is
a useful feature for applications that talk to legacy systems whose encoding
you cannot control.

Django does not decode the data of file uploads, because that data is normally
treated as collections of bytes, rather than strings. Any automatic decoding
there would alter the meaning of the stream of bytes.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Urlresolvers (`大一小学期/Week_3-Python/exam/2016/docs/ref/urlresolvers.txt`)

=================================
``django.urls`` utility functions
=================================

.. module:: django.urls

.. deprecated:: 1.10

    In older versions, these functions are located in
    ``django.core.urlresolvers``. Importing from the old location will continue
    to work until Django 2.0.

``reverse()``
=============

If you need to use something similar to the :ttag:`url` template tag in
your code, Django provides the following function:

.. function:: reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)

``viewname`` can be a :ref:`URL pattern name <naming-url-patterns>` or the
callable view object. For example, given the following ``url``::

    from news import views

    url(r'^archive/$', views.archive, name='news-archive')

you can use any of the following to reverse the URL::

    # using the named URL
    reverse('news-archive')

    # passing a callable object
    # (This is discouraged because you can't reverse namespaced views this way.)
    from news import views
    reverse(views.archive)

If the URL accepts arguments, you may pass them in ``args``. For example::

    from django.urls import reverse

    def myview(request):
        return HttpResponseRedirect(reverse('arch-summary', args=[1945]))

You can also pass ``kwargs`` instead of ``args``. For example::

    >>> reverse('admin:app_list', kwargs={'app_label': 'auth'})
    '/admin/auth/'

``args`` and ``kwargs`` cannot be passed to ``reverse()`` at the same time.

If no match can be made, ``reverse()`` raises a
:class:`~django.urls.NoReverseMatch` exception.

The ``reverse()`` function can reverse a large variety of regular expression
patterns for URLs, but not every possible one. The main restriction at the
moment is that the pattern cannot contain alternative choices using the
vertical bar (``"|"``) character. You can quite happily use such patterns for
matching against incoming URLs and sending them off to views, but you cannot
reverse such patterns.

The ``current_app`` argument allows you to provide a hint to the resolver
indicating the application to which the currently executing view belongs.
This ``current_app`` argument is used as a hint to resolve application
namespaces into URLs on specific application instances, according to the
:ref:`namespaced URL resolution strategy <topics-http-reversing-url-namespaces>`.

The ``urlconf`` argument is the URLconf module containing the URL patterns to
use for reversing. By default, the root URLconf for the current thread is used.

.. note::

    The string returned by ``reverse()`` is already
    :ref:`urlquoted <uri-and-iri-handling>`. For example::

        >>> reverse('cities', args=['Orléans'])
        '.../Orl%C3%A9ans/'

    Applying further encoding (such as :meth:`~django.utils.http.urlquote` or
    ``urllib.quote``) to the output of ``reverse()`` may produce undesirable
    results.

``reverse_lazy()``
==================

A lazily evaluated version of `reverse()`_.

.. function:: reverse_lazy(viewname, urlconf=None, args=None, kwargs=None, current_app=None)

It is useful for when you need to use a URL reversal before your project's
URLConf is loaded. Some common cases where this function is necessary are:

* providing a reversed URL as the ``url`` attribute of a generic class-based
  view.

* providing a reversed URL to a decorator (such as the ``login_url`` argument
  for the :func:`django.contrib.auth.decorators.permission_required`
  decorator).

* providing a reversed URL as a default value for a parameter in a function's
  signature.

``resolve()``
=============

The ``resolve()`` function can be used for resolving URL paths to the
corresponding view functions. It has the following signature:

.. function:: resolve(path, urlconf=None)

``path`` is the URL path you want to resolve. As with
:func:`~django.urls.reverse`, you don't need to worry about the ``urlconf``
parameter. The function returns a :class:`ResolverMatch` object that allows you
to access various metadata about the resolved URL.

If the URL does not resolve, the function raises a
:exc:`~django.urls.Resolver404` exception (a subclass of
:class:`~django.http.Http404`) .

.. class:: ResolverMatch

    .. attribute:: ResolverMatch.func

        The view function that would be used to serve the URL

    .. attribute:: ResolverMatch.args

        The arguments that would be passed to the view function, as
        parsed from the URL.

    .. attribute:: ResolverMatch.kwargs

        The keyword arguments that would be passed to the view
        function, as parsed from the URL.

    .. attribute:: ResolverMatch.url_name

        The name of the URL pattern that matches the URL.

    .. attribute:: ResolverMatch.app_name

        The application namespace for the URL pattern that matches the
        URL.

    .. attribute:: ResolverMatch.app_names

        .. versionadded:: 1.9

        The list of individual namespace components in the full
        application namespace for the URL pattern that matches the URL.
        For example, if the ``app_name`` is ``'foo:bar'``, then ``app_names``
        will be ``['foo', 'bar']``.

    .. attribute:: ResolverMatch.namespace

        The instance namespace for the URL pattern that matches the
        URL.

    .. attribute:: ResolverMatch.namespaces

        The list of individual namespace components in the full
        instance namespace for the URL pattern that matches the URL.
        i.e., if the namespace is ``foo:bar``, then namespaces will be
        ``['foo', 'bar']``.

    .. attribute:: ResolverMatch.view_name

        The name of the view that matches the URL, including the namespace if
        there is one.

A :class:`ResolverMatch` object can then be interrogated to provide
information about the URL pattern that matches a URL::

    # Resolve a URL
    match = resolve('/some/path/')
    # Print the URL pattern that matches the URL
    print(match.url_name)

A :class:`ResolverMatch` object can also be assigned to a triple::

    func, args, kwargs = resolve('/some/path/')

One possible use of :func:`~django.urls.resolve` would be to test whether a
view would raise a ``Http404`` error before redirecting to it::

    from django.urls import resolve
    from django.http import HttpResponseRedirect, Http404
    from django.utils.six.moves.urllib.parse import urlparse

    def myview(request):
        next = request.META.get('HTTP_REFERER', None) or '/'
        response = HttpResponseRedirect(next)

        # modify the request and response as required, e.g. change locale
        # and set corresponding locale cookie

        view, args, kwargs = resolve(urlparse(next)[2])
        kwargs['request'] = request
        try:
            view(*args, **kwargs)
        except Http404:
            return HttpResponseRedirect('/')
        return response

``get_script_prefix()``
=======================

.. function:: get_script_prefix()

Normally, you should always use :func:`~django.urls.reverse` to define URLs
within your application. However, if your application constructs part of the
URL hierarchy itself, you may occasionally need to generate URLs. In that
case, you need to be able to find the base URL of the Django project within
its Web server (normally, :func:`~django.urls.reverse` takes care of this for
you). In that case, you can call ``get_script_prefix()``, which will return
the script prefix portion of the URL for your Django project. If your Django
project is at the root of its web server, this is always ``"/"``.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Urls (`大一小学期/Week_3-Python/exam/2016/docs/ref/urls.txt`)

======================================
``django.conf.urls`` utility functions
======================================

.. module:: django.conf.urls

``static()``
============

.. function:: static.static(prefix, view=django.views.static.serve, **kwargs)

Helper function to return a URL pattern for serving files in debug mode::

    from django.conf import settings
    from django.conf.urls.static import static

    urlpatterns = [
        # ... the rest of your URLconf goes here ...
    ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

``url()``
=========

.. function:: url(regex, view, kwargs=None, name=None)

``urlpatterns`` should be a list of ``url()`` instances. For example::

    from django.conf.urls import include, url

    urlpatterns = [
        url(r'^index/$', index_view, name='main-view'),
        url(r'^weblog/', include('blog.urls')),
        ...
    ]

The ``view`` parameter is a view function or the result of
:meth:`~django.views.generic.base.View.as_view` for class-based views. It can
also be an :func:`include`.

The ``kwargs`` parameter allows you to pass additional arguments to the view
function or method. See :ref:`views-extra-options` for an example.

See :ref:`Naming URL patterns <naming-url-patterns>` for why the ``name``
parameter is useful.

``include()``
=============

.. function:: include(module, namespace=None, app_name=None)
              include(pattern_list)
              include((pattern_list, app_namespace), namespace=None)
              include((pattern_list, app_namespace, instance_namespace))

    A function that takes a full Python import path to another URLconf module
    that should be "included" in this place. Optionally, the :term:`application
    namespace` and :term:`instance namespace` where the entries will be included
    into can also be specified.

    Usually, the application namespace should be specified by the included
    module. If an application namespace is set, the ``namespace`` argument
    can be used to set a different instance namespace.

    ``include()`` also accepts as an argument either an iterable that returns
    URL patterns, a 2-tuple containing such iterable plus the names of the
    application namespaces, or a 3-tuple containing the iterable and the names
    of both the application and instance namespace.

    :arg module: URLconf module (or module name)
    :arg namespace: Instance namespace for the URL entries being included
    :type namespace: string
    :arg app_name: Application namespace for the URL entries being included
    :type app_name: string
    :arg pattern_list: Iterable of :func:`django.conf.urls.url` instances
    :arg app_namespace: Application namespace for the URL entries being included
    :type app_namespace: string
    :arg instance_namespace: Instance namespace for the URL entries being included
    :type instance_namespace: string

See :ref:`including-other-urlconfs` and :ref:`namespaces-and-include`.

.. deprecated:: 1.9

    Support for the ``app_name`` argument is deprecated and will be removed in
    Django 2.0. Specify the ``app_name`` as explained in
    :ref:`namespaces-and-include` instead.

    Support for passing a 3-tuple is also deprecated and will be removed in
    Django 2.0. Pass a 2-tuple containing the pattern list and application
    namespace, and use the ``namespace`` argument instead.

    Lastly, support for an instance namespace without an application namespace
    has been deprecated and will be removed in Django 2.0. Specify the
    application namespace or remove the instance namespace.

``handler400``
==============

.. data:: handler400

A callable, or a string representing the full Python import path to the view
that should be called if the HTTP client has sent a request that caused an error
condition and a response with a status code of 400.

By default, this is ``'django.views.defaults.bad_request'``. If you
implement a custom view, be sure it returns an
:class:`~django.http.HttpResponseBadRequest`.

See the documentation about :ref:`the 400 (bad request) view
<http_bad_request_view>` for more information.

``handler403``
==============

.. data:: handler403

A callable, or a string representing the full Python import path to the view
that should be called if the user doesn't have the permissions required to
access a resource.

By default, this is ``'django.views.defaults.permission_denied'``. If you
implement a custom view, be sure it returns an
:class:`~django.http.HttpResponseForbidden`.

See the documentation about :ref:`the 403 (HTTP Forbidden) view
<http_forbidden_view>` for more information.

``handler404``
==============

.. data:: handler404

A callable, or a string representing the full Python import path to the view
that should be called if none of the URL patterns match.

By default, this is ``'django.views.defaults.page_not_found'``. If you
implement a custom view, be sure it returns an
:class:`~django.http.HttpResponseNotFound`.

See the documentation about :ref:`the 404 (HTTP Not Found) view
<http_not_found_view>` for more information.

``handler500``
==============

.. data:: handler500

A callable, or a string representing the full Python import path to the view
that should be called in case of server errors. Server errors happen when you
have runtime errors in view code.

By default, this is ``'django.views.defaults.server_error'``. If you
implement a custom view, be sure it returns an
:class:`~django.http.HttpResponseServerError`.

See the documentation about :ref:`the 500 (HTTP Internal Server Error) view
<http_internal_server_error_view>` for more information.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Utils (`大一小学期/Week_3-Python/exam/2016/docs/ref/utils.txt`)

============
Django Utils
============

.. module:: django.utils
   :synopsis: Django's built-in utilities.

This document covers all stable modules in ``django.utils``. Most of the
modules in ``django.utils`` are designed for internal use and only the
following parts can be considered stable and thus backwards compatible as per
the :ref:`internal release deprecation policy <internal-release-deprecation-policy>`.

``django.utils.cache``
======================

.. module:: django.utils.cache
   :synopsis: Helper functions for controlling caching.

This module contains helper functions for controlling caching. It does so by
managing the ``Vary`` header of responses. It includes functions to patch the
header of response objects directly and decorators that change functions to do
that header-patching themselves.

For information on the ``Vary`` header, see :rfc:`7231#section-7.1.4`.

Essentially, the ``Vary`` HTTP header defines which headers a cache should take
into account when building its cache key. Requests with the same path but
different header content for headers named in ``Vary`` need to get different
cache keys to prevent delivery of wrong content.

For example, :doc:`internationalization </topics/i18n/index>` middleware would
need to distinguish caches by the ``Accept-language`` header.

.. function:: patch_cache_control(response, **kwargs)

    This function patches the ``Cache-Control`` header by adding all keyword
    arguments to it. The transformation is as follows:

    * All keyword parameter names are turned to lowercase, and underscores
      are converted to hyphens.
    * If the value of a parameter is ``True`` (exactly ``True``, not just a
      true value), only the parameter name is added to the header.
    * All other parameters are added with their value, after applying
      ``str()`` to it.

.. function:: get_max_age(response)

    Returns the max-age from the response Cache-Control header as an integer
    (or ``None`` if it wasn't found or wasn't an integer).

.. function:: patch_response_headers(response, cache_timeout=None)

    Adds some useful headers to the given ``HttpResponse`` object:

    * ``ETag``
    * ``Last-Modified``
    * ``Expires``
    * ``Cache-Control``

    Each header is only added if it isn't already set.

    ``cache_timeout`` is in seconds. The :setting:`CACHE_MIDDLEWARE_SECONDS`
    setting is used by default.

.. function:: add_never_cache_headers(response)

    Adds a ``Cache-Control: max-age=0, no-cache, no-store, must-revalidate``
    header to a response to indicate that a page should never be cached.

    .. versionchanged:: 1.8.8

        In older versions, ``Cache-Control: max-age=0`` was sent. This didn't
        reliably prevent caching in all browsers.

.. function:: patch_vary_headers(response, newheaders)

    Adds (or updates) the ``Vary`` header in the given ``HttpResponse`` object.
    ``newheaders`` is a list of header names that should be in ``Vary``.
    Existing headers in ``Vary`` aren't removed.

.. function:: get_cache_key(request, key_prefix=None)

    Returns a cache key based on the request path. It can be used in the
    request phase because it pulls the list of headers to take into account
    from the global path registry and uses those to build a cache key to
    check against.

    If there is no headerlist stored, the page needs to be rebuilt, so this
    function returns ``None``.

.. function:: learn_cache_key(request, response, cache_timeout=None, key_prefix=None)

    Learns what headers to take into account for some request path from the
    response object. It stores those headers in a global path registry so that
    later access to that path will know what headers to take into account
    without building the response object itself. The headers are named in
    the ``Vary`` header of the response, but we want to prevent response
    generation.

    The list of headers to use for cache key generation is stored in the same
    cache as the pages themselves. If the cache ages some data out of the
    cache, this just means that we have to build the response once to get at
    the Vary header and so at the list of headers to use for the cache key.

``django.utils.dateparse``
==========================

.. module:: django.utils.dateparse
   :synopsis: Functions to parse datetime objects.

The functions defined in this module share the following properties:

- They raise :exc:`ValueError` if their input is well formatted but isn't a
  valid date or time.
- They return ``None`` if it isn't well formatted at all.
- They accept up to picosecond resolution in input, but they truncate it to
  microseconds, since that's what Python supports.

.. function:: parse_date(value)

    Parses a string and returns a :class:`datetime.date`.

.. function:: parse_time(value)

    Parses a string and returns a :class:`datetime.time`.

    UTC offsets aren't supported; if ``value`` describes one, the result is
    ``None``.

.. function:: parse_datetime(value)

    Parses a string and returns a :class:`datetime.datetime`.

    UTC offsets are supported; if ``value`` describes one, the result's
    ``tzinfo`` attribute is a :class:`~django.utils.timezone.FixedOffset`
    instance.

.. function:: parse_duration(value)

    Parses a string and returns a :class:`datetime.timedelta`.

    Expects data in the format ``"DD HH:MM:SS.uuuuuu"`` or as specified by ISO
    8601 (e.g. ``P4DT1H15M20S`` which is equivalent to ``4 1:15:20``).

``django.utils.decorators``
===========================

.. module:: django.utils.decorators
    :synopsis: Functions that help with creating decorators for views.

.. function:: method_decorator(decorator, name='')

    Converts a function decorator into a method decorator. It can be used to
    decorate methods or classes; in the latter case, ``name`` is the name
    of the method to be decorated and is required.

    ``decorator`` may also be a list or tuple of functions. They are wrapped
    in reverse order so that the call order is the order in which the functions
    appear in the list/tuple.

    See :ref:`decorating class based views <decorating-class-based-views>` for
    example usage.

    .. versionchanged:: 1.9

       The ability to decorate classes, the ``name`` parameter, and the ability
       for ``decorator`` to accept a list/tuple of decorator functions were
       added.

.. function:: decorator_from_middleware(middleware_class)

    Given a middleware class, returns a view decorator. This lets you use
    middleware functionality on a per-view basis. The middleware is created
    with no params passed.

    It assumes middleware that's compatible with the old style of Django 1.9
    and earlier (having methods like ``process_request()``,
    ``process_exception()``, and ``process_response()``).

.. function:: decorator_from_middleware_with_args(middleware_class)

    Like ``decorator_from_middleware``, but returns a function
    that accepts the arguments to be passed to the middleware_class.
    For example, the :func:`~django.views.decorators.cache.cache_page`
    decorator is created from the ``CacheMiddleware`` like this::

         cache_page = decorator_from_middleware_with_args(CacheMiddleware)

         @cache_page(3600)
         def my_view(request):
             pass

``django.utils.encoding``
=========================

.. module:: django.utils.encoding
   :synopsis: A series of helper functions to manage character encoding.

.. function:: python_2_unicode_compatible

    A decorator that defines ``__unicode__`` and ``__str__`` methods under
    Python 2. Under Python 3 it does nothing.

    To support Python 2 and 3 with a single code base, define a ``__str__``
    method returning text and apply this decorator to the class.

.. function:: smart_text(s, encoding='utf-8', strings_only=False, errors='strict')

    Returns a text object representing ``s`` -- ``unicode`` on Python 2 and
    ``str`` on Python 3. Treats bytestrings using the ``encoding`` codec.

    If ``strings_only`` is ``True``, don't convert (some) non-string-like
    objects.

.. function:: smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict')

    Historical name of :func:`smart_text`. Only available under Python 2.

.. function:: is_protected_type(obj)

    Determine if the object instance is of a protected type.

    Objects of protected types are preserved as-is when passed to
    ``force_text(strings_only=True)``.

.. function:: force_text(s, encoding='utf-8', strings_only=False, errors='strict')

    Similar to ``smart_text``, except that lazy instances are resolved to
    strings, rather than kept as lazy objects.

    If ``strings_only`` is ``True``, don't convert (some) non-string-like
    objects.

.. function:: force_unicode(s, encoding='utf-8', strings_only=False, errors='strict')

    Historical name of :func:`force_text`. Only available under Python 2.

.. function:: smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict')

    Returns a bytestring version of ``s``, encoded as specified in
    ``encoding``.

    If ``strings_only`` is ``True``, don't convert (some) non-string-like
    objects.

.. function:: force_bytes(s, encoding='utf-8', strings_only=False, errors='strict')

    Similar to ``smart_bytes``, except that lazy instances are resolved to
    bytestrings, rather than kept as lazy objects.

    If ``strings_only`` is ``True``, don't convert (some) non-string-like
    objects.

.. function:: smart_str(s, encoding='utf-8', strings_only=False, errors='strict')

    Alias of :func:`smart_bytes` on Python 2 and :func:`smart_text` on Python
    3. This function returns a ``str`` or a lazy string.

    For instance, this is  suitable for writing to :data:`sys.stdout` on
    Python 2 and 3.

.. function:: force_str(s, encoding='utf-8', strings_only=False, errors='strict')

    Alias of :func:`force_bytes` on Python 2 and :func:`force_text` on Python
    3. This function always returns a ``str``.

.. function:: iri_to_uri(iri)

    Convert an Internationalized Resource Identifier (IRI) portion to a URI
    portion that is suitable for inclusion in a URL.

    This is the algorithm from section 3.1 of :rfc:`3987#section-3.1`. However,
    since we are assuming input is either UTF-8 or unicode already, we can
    simplify things a little from the full method.

    Takes an IRI in UTF-8 bytes and returns ASCII bytes containing the encoded
    result.

.. function:: uri_to_iri(uri)

    Converts a Uniform Resource Identifier into an Internationalized Resource
    Identifier.

    This is an algorithm from section 3.2 of :rfc:`3987#section-3.2`.

    Takes a URI in ASCII bytes and returns a unicode string containing the
    encoded result.

.. function:: filepath_to_uri(path)

    Convert a file system path to a URI portion that is suitable for inclusion
    in a URL. The path is assumed to be either UTF-8 or unicode.

    This method will encode certain characters that would normally be
    recognized as special characters for URIs.  Note that this method does not
    encode the ' character, as it is a valid character within URIs. See
    ``encodeURIComponent()`` JavaScript function for more details.

    Returns an ASCII string containing the encoded result.

.. function:: escape_uri_path(path)

    Escapes the unsafe characters from the path portion of a Uniform Resource
    Identifier (URI).

``django.utils.feedgenerator``
==============================

.. module:: django.utils.feedgenerator
   :synopsis: Syndication feed generation library -- used for generating RSS, etc.

Sample usage::

    >>> from django.utils import feedgenerator
    >>> feed = feedgenerator.Rss201rev2Feed(
    ...     title="Poynter E-Media Tidbits",
    ...     link="http://www.poynter.org/column.asp?id=31",
    ...     description="A group Weblog by the sharpest minds in online media/journalism/publishing.",
    ...     language="en",
    ... )
    >>> feed.add_item(
    ...     title="Hello",
    ...     link="http://www.holovaty.com/test/",
    ...     description="Testing.",
    ... )
    >>> with open('test.rss', 'w') as fp:
    ...     feed.write(fp, 'utf-8')

For simplifying the selection of a generator use ``feedgenerator.DefaultFeed``
which is currently ``Rss201rev2Feed``

For definitions of the different versions of RSS, see:
https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004/02/04/incompatible-rss

.. function:: get_tag_uri(url, date)

    Creates a TagURI.

    See https://web.archive.org/web/20110514113830/http://diveintomark.org/archives/2004/05/28/howto-atom-id

``SyndicationFeed``
-------------------

.. class:: SyndicationFeed

    Base class for all syndication feeds. Subclasses should provide write().

    .. method:: __init__(title, link, description, language=None, author_email=None, author_name=None, author_link=None, subtitle=None, categories=None, feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, **kwargs)

        Initialize the feed with the given dictionary of metadata, which applies
        to the entire feed.

        Any extra keyword arguments you pass to ``__init__`` will be stored in
        ``self.feed``.

        All parameters should be Unicode objects, except ``categories``, which
        should be a sequence of Unicode objects.

    .. method:: add_item(title, link, description, author_email=None, author_name=None, author_link=None, pubdate=None, comments=None, unique_id=None, enclosure=None, categories=(), item_copyright=None, ttl=None, updateddate=None, enclosures=None, **kwargs)

        Adds an item to the feed. All args are expected to be Python ``unicode``
        objects except ``pubdate`` and ``updateddate``, which are ``datetime.datetime``
        objects, ``enclosure``, which is an ``Enclosure`` instance, and
        ``enclosures``, which is a list of ``Enclosure`` instances.

        .. deprecated:: 1.9

            The ``enclosure`` keyword argument is deprecated in favor of the
            new ``enclosures`` keyword argument which accepts a list of
            ``Enclosure`` objects.

    .. method:: num_items()

    .. method:: root_attributes()

        Return extra attributes to place on the root (i.e. feed/channel)
        element. Called from ``write()``.

    .. method:: add_root_elements(handler)

        Add elements in the root (i.e. feed/channel) element.
        Called from ``write()``.

    .. method:: item_attributes(item)

        Return extra attributes to place on each item (i.e. item/entry)
        element.

    .. method:: add_item_elements(handler, item)

        Add elements on each item (i.e. item/entry) element.

    .. method:: write(outfile, encoding)

        Outputs the feed in the given encoding to ``outfile``, which is a
        file-like object. Subclasses should override this.

    .. method:: writeString(encoding)

        Returns the feed in the given encoding as a string.

    .. method:: latest_post_date()

        Returns the latest ``pubdate`` or ``updateddate`` for all items in the
        feed. If no items have either of these attributes this returns the
        current date/time.

``Enclosure``
-------------

.. class:: Enclosure

    Represents an RSS enclosure

``RssFeed``
-----------

.. class:: RssFeed(SyndicationFeed)

``Rss201rev2Feed``
------------------

.. class:: Rss201rev2Feed(RssFeed)

    Spec: https://cyber.law.harvard.edu/rss/rss.html

``RssUserland091Feed``
----------------------

.. class:: RssUserland091Feed(RssFeed)

    Spec: http://backend.userland.com/rss091

``Atom1Feed``
-------------

.. class:: Atom1Feed(SyndicationFeed)

    Spec: https://tools.ietf.org/html/rfc4287

``django.utils.functional``
===========================

.. module:: django.utils.functional
    :synopsis: Functional programming tools.

.. class:: cached_property(object, name)

    The ``@cached_property`` decorator caches the result of a method with a
    single ``self`` argument as a property. The cached result will persist
    as long as the instance does, so if the instance is passed around and the
    function subsequently invoked, the cached result will be returned.

    Consider a typical case, where a view might need to call a model's method
    to perform some computation, before placing the model instance into the
    context, where the template might invoke the method once more::

        # the model
        class Person(models.Model):

            def friends(self):
                # expensive computation
                ...
                return friends

        # in the view:
        if person.friends():
            ...

    And in the template you would have:

    .. code-block:: html+django

        {% for friend in person.friends %}

    Here, ``friends()`` will be called twice. Since the instance ``person`` in
    the view and the template are the same, ``@cached_property`` can avoid
    that::

        from django.utils.functional import cached_property

        @cached_property
        def friends(self):
            # expensive computation
            ...
            return friends

    Note that as the method is now a property, in Python code it will need to
    be invoked appropriately::

        # in the view:
        if person.friends:
            ...

    The cached value can be treated like an ordinary attribute of the instance::

        # clear it, requiring re-computation next time it's called
        del person.friends # or delattr(person, "friends")

        # set a value manually, that will persist on the instance until cleared
        person.friends = ["Huckleberry Finn", "Tom Sawyer"]

    As well as offering potential performance advantages, ``@cached_property``
    can ensure that an attribute's value does not change unexpectedly over the
    life of an instance. This could occur with a method whose computation is
    based on ``datetime.now()``, or simply if a change were saved to the
    database by some other process in the brief interval between subsequent
    invocations of a method on the same instance.

    You can use the ``name`` argument to make cached properties of other
    methods. For example, if you had an expensive ``get_friends()`` method and
    wanted to allow calling it without retrieving the cached value, you could
    write::

        friends = cached_property(get_friends, name='friends')

    While ``person.get_friends()`` will recompute the friends on each call, the
    value of the cached property will persist until you delete it as described
    above::

        x = person.friends         # calls first time
        y = person.get_friends()   # calls again
        z = person.friends         # does not call
        x is z                     # is True

.. function:: allow_lazy(func, *resultclasses)

    .. deprecated:: 1.10

    Works like :meth:`~django.utils.functional.keep_lazy` except that it can't
    be used as a decorator.

.. function:: keep_lazy(func, *resultclasses)

    .. versionadded:: 1.10

    Django offers many utility functions (particularly in ``django.utils``)
    that take a string as their first argument and do something to that string.
    These functions are used by template filters as well as directly in other
    code.

    If you write your own similar functions and deal with translations, you'll
    face the problem of what to do when the first argument is a lazy
    translation object. You don't want to convert it to a string immediately,
    because you might be using this function outside of a view (and hence the
    current thread's locale setting will not be correct).

    For cases like this, use the ``django.utils.functional.keep_lazy()``
    decorator. It modifies the function so that *if* it's called with a lazy
    translation as one of its arguments, the function evaluation is delayed
    until it needs to be converted to a string.

    For example::

        from django.utils import six
        from django.utils.functional import keep_lazy, keep_lazy_text

        def fancy_utility_function(s, ...):
            # Do some conversion on string 's'
            ...
        fancy_utility_function = keep_lazy(six.text_type)(fancy_utility_function)

        # Or more succinctly:
        @keep_lazy(six.text_type)
        def fancy_utility_function(s, ...):
            ...

    The ``keep_lazy()`` decorator takes a number of extra arguments (``*args``)
    specifying the type(s) that the original function can return. A common
    use case is to have functions that return text. For these, you can just
    pass the ``six.text_type`` type to ``keep_lazy`` (or even simpler, use the
    :func:`keep_lazy_text` decorator described in the next section).

    Using this decorator means you can write your function and assume that the
    input is a proper string, then add support for lazy translation objects at
    the end.

.. function:: keep_lazy_text(func)

    .. versionadded:: 1.10

    A shortcut for ``keep_lazy(six.text_type)(func)``.

    If you have a function that returns text and you want to be able to take
    lazy arguments while delaying their evaluation, simply use this decorator::

        from django.utils import six
        from django.utils.functional import keep_lazy, keep_lazy_text

        # Our previous example was:
        @keep_lazy(six.text_type)
        def fancy_utility_function(s, ...):
            ...

        # Which can be rewritten as:
        @keep_lazy_text
        def fancy_utility_function(s, ...):
            ...

``django.utils.html``
=====================

.. module:: django.utils.html
   :synopsis: HTML helper functions

Usually you should build up HTML using Django's templates to make use of its
autoescape mechanism, using the utilities in :mod:`django.utils.safestring`
where appropriate. This module provides some additional low level utilities for
escaping HTML.

.. function:: escape(text)

    Returns the given text with ampersands, quotes and angle brackets encoded
    for use in HTML. The input is first passed through
    :func:`~django.utils.encoding.force_text` and the output has
    :func:`~django.utils.safestring.mark_safe` applied.

.. function:: conditional_escape(text)

    Similar to ``escape()``, except that it doesn't operate on pre-escaped
    strings, so it will not double escape.

.. function:: format_html(format_string, *args, **kwargs)

    This is similar to :meth:`str.format`, except that it is appropriate for
    building up HTML fragments. All args and kwargs are passed through
    :func:`conditional_escape` before being passed to ``str.format()``.

    For the case of building up small HTML fragments, this function is to be
    preferred over string interpolation using ``%`` or ``str.format()``
    directly, because it applies escaping to all arguments - just like the
    template system applies escaping by default.

    So, instead of writing::

        mark_safe("%s <b>%s</b> %s" % (
            some_html,
            escape(some_text),
            escape(some_other_text),
        ))

    You should instead use::

        format_html("{} <b>{}</b> {}",
            mark_safe(some_html),
            some_text,
            some_other_text,
        )

    This has the advantage that you don't need to apply :func:`escape` to each
    argument and risk a bug and an XSS vulnerability if you forget one.

    Note that although this function uses ``str.format()`` to do the
    interpolation, some of the formatting options provided by ``str.format()``
    (e.g. number formatting) will not work, since all arguments are passed
    through :func:`conditional_escape` which (ultimately) calls
    :func:`~django.utils.encoding.force_text` on the values.

.. function:: format_html_join(sep, format_string, args_generator)

    A wrapper of :func:`format_html`, for the common case of a group of
    arguments that need to be formatted using the same format string, and then
    joined using ``sep``. ``sep`` is also passed through
    :func:`conditional_escape`.

    ``args_generator`` should be an iterator that returns the sequence of
    ``args`` that will be passed to :func:`format_html`. For example::

        format_html_join(
            '\n', "<li>{} {}</li>",
            ((u.first_name, u.last_name) for u in users)
        )

.. function:: strip_tags(value)

    Tries to remove anything that looks like an HTML tag from the string, that
    is anything contained within ``<>``.

    Absolutely NO guarantee is provided about the resulting string being
    HTML safe. So NEVER mark safe the result of a ``strip_tag`` call without
    escaping it first, for example with :func:`~django.utils.html.escape`.

    For example::

        strip_tags(value)

    If ``value`` is ``"<b>Joel</b> <button>is</button> a <span>slug</span>"``
    the return value will be ``"Joel is a slug"``.

    If you are looking for a more robust solution, take a look at the `bleach
    <https://pypi.python.org/pypi/bleach>`_ Python library.

.. function:: html_safe()

    The ``__html__()`` method on a class helps non-Django templates detect
    classes whose output doesn't require HTML escaping.

    This decorator defines the ``__html__()`` method on the decorated class
    by wrapping the ``__unicode__()`` (Python 2) or ``__str__()`` (Python 3)
    in :meth:`~django.utils.safestring.mark_safe`. Ensure the ``__unicode__()``
    or ``__str__()`` method does indeed return text that doesn't require HTML
    escaping.


``django.utils.http``
=====================

.. module:: django.utils.http
   :synopsis: HTTP helper functions. (URL encoding, cookie handling, ...)

.. function:: urlquote(url, safe='/')

    A version of Python's ``urllib.quote()`` function that can operate on
    unicode strings. The url is first UTF-8 encoded before quoting. The
    returned string can safely be used as part of an argument to a subsequent
    ``iri_to_uri()`` call without double-quoting occurring. Employs lazy
    execution.

.. function:: urlquote_plus(url, safe='')

    A version of Python's urllib.quote_plus() function that can operate on
    unicode strings. The url is first UTF-8 encoded before quoting. The
    returned string can safely be used as part of an argument to a subsequent
    ``iri_to_uri()`` call without double-quoting occurring. Employs lazy
    execution.

.. function:: urlencode(query, doseq=0)

    A version of Python's urllib.urlencode() function that can operate on
    unicode strings. The parameters are first cast to UTF-8 encoded strings
    and then encoded as per normal.

.. function:: cookie_date(epoch_seconds=None)

    Formats the time to ensure compatibility with Netscape's cookie standard.

    Accepts a floating point number expressed in seconds since the epoch in
    UTC--such as that outputted by ``time.time()``. If set to ``None``,
    defaults to the current time.

    Outputs a string in the format ``Wdy, DD-Mon-YYYY HH:MM:SS GMT``.

.. function:: http_date(epoch_seconds=None)

    Formats the time to match the :rfc:`1123` date format as specified by HTTP
    :rfc:`7231#section-7.1.1.1`.

    Accepts a floating point number expressed in seconds since the epoch in
    UTC--such as that outputted by ``time.time()``. If set to ``None``,
    defaults to the current time.

    Outputs a string in the format ``Wdy, DD Mon YYYY HH:MM:SS GMT``.

.. function:: base36_to_int(s)

    Converts a base 36 string to an integer. On Python 2 the output is
    guaranteed to be an ``int`` and not a ``long``.

.. function:: int_to_base36(i)

    Converts a positive integer to a base 36 string. On Python 2 ``i`` must be
    smaller than `sys.maxint`_.

    .. _sys.maxint: https://docs.python.org/2/library/sys.html#sys.maxint

.. function:: urlsafe_base64_encode(s)

    Encodes a bytestring in base64 for use in URLs, stripping any trailing
    equal signs.

.. function::  urlsafe_base64_decode(s)

    Decodes a base64 encoded string, adding back any trailing equal signs that
    might have been stripped.

``django.utils.module_loading``
===============================

.. module:: django.utils.module_loading
   :synopsis: Functions for working with Python modules.

Functions for working with Python modules.

.. function:: import_string(dotted_path)

    Imports a dotted module path and returns the attribute/class designated by
    the last name in the path. Raises ``ImportError`` if the import failed. For
    example::

        from django.utils.module_loading import import_string
        ValidationError = import_string('django.core.exceptions.ValidationError')

    is equivalent to::

        from django.core.exceptions import ValidationError

``django.utils.safestring``
===========================

.. module:: django.utils.safestring
   :synopsis: Functions and classes for working with strings that can be displayed safely without further escaping in HTML.

Functions and classes for working with "safe strings": strings that can be
displayed safely without further escaping in HTML. Marking something as a "safe
string" means that the producer of the string has already turned characters
that should not be interpreted by the HTML engine (e.g. '<') into the
appropriate entities.

.. class:: SafeBytes

    A ``bytes`` subclass that has been specifically marked as "safe"
    (requires no further escaping) for HTML output purposes.

.. class:: SafeString

    A ``str`` subclass that has been specifically marked as "safe"
    (requires no further escaping) for HTML output purposes. This is
    :class:`SafeBytes` on Python 2 and :class:`SafeText` on Python 3.

.. class:: SafeText

    A ``str`` (in Python 3) or ``unicode`` (in Python 2) subclass
    that has been specifically marked as "safe" for HTML output purposes.

.. class:: SafeUnicode

    Historical name of :class:`SafeText`. Only available under Python 2.

.. function:: mark_safe(s)

    Explicitly mark a string as safe for (HTML) output purposes. The returned
    object can be used everywhere a string or unicode object is appropriate.

    Can be called multiple times on a single string.

    For building up fragments of HTML, you should normally be using
    :func:`django.utils.html.format_html` instead.

    String marked safe will become unsafe again if modified. For example::

        >>> mystr = '<b>Hello World</b>   '
        >>> mystr = mark_safe(mystr)
        >>> type(mystr)
        <class 'django.utils.safestring.SafeBytes'>

        >>> mystr = mystr.strip()  # removing whitespace
        >>> type(mystr)
        <type 'str'>

.. function:: mark_for_escaping(s)

    .. deprecated:: 1.10

    Explicitly mark a string as requiring HTML escaping upon output. Has no
    effect on ``SafeData`` subclasses.

    Can be called multiple times on a single string (the resulting escaping is
    only applied once).

``django.utils.text``
=====================

.. module:: django.utils.text
    :synopsis: Text manipulation.

.. function:: slugify(allow_unicode=False)

    Converts to ASCII if ``allow_unicode`` is ``False`` (default). Converts spaces to
    hyphens. Removes characters that aren't alphanumerics, underscores, or
    hyphens. Converts to lowercase. Also strips leading and trailing whitespace.

    For example::

        slugify(value)

    If ``value`` is ``"Joel is a slug"``, the output will be
    ``"joel-is-a-slug"``.

    You can set the ``allow_unicode`` parameter to ``True``, if you want to
    allow Unicode characters::

        slugify(value, allow_unicode=True)

    If ``value`` is ``"你好 World"``, the output will be ``"你好-world"``.

    .. versionchanged:: 1.9

        The ``allow_unicode`` parameter was added.

.. _time-zone-selection-functions:

``django.utils.timezone``
=========================

.. module:: django.utils.timezone
    :synopsis: Timezone support.

.. data:: utc

    :class:`~datetime.tzinfo` instance that represents UTC.

.. class:: FixedOffset(offset=None, name=None)

    A :class:`~datetime.tzinfo` subclass modeling a fixed offset from UTC.
    ``offset`` is an integer number of minutes east of UTC.

.. function:: get_fixed_timezone(offset)

    Returns a :class:`~datetime.tzinfo` instance that represents a time zone
    with a fixed offset from UTC.

    ``offset`` is a :class:`datetime.timedelta` or an integer number of
    minutes. Use positive values for time zones east of UTC and negative
    values for west of UTC.

.. function:: get_default_timezone()

    Returns a :class:`~datetime.tzinfo` instance that represents the
    :ref:`default time zone <default-current-time-zone>`.

.. function:: get_default_timezone_name()

    Returns the name of the :ref:`default time zone
    <default-current-time-zone>`.

.. function:: get_current_timezone()

    Returns a :class:`~datetime.tzinfo` instance that represents the
    :ref:`current time zone <default-current-time-zone>`.

.. function:: get_current_timezone_name()

    Returns the name of the :ref:`current time zone
    <default-current-time-zone>`.

.. function:: activate(timezone)

    Sets the :ref:`current time zone <default-current-time-zone>`. The
    ``timezone`` argument must be an instance of a :class:`~datetime.tzinfo`
    subclass or, if pytz_ is available, a time zone name.

.. function:: deactivate()

    Unsets the :ref:`current time zone <default-current-time-zone>`.

.. function:: override(timezone)

    This is a Python context manager that sets the :ref:`current time zone
    <default-current-time-zone>` on entry with :func:`activate()`, and restores
    the previously active time zone on exit. If the ``timezone`` argument is
    ``None``, the :ref:`current time zone <default-current-time-zone>` is unset
    on entry with :func:`deactivate()` instead.

    ``override`` is also usable as a function decorator.

.. function:: localtime(value, timezone=None)

    Converts an aware :class:`~datetime.datetime` to a different time zone,
    by default the :ref:`current time zone <default-current-time-zone>`.

    This function doesn't work on naive datetimes; use :func:`make_aware`
    instead.

.. function:: now()

    Returns a :class:`~datetime.datetime` that represents the
    current point in time. Exactly what's returned depends on the value of
    :setting:`USE_TZ`:

    * If :setting:`USE_TZ` is ``False``, this will be a
      :ref:`naive <naive_vs_aware_datetimes>` datetime (i.e. a datetime
      without an associated timezone) that represents the current time
      in the system's local timezone.

    * If :setting:`USE_TZ` is ``True``, this will be an
      :ref:`aware <naive_vs_aware_datetimes>` datetime representing the
      current time in UTC. Note that :func:`now` will always return
      times in UTC regardless of the value of :setting:`TIME_ZONE`;
      you can use :func:`localtime` to convert to a time in the current
      time zone.

.. function:: is_aware(value)

    Returns ``True`` if ``value`` is aware, ``False`` if it is naive. This
    function assumes that ``value`` is a :class:`~datetime.datetime`.

.. function:: is_naive(value)

    Returns ``True`` if ``value`` is naive, ``False`` if it is aware. This
    function assumes that ``value`` is a :class:`~datetime.datetime`.

.. function:: make_aware(value, timezone=None, is_dst=None)

    Returns an aware :class:`~datetime.datetime` that represents the same
    point in time as ``value`` in ``timezone``, ``value`` being a naive
    :class:`~datetime.datetime`. If ``timezone`` is set to ``None``, it
    defaults to the :ref:`current time zone <default-current-time-zone>`.

    When pytz_ is installed, the exception ``pytz.AmbiguousTimeError``
    will be raised if you try to make ``value`` aware during a DST transition
    where the same time occurs twice (when reverting from DST). Setting
    ``is_dst`` to ``True`` or ``False`` will avoid the exception by choosing if
    the time is pre-transition or post-transition respectively.

    When pytz_ is installed, the exception ``pytz.NonExistentTimeError``
    will be raised if you try to make ``value`` aware during a DST transition
    such that the time never occurred (when entering into DST). Setting
    ``is_dst`` to ``True`` or ``False`` will avoid the exception by moving the
    hour backwards or forwards by 1 respectively. For example, ``is_dst=True``
    would change a non-existent time of 2:30 to 1:30 and ``is_dst=False``
    would change the time to 3:30.

    ``is_dst`` has no effect when ``pytz`` is not installed.

    .. versionchanged:: 1.9

        The ``is_dst`` argument was added.

.. function:: make_naive(value, timezone=None)

    Returns an naive :class:`~datetime.datetime` that represents in
    ``timezone``  the same point in time as ``value``, ``value`` being an
    aware :class:`~datetime.datetime`. If ``timezone`` is set to ``None``, it
    defaults to the :ref:`current time zone <default-current-time-zone>`.

.. _pytz: http://pytz.sourceforge.net/

``django.utils.translation``
============================

.. module:: django.utils.translation
   :synopsis: Internationalization support.

For a complete discussion on the usage of the following see the
:doc:`translation documentation </topics/i18n/translation>`.

.. function:: gettext(message)

    Translates ``message`` and returns it in a UTF-8 bytestring

.. function:: ugettext(message)

    Translates ``message`` and returns it in a unicode string

.. function:: pgettext(context, message)

    Translates ``message`` given the ``context`` and returns
    it in a unicode string.

    For more information, see :ref:`contextual-markers`.

.. function:: gettext_lazy(message)
.. function:: ugettext_lazy(message)
.. function:: pgettext_lazy(context, message)

    Same as the non-lazy versions above, but using lazy execution.

    See :ref:`lazy translations documentation <lazy-translations>`.

.. function:: gettext_noop(message)
.. function:: ugettext_noop(message)

    Marks strings for translation but doesn't translate them now. This can be
    used to store strings in global variables that should stay in the base
    language (because they might be used externally) and will be translated
    later.

.. function:: ngettext(singular, plural, number)

    Translates ``singular`` and ``plural`` and returns the appropriate string
    based on ``number`` in a UTF-8 bytestring.

.. function:: ungettext(singular, plural, number)

    Translates ``singular`` and ``plural`` and returns the appropriate string
    based on ``number`` in a unicode string.

.. function:: npgettext(context, singular, plural, number)

    Translates ``singular`` and ``plural`` and returns the appropriate string
    based on ``number`` and the ``context`` in a unicode string.

.. function:: ngettext_lazy(singular, plural, number)
.. function:: ungettext_lazy(singular, plural, number)
.. function:: npgettext_lazy(context, singular, plural, number)

    Same as the non-lazy versions above, but using lazy execution.

    See :ref:`lazy translations documentation <lazy-translations>`.

.. function:: string_concat(*strings)

    Lazy variant of string concatenation, needed for translations that are
    constructed from multiple parts.

.. function:: activate(language)

    Fetches the translation object for a given language and activates it as
    the current translation object for the current thread.

.. function:: deactivate()

    Deactivates the currently active translation object so that further _ calls
    will resolve against the default translation object, again.

.. function:: deactivate_all()

    Makes the active translation object a ``NullTranslations()`` instance.
    This is useful when we want delayed translations to appear as the original
    string for some reason.

.. function:: override(language, deactivate=False)

    A Python context manager that uses
    :func:`django.utils.translation.activate` to fetch the translation object
    for a given language, activates it as the translation object for the
    current thread and reactivates the previous active language on exit.
    Optionally, it can simply deactivate the temporary translation on exit with
    :func:`django.utils.translation.deactivate` if the ``deactivate`` argument
    is ``True``. If you pass ``None`` as the language argument, a
    ``NullTranslations()`` instance is activated within the context.

    ``override`` is also usable as a function decorator.

.. function:: check_for_language(lang_code)

    Checks whether there is a global language file for the given language
    code (e.g. 'fr', 'pt_BR'). This is used to decide whether a user-provided
    language is available.

.. function:: get_language()

    Returns the currently selected language code. Returns ``None`` if
    translations are temporarily deactivated (by :func:`deactivate_all()` or
    when ``None`` is passed to :func:`override()`).

.. function:: get_language_bidi()

    Returns selected language's BiDi layout:

    * ``False`` = left-to-right layout
    * ``True`` = right-to-left layout

.. function:: get_language_from_request(request, check_path=False)

    Analyzes the request to find what language the user wants the system to
    show. Only languages listed in settings.LANGUAGES are taken into account.
    If the user requests a sublanguage where we have a main language, we send
    out the main language.

    If ``check_path`` is ``True``, the function first checks the requested URL
    for whether its path begins with a language code listed in the
    :setting:`LANGUAGES` setting.

.. function:: to_locale(language)

    Turns a language name (en-us) into a locale name (en_US).

.. function:: templatize(src)

    Turns a Django template into something that is understood by ``xgettext``.
    It does so by translating the Django translation tags into standard
    ``gettext`` function invocations.

.. data:: LANGUAGE_SESSION_KEY

    Session key under which the active language for the current session is
    stored.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Validators (`大一小学期/Week_3-Python/exam/2016/docs/ref/validators.txt`)

==========
Validators
==========

.. module:: django.core.validators
    :synopsis: Validation utilities and base classes

Writing validators
==================

A validator is a callable that takes a value and raises a
:exc:`~django.core.exceptions.ValidationError` if it doesn't meet some
criteria. Validators can be useful for re-using validation logic between
different types of fields.

For example, here's a validator that only allows even numbers::

    from django.core.exceptions import ValidationError
    from django.utils.translation import ugettext_lazy as _

    def validate_even(value):
        if value % 2 != 0:
            raise ValidationError(
                _('%(value)s is not an even number'),
                params={'value': value},
            )

You can add this to a model field via the field's :attr:`~django.db.models.Field.validators`
argument::

    from django.db import models

    class MyModel(models.Model):
        even_field = models.IntegerField(validators=[validate_even])

Because values are converted to Python before validators are run, you can even
use the same validator with forms::

    from django import forms

    class MyForm(forms.Form):
        even_field = forms.IntegerField(validators=[validate_even])

You can also use a class with a ``__call__()`` method for more complex or
configurable validators. :class:`RegexValidator`, for example, uses this
technique. If a class-based validator is used in the
:attr:`~django.db.models.Field.validators` model field option, you should make
sure it is :ref:`serializable by the migration framework
<migration-serializing>` by adding :ref:`deconstruct()
<custom-deconstruct-method>` and ``__eq__()`` methods.

How validators are run
======================

See the :doc:`form validation </ref/forms/validation>` for more information on
how validators are run in forms, and :ref:`Validating objects
<validating-objects>` for how they're run in models. Note that validators will
not be run automatically when you save a model, but if you are using a
:class:`~django.forms.ModelForm`, it will run your validators on any fields
that are included in your form. See the
:doc:`ModelForm documentation </topics/forms/modelforms>` for information on
how model validation interacts with forms.

Built-in validators
===================

The :mod:`django.core.validators` module contains a collection of callable
validators for use with model and form fields. They're used internally but
are available for use with your own fields, too. They can be used in addition
to, or in lieu of custom ``field.clean()`` methods.

``RegexValidator``
------------------

.. class:: RegexValidator(regex=None, message=None, code=None, inverse_match=None, flags=0)

    :param regex: If not ``None``, overrides :attr:`regex`. Can be a regular
        expression string or a pre-compiled regular expression.
    :param message: If not ``None``, overrides :attr:`.message`.
    :param code: If not ``None``, overrides :attr:`code`.
    :param inverse_match: If not ``None``, overrides :attr:`inverse_match`.
    :param flags: If not ``None``, overrides :attr:`flags`. In that case,
        :attr:`regex` must be a regular expression string, or
        :exc:`TypeError` is raised.

    .. attribute:: regex

        The regular expression pattern to search for the provided ``value``,
        or a pre-compiled regular expression. By default, raises a
        :exc:`~django.core.exceptions.ValidationError` with :attr:`message`
        and :attr:`code` if a match is not found. That standard behavior can
        be reversed by setting :attr:`inverse_match` to ``True``, in which case
        the :exc:`~django.core.exceptions.ValidationError` is raised when a
        match **is** found. By default, matches any string (including an empty
        string).

    .. attribute:: message

        The error message used by
        :exc:`~django.core.exceptions.ValidationError` if validation fails.
        Defaults to ``"Enter a valid value"``.

    .. attribute:: code

        The error code used by :exc:`~django.core.exceptions.ValidationError`
        if validation fails. Defaults to ``"invalid"``.

    .. attribute:: inverse_match

        The match mode for :attr:`regex`. Defaults to ``False``.

    .. attribute:: flags

        The flags used when compiling the regular expression string
        :attr:`regex`. If :attr:`regex` is a pre-compiled regular expression,
        and :attr:`flags` is overridden, :exc:`TypeError` is raised. Defaults
        to ``0``.

``EmailValidator``
------------------

.. class:: EmailValidator(message=None, code=None, whitelist=None)

    :param message: If not ``None``, overrides :attr:`.message`.
    :param code: If not ``None``, overrides :attr:`code`.
    :param whitelist: If not ``None``, overrides :attr:`whitelist`.

    .. attribute:: message

        The error message used by
        :exc:`~django.core.exceptions.ValidationError` if validation fails.
        Defaults to ``"Enter a valid email address"``.

    .. attribute:: code

        The error code used by :exc:`~django.core.exceptions.ValidationError`
        if validation fails. Defaults to ``"invalid"``.

    .. attribute:: whitelist

        Whitelist of email domains to allow. By default, a regular expression
        (the ``domain_regex`` attribute) is used to validate whatever appears
        after the @ sign. However, if that string appears in the whitelist, this
        validation is bypassed. If not provided, the default whitelist is
        ``['localhost']``. Other domains that don't contain a dot won't pass
        validation, so you'd need to whitelist them as necessary.

``URLValidator``
----------------

.. class:: URLValidator(schemes=None, regex=None, message=None, code=None)

    A :class:`RegexValidator` that ensures a value looks like a URL, and raises
    an error code of ``'invalid'`` if it doesn't.

    Loopback addresses and reserved IP spaces are considered valid. Literal
    IPv6 addresses (:rfc:`2732`) and unicode domains are both supported.

    In addition to the optional arguments of its parent :class:`RegexValidator`
    class, ``URLValidator`` accepts an extra optional attribute:

    .. attribute:: schemes

        URL/URI scheme list to validate against. If not provided, the default
        list is ``['http', 'https', 'ftp', 'ftps']``. As a reference, the IANA
        website provides a full list of `valid URI schemes`_.

        .. _valid URI schemes: https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml

``validate_email``
------------------

.. data:: validate_email

    An :class:`EmailValidator` instance without any customizations.

``validate_slug``
-----------------

.. data:: validate_slug

    A :class:`RegexValidator` instance that ensures a value consists of only
    letters, numbers, underscores or hyphens.

``validate_unicode_slug``
-------------------------

.. data:: validate_unicode_slug

    .. versionadded:: 1.9

    A :class:`RegexValidator` instance that ensures a value consists of only
    Unicode letters, numbers, underscores, or hyphens.

``validate_ipv4_address``
-------------------------

.. data:: validate_ipv4_address

    A :class:`RegexValidator` instance that ensures a value looks like an IPv4
    address.

``validate_ipv6_address``
-------------------------

.. data:: validate_ipv6_address

    Uses ``django.utils.ipv6`` to check the validity of an IPv6 address.

``validate_ipv46_address``
--------------------------

.. data:: validate_ipv46_address

    Uses both ``validate_ipv4_address`` and ``validate_ipv6_address`` to
    ensure a value is either a valid IPv4 or IPv6 address.

``validate_comma_separated_integer_list``
-----------------------------------------

.. data:: validate_comma_separated_integer_list

    A :class:`RegexValidator` instance that ensures a value is a
    comma-separated list of integers.

``int_list_validator``
----------------------

.. function:: int_list_validator(sep=',', message=None, code='invalid', allow_negative=False)

    .. versionadded:: 1.9

    Returns a :class:`RegexValidator` instance that ensures a string consists
    of integers separated by ``sep``. It allows negative integers when
    ``allow_negative`` is ``True``.

    .. versionchanged:: 1.10

        The ``allow_negative`` parameter was added.

``MaxValueValidator``
---------------------

.. class:: MaxValueValidator(max_value, message=None)

    Raises a :exc:`~django.core.exceptions.ValidationError` with a code of
    ``'max_value'`` if ``value`` is greater than ``max_value``.

``MinValueValidator``
---------------------

.. class:: MinValueValidator(min_value, message=None)

    Raises a :exc:`~django.core.exceptions.ValidationError` with a code of
    ``'min_value'`` if ``value`` is less than ``min_value``.

``MaxLengthValidator``
----------------------

.. class:: MaxLengthValidator(max_length, message=None)

    Raises a :exc:`~django.core.exceptions.ValidationError` with a code of
    ``'max_length'`` if the length of ``value`` is greater than ``max_length``.

``MinLengthValidator``
----------------------

.. class:: MinLengthValidator(min_length, message=None)

    Raises a :exc:`~django.core.exceptions.ValidationError` with a code of
    ``'min_length'`` if the length of ``value`` is less than ``min_length``.

``DecimalValidator``
--------------------

.. class:: DecimalValidator(max_digits, decimal_places)

    .. versionadded:: 1.9

    Raises :exc:`~django.core.exceptions.ValidationError` with the following
    codes:

    - ``'max_digits'`` if the number of digits is larger than ``max_digits``.
    - ``'max_decimal_places'`` if the number of decimals is larger than
      ``decimal_places``.
    - ``'max_whole_digits'`` if the number of whole digits is larger than
      the difference between ``max_digits`` and ``decimal_places``.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Ref Views (`大一小学期/Week_3-Python/exam/2016/docs/ref/views.txt`)

==============
Built-in Views
==============

.. module:: django.views
   :synopsis: Django's built-in views.

Several of Django's built-in views are documented in
:doc:`/topics/http/views` as well as elsewhere in the documentation.

Serving files in development
============================

.. function:: static.serve(request, path, document_root, show_indexes=False)

There may be files other than your project's static assets that, for
convenience, you'd like to have Django serve for you in local development.
The :func:`~django.views.static.serve` view can be used to serve any directory
you give it. (This view is **not** hardened for production use and should be
used only as a development aid; you should serve these files in production
using a real front-end web server).

The most likely example is user-uploaded content in :setting:`MEDIA_ROOT`.
``django.contrib.staticfiles`` is intended for static assets and has no
built-in handling for user-uploaded files, but you can have Django serve your
:setting:`MEDIA_ROOT` by appending something like this to your URLconf::

    from django.conf import settings
    from django.views.static import serve

    # ... the rest of your URLconf goes here ...

    if settings.DEBUG:
        urlpatterns += [
            url(r'^media/(?P<path>.*)$', serve, {
                'document_root': settings.MEDIA_ROOT,
            }),
        ]

Note, the snippet assumes your :setting:`MEDIA_URL` has a value of
``'/media/'``. This will call the :func:`~django.views.static.serve` view,
passing in the path from the URLconf and the (required) ``document_root``
parameter.

Since it can become a bit cumbersome to define this URL pattern, Django
ships with a small URL helper function :func:`~django.conf.urls.static.static`
that takes as parameters the prefix such as :setting:`MEDIA_URL` and a dotted
path to a view, such as ``'django.views.static.serve'``. Any other function
parameter will be transparently passed to the view.

.. _error-views:

Error views
===========

Django comes with a few views by default for handling HTTP errors. To override
these with your own custom views, see :ref:`customizing-error-views`.

.. _http_not_found_view:

The 404 (page not found) view
-----------------------------

.. function:: defaults.page_not_found(request, exception, template_name='404.html')

When you raise :exc:`~django.http.Http404` from within a view, Django loads a
special view devoted to handling 404 errors. By default, it's the view
:func:`django.views.defaults.page_not_found`, which either produces a very
simple "Not Found" message or loads and renders the template ``404.html`` if
you created it in your root template directory.

The default 404 view will pass two variables to the template: ``request_path``,
which is the URL that resulted in the error, and ``exception``, which is a
useful representation of the exception that triggered the view (e.g. containing
any message passed to a specific ``Http404`` instance).

Three things to note about 404 views:

* The 404 view is also called if Django doesn't find a match after
  checking every regular expression in the URLconf.

* The 404 view is passed a :class:`~django.template.RequestContext` and
  will have access to variables supplied by your template context
  processors (e.g. ``MEDIA_URL``).

* If :setting:`DEBUG` is set to ``True`` (in your settings module), then
  your 404 view will never be used, and your URLconf will be displayed
  instead, with some debug information.

.. versionchanged:: 1.9

    The signature of ``page_not_found()`` changed. The function now accepts a
    second parameter, the exception that triggered the error. A useful
    representation of the exception is also passed in the template context.

.. versionchanged:: 1.10

    Passing a nonexistent ``template_name`` will raise ``TemplateDoesNotExist``.

.. _http_internal_server_error_view:

The 500 (server error) view
---------------------------

.. function:: defaults.server_error(request, template_name='500.html')

Similarly, Django executes special-case behavior in the case of runtime errors
in view code. If a view results in an exception, Django will, by default, call
the view ``django.views.defaults.server_error``, which either produces a very
simple "Server Error" message or loads and renders the template ``500.html`` if
you created it in your root template directory.

The default 500 view passes no variables to the ``500.html`` template and is
rendered with an empty ``Context`` to lessen the chance of additional errors.

If :setting:`DEBUG` is set to ``True`` (in your settings module), then
your 500 view will never be used, and the traceback will be displayed
instead, with some debug information.

.. versionchanged:: 1.10

    Passing a nonexistent ``template_name`` will raise ``TemplateDoesNotExist``.

.. _http_forbidden_view:

The 403 (HTTP Forbidden) view
-----------------------------

.. function:: defaults.permission_denied(request, exception, template_name='403.html')

In the same vein as the 404 and 500 views, Django has a view to handle 403
Forbidden errors. If a view results in a 403 exception then Django will, by
default, call the view ``django.views.defaults.permission_denied``.

This view loads and renders the template ``403.html`` in your root template
directory, or if this file does not exist, instead serves the text
"403 Forbidden", as per :rfc:`7231#section-6.5.3` (the HTTP 1.1 Specification).
The template context contains ``exception``, which is the unicode
representation of the exception that triggered the view.

``django.views.defaults.permission_denied`` is triggered by a
:exc:`~django.core.exceptions.PermissionDenied` exception. To deny access in a
view you can use code like this::

    from django.core.exceptions import PermissionDenied

    def edit(request, pk):
        if not request.user.is_staff:
            raise PermissionDenied
        # ...

.. versionchanged:: 1.9

    The signature of ``permission_denied()`` changed in Django 1.9. The function
    now accepts a second parameter, the exception that triggered the error. The
    unicode representation of the exception is also passed in the template
    context.

.. versionchanged:: 1.10

    Passing a nonexistent ``template_name`` will raise ``TemplateDoesNotExist``.

.. _http_bad_request_view:

The 400 (bad request) view
--------------------------

.. function:: defaults.bad_request(request, exception, template_name='400.html')

When a :exc:`~django.core.exceptions.SuspiciousOperation` is raised in Django,
it may be handled by a component of Django (for example resetting the session
data). If not specifically handled, Django will consider the current request a
'bad request' instead of a server error.

``django.views.defaults.bad_request``, is otherwise very similar to the
``server_error`` view, but returns with the status code 400 indicating that
the error condition was the result of a client operation. By default, nothing
related to the exception that triggered the view is passed to the template
context, as the exception message might contain sensitive information like
filesystem paths.

``bad_request`` views are also only used when :setting:`DEBUG` is ``False``.

.. versionchanged:: 1.9

    The signature of ``bad_request()`` changed in Django 1.9. The function
    now accepts a second parameter, the exception that triggered the error.

.. versionchanged:: 1.10

    Passing a nonexistent ``template_name`` will raise ``TemplateDoesNotExist``.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 0.95 (`大一小学期/Week_3-Python/exam/2016/docs/releases/0.95.txt`)

=================================
Django version 0.95 release notes
=================================

Welcome to the Django 0.95 release.

This represents a significant advance in Django development since the 0.91
release in January 2006. The details of every change in this release would be
too extensive to list in full, but a summary is presented below.

Suitability and API stability
=============================

This release is intended to provide a stable reference point for developers
wanting to work on production-level applications that use Django.

However, it's not the 1.0 release, and we'll be introducing further changes
before 1.0. For a clear look at which areas of the framework will change (and
which ones will *not* change) before 1.0, see the ``api-stability.txt`` file,
which lives in the docs/ directory of the distribution.

You may have a need to use some of the features that are marked as
"subject to API change" in that document, but that's OK with us as long as it's
OK with you, and as long as you understand APIs may change in the future.

Fortunately, most of Django's core APIs won't be changing before version 1.0.
There likely won't be as big of a change between 0.95 and 1.0 versions as there
was between 0.91 and 0.95.

Changes and new features
========================

The major changes in this release (for developers currently using the 0.91
release) are a result of merging the 'magic-removal' branch of development.
This branch removed a number of constraints in the way Django code had to be
written that were a consequence of decisions made in the early days of Django,
prior to its open-source release. It's now possible to write more natural,
Pythonic code that works as expected, and there's less "black magic" happening
behind the scenes.

Aside from that, another main theme of this release is a dramatic increase in
usability. We've made countless improvements in error messages, documentation,
etc., to improve developers' quality of life.

The new features and changes introduced in 0.95 include:

* Django now uses a more consistent and natural filtering interface for
  retrieving objects from the database.

* User-defined models, functions and constants now appear in the module
  namespace they were defined in. (Previously everything was magically
  transferred to the django.models.* namespace.)

* Some optional applications, such as the FlatPage, Sites and Redirects
  apps, have been decoupled and moved into django.contrib. If you don't
  want to use these applications, you no longer have to install their
  database tables.

* Django now has support for managing database transactions.

* We've added the ability to write custom authentication and authorization
  backends for authenticating users against alternate systems, such as
  LDAP.

* We've made it easier to add custom table-level functions to models,
  through a new "Manager" API.

* It's now possible to use Django without a database. This simply means
  that the framework no longer requires you to have a working database set
  up just to serve dynamic pages. In other words, you can just use
  URLconfs/views on their own. Previously, the framework required that a
  database be configured, regardless of whether you actually used it.

* It's now more explicit and natural to override save() and delete()
  methods on models, rather than needing to hook into the pre_save() and
  post_save() method hooks.

* Individual pieces of the framework now can be configured without
  requiring the setting of an environment variable. This permits use of,
  for example, the Django templating system inside other applications.

* More and more parts of the framework have been internationalized, as
  we've expanded internationalization (i18n) support. The Django
  codebase, including code and templates, has now been translated, at least
  in part, into 31 languages. From Arabic to Chinese to Hungarian to Welsh,
  it is now possible to use Django's admin site in your native language.

The number of changes required to port from 0.91-compatible code to the 0.95
code base are significant in some cases. However, they are, for the most part,
reasonably routine and only need to be done once. A list of the necessary
changes is described in the `Removing The Magic`_ wiki page. There is also an
easy checklist_ for reference when undertaking the porting operation.

.. _Removing The Magic: https://code.djangoproject.com/wiki/RemovingTheMagic
.. _checklist: https://code.djangoproject.com/wiki/MagicRemovalCheatSheet

Problem reports and getting help
================================

Need help resolving a problem with Django? The documentation in the
distribution is also available :doc:`online </index>` at the `Django website`_.
The :doc:`FAQ </faq/index>` document is especially recommended, as it contains
a number of issues that come up time and again.

For more personalized help, the `django-users`_ mailing list is a very active
list, with more than 2,000 subscribers who can help you solve any sort of
Django problem. We recommend you search the archives first, though, because
many common questions appear with some regularity, and any particular problem
may already have been answered.

Finally, for those who prefer the more immediate feedback offered by IRC,
there's a #django channel on irc.freenode.net that is regularly populated by
Django users and developers from around the world. Friendly people are usually
available at any hour of the day -- to help, or just to chat.

.. _Django website: https://www.djangoproject.com/
.. _django-users: https://groups.google.com/group/django-users

Thanks for using Django!

The Django Team
July 2006

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 0.96 (`大一小学期/Week_3-Python/exam/2016/docs/releases/0.96.txt`)

=================================
Django version 0.96 release notes
=================================

Welcome to Django 0.96!

The primary goal for 0.96 is a cleanup and stabilization of the features
introduced in 0.95. There have been a few small `backwards-incompatible
changes`_ since 0.95, but the upgrade process should be fairly simple
and should not require major changes to existing applications.

However, we're also releasing 0.96 now because we have a set of
backwards-incompatible changes scheduled for the near future. Once
completed, they will involve some code changes for application
developers, so we recommend that you stick with Django 0.96 until the
next official release; then you'll be able to upgrade in one step
instead of needing to make incremental changes to keep up with the
development version of Django.

Backwards-incompatible changes
==============================

The following changes may require you to update your code when you switch from
0.95 to 0.96:

``MySQLdb`` version requirement
-------------------------------

Due to a bug in older versions of the ``MySQLdb`` Python module (which
Django uses to connect to MySQL databases), Django's MySQL backend now
requires version 1.2.1p2 or higher of ``MySQLdb``, and will raise
exceptions if you attempt to use an older version.

If you're currently unable to upgrade your copy of ``MySQLdb`` to meet
this requirement, a separate, backwards-compatible backend, called
"mysql_old", has been added to Django. To use this backend, change
the ``DATABASE_ENGINE`` setting in your Django settings file from this::

    DATABASE_ENGINE = "mysql"

to this::

    DATABASE_ENGINE = "mysql_old"

However, we strongly encourage MySQL users to upgrade to a more recent
version of ``MySQLdb`` as soon as possible, The "mysql_old" backend is
provided only to ease this transition, and is considered deprecated;
aside from any necessary security fixes, it will not be actively
maintained, and it will be removed in a future release of Django.

Also, note that some features, like the new ``DATABASE_OPTIONS``
setting (see the :doc:`databases documentation </ref/databases>` for details),
are only available on the "mysql" backend, and will not be made available for
"mysql_old".

Database constraint names changed
---------------------------------

The format of the constraint names Django generates for foreign key
references have changed slightly. These names are generally only used
when it is not possible to put the reference directly on the affected
column, so they are not always visible.

The effect of this change is that running ``manage.py reset`` and
similar commands against an existing database may generate SQL with
the new form of constraint name, while the database itself contains
constraints named in the old form; this will cause the database server
to raise an error message about modifying non-existent constraints.

If you need to work around this, there are two methods available:

1. Redirect the output of ``manage.py`` to a file, and edit the
   generated SQL to use the correct constraint names before
   executing it.

2. Examine the output of ``manage.py sqlall`` to see the new-style
   constraint names, and use that as a guide to rename existing
   constraints in your database.

Name changes in ``manage.py``
-----------------------------

A few of the options to ``manage.py`` have changed with the addition of fixture
support:

* There are new ``dumpdata`` and ``loaddata`` commands which, as
  you might expect, will dump and load data to/from the
  database. These commands can operate against any of Django's
  supported serialization formats.

* The ``sqlinitialdata`` command has been renamed to ``sqlcustom`` to
  emphasize that ``loaddata`` should be used for data (and ``sqlcustom`` for
  other custom SQL -- views, stored procedures, etc.).

* The vestigial ``install`` command has been removed. Use ``syncdb``.

Backslash escaping changed
--------------------------

The Django database API now escapes backslashes given as query parameters. If
you have any database API code that matches backslashes, and it was working before
(despite the lack of escaping), you'll have to change your code to "unescape" the
slashes one level.

For example, this used to work::

    # Find text containing a single backslash
    MyModel.objects.filter(text__contains='\\\\')

The above is now incorrect, and should be rewritten as::

    # Find text containing a single backslash
    MyModel.objects.filter(text__contains='\\')

Removed ENABLE_PSYCO setting
----------------------------

The ``ENABLE_PSYCO`` setting no longer exists. If your settings file includes
``ENABLE_PSYCO`` it will have no effect; to use Psyco_, we recommend
writing a middleware class to activate it.

.. _psyco: http://psyco.sourceforge.net/

What's new in 0.96?
===================

This revision represents over a thousand source commits and over four hundred
bug fixes, so we can't possibly catalog all the changes. Here, we describe the
most notable changes in this release.

New forms library
-----------------

``django.newforms`` is Django's new form-handling library. It's a
replacement for ``django.forms``, the old form/manipulator/validation
framework.  Both APIs are available in 0.96, but over the next two
releases we plan to switch completely to the new forms system, and
deprecate and remove the old system.

There are three elements to this transition:

* We've copied the current ``django.forms`` to
  ``django.oldforms``. This allows you to upgrade your code *now*
  rather than waiting for the backwards-incompatible change and
  rushing to fix your code after the fact.  Just change your
  import statements like this::

      from django import forms             # 0.95-style
      from django import oldforms as forms # 0.96-style

* The next official release of Django will move the current
  ``django.newforms`` to ``django.forms``. This will be a
  backwards-incompatible change, and anyone still using the old
  version of ``django.forms`` at that time will need to change
  their import statements as described above.

* The next release after that will completely remove
  ``django.oldforms``.

Although the ``newforms`` library will continue to evolve, it's ready for use
for most common cases. We recommend that anyone new to form handling skip the
old forms system and start with the new.

For more information about ``django.newforms``, read the :doc:`newforms
documentation </topics/forms/index>`.

URLconf improvements
--------------------

You can now use any callable as the callback in URLconfs (previously, only
strings that referred to callables were allowed). This allows a much more
natural use of URLconfs. For example, this URLconf::

    from django.conf.urls.defaults import *

    urlpatterns = patterns('',
        ('^myview/$', 'mysite.myapp.views.myview')
    )

can now be rewritten as::

    from django.conf.urls.defaults import *
    from mysite.myapp.views import myview

    urlpatterns = patterns('',
        ('^myview/$', myview)
    )

One useful application of this can be seen when using decorators; this
change allows you to apply decorators to views *in your
URLconf*. Thus, you can make a generic view require login very
easily::

    from django.conf.urls.defaults import *
    from django.contrib.auth.decorators import login_required
    from django.views.generic.list_detail import object_list
    from mysite.myapp.models import MyModel

    info = {
        "queryset" : MyModel.objects.all(),
    }

    urlpatterns = patterns('',
        ('^myview/$', login_required(object_list), info)
    )

Note that both syntaxes (strings and callables) are valid, and will continue to
be valid for the foreseeable future.

The test framework
------------------

Django now includes a test framework so you can start transmuting fear into
boredom (with apologies to Kent Beck). You can write tests based on
:mod:`doctest` or :mod:`unittest` and test your views with a simple test client.

There is also new support for "fixtures" -- initial data, stored in any of the
supported :doc:`serialization formats </topics/serialization>`, that will be
loaded into your database at the start of your tests. This makes testing with
real data much easier.

See :doc:`the testing documentation </topics/testing/index>` for the full details.

Improvements to the admin interface
-----------------------------------

A small change, but a very nice one: dedicated views for adding and
updating users have been added to the admin interface, so you no
longer need to worry about working with hashed passwords in the admin.

Thanks
======

Since 0.95, a number of people have stepped forward and taken a major
new role in Django's development. We'd like to thank these people for
all their hard work:

* Russell Keith-Magee and Malcolm Tredinnick for their major code
  contributions. This release wouldn't have been possible without them.

* Our new release manager, James Bennett, for his work in getting out
  0.95.1, 0.96, and (hopefully) future release.

* Our ticket managers Chris Beaven (aka SmileyChris), Simon Greenhill,
  Michael Radziej, and Gary Wilson. They agreed to take on the monumental
  task of wrangling our tickets into nicely cataloged submission. Figuring
  out what to work on is now about a million times easier; thanks again,
  guys.

* Everyone who submitted a bug report, patch or ticket comment. We can't
  possibly thank everyone by name -- over 200 developers submitted patches
  that went into 0.96 -- but everyone who's contributed to Django is listed
  in AUTHORS_.

.. _AUTHORS: https://code.djangoproject.com/browser/django/trunk/AUTHORS

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.0 Porting Guide (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.0-porting-guide.txt`)

=========================================
Porting your apps from Django 0.96 to 1.0
=========================================

.. highlight:: python

Django 1.0 breaks compatibility with 0.96 in some areas.

This guide will help you port 0.96 projects and apps to 1.0. The first part of
this document includes the common changes needed to run with 1.0. If after going
through the first part your code still breaks, check the section `Less-common
Changes`_ for a list of a bunch of less-common compatibility issues.

.. seealso::

    The :doc:`1.0 release notes </releases/1.0>`. That document explains the new
    features in 1.0 more deeply; the porting guide is more concerned with
    helping you quickly update your code.

Common changes
==============

This section describes the changes between 0.96 and 1.0 that most users will
need to make.

Use Unicode
-----------

Change string literals (``'foo'``) into Unicode literals (``u'foo'``). Django
now uses Unicode strings throughout. In most places, raw strings will continue
to work, but updating to use Unicode literals will prevent some obscure
problems.

See :doc:`/ref/unicode` for full details.

Models
------

Common changes to your models file:

Rename ``maxlength`` to ``max_length``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Rename your ``maxlength`` argument to ``max_length`` (this was changed to be
consistent with form fields):

Replace ``__str__`` with ``__unicode__``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Replace your model's ``__str__`` function with a ``__unicode__`` method, and
make sure you `use Unicode`_ (``u'foo'``) in that method.

Remove ``prepopulated_from``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Remove the ``prepopulated_from`` argument on model fields. It's no longer valid
and has been moved to the ``ModelAdmin`` class in ``admin.py``. See `the
admin`_, below, for more details about changes to the admin.

Remove ``core``
~~~~~~~~~~~~~~~

Remove the ``core`` argument from your model fields. It is no longer
necessary, since the equivalent functionality (part of :ref:`inline editing
<admin-inlines>`) is handled differently by the admin interface now. You don't
have to worry about inline editing until you get to `the admin`_ section,
below. For now, remove all references to ``core``.

Replace ``class Admin:`` with ``admin.py``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Remove all your inner ``class Admin`` declarations from your models. They won't
break anything if you leave them, but they also won't do anything. To register
apps with the admin you'll move those declarations to an ``admin.py`` file;
see `the admin`_ below for more details.

.. seealso::

    A contributor to djangosnippets__ has written a script that'll `scan your
    models.py and generate a corresponding admin.py`__.

    __ https://www.djangosnippets.org/
    __ https://www.djangosnippets.org/snippets/603/

Example
~~~~~~~

Below is an example ``models.py`` file with all the changes you'll need to make:

Old (0.96) ``models.py``::

    class Author(models.Model):
        first_name = models.CharField(maxlength=30)
        last_name = models.CharField(maxlength=30)
        slug = models.CharField(maxlength=60, prepopulate_from=('first_name', 'last_name'))

        class Admin:
            list_display = ['first_name', 'last_name']

        def __str__(self):
            return '%s %s' % (self.first_name, self.last_name)

New (1.0) ``models.py``::

    class Author(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=30)
        slug = models.CharField(max_length=60)

        def __unicode__(self):
            return u'%s %s' % (self.first_name, self.last_name)

New (1.0) ``admin.py``::

    from django.contrib import admin
    from models import Author

    class AuthorAdmin(admin.ModelAdmin):
        list_display = ['first_name', 'last_name']
        prepopulated_fields = {
            'slug': ('first_name', 'last_name')
        }

    admin.site.register(Author, AuthorAdmin)

The Admin
---------

One of the biggest changes in 1.0 is the new admin. The Django administrative
interface (``django.contrib.admin``) has been completely refactored; admin
definitions are now completely decoupled from model definitions, the framework
has been rewritten to use Django's new form-handling library and redesigned with
extensibility and customization in mind.

Practically, this means you'll need to rewrite all of your ``class Admin``
declarations. You've already seen in `models`_ above how to replace your ``class
Admin`` with a ``admin.site.register()`` call in an ``admin.py`` file. Below are
some more details on how to rewrite that ``Admin`` declaration into the new
syntax.

Use new inline syntax
~~~~~~~~~~~~~~~~~~~~~

The new ``edit_inline`` options have all been moved to ``admin.py``. Here's an
example:

Old (0.96)::

    class Parent(models.Model):
        ...

    class Child(models.Model):
        parent = models.ForeignKey(Parent, edit_inline=models.STACKED, num_in_admin=3)


New (1.0)::

    class ChildInline(admin.StackedInline):
        model = Child
        extra = 3

    class ParentAdmin(admin.ModelAdmin):
        model = Parent
        inlines = [ChildInline]

    admin.site.register(Parent, ParentAdmin)

See :ref:`admin-inlines` for more details.

Simplify ``fields``, or use ``fieldsets``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The old ``fields`` syntax was quite confusing, and has been simplified. The old
syntax still works, but you'll need to use ``fieldsets`` instead.

Old (0.96)::

    class ModelOne(models.Model):
        ...

        class Admin:
            fields = (
                (None, {'fields': ('foo','bar')}),
            )

    class ModelTwo(models.Model):
        ...

        class Admin:
            fields = (
                ('group1', {'fields': ('foo','bar'),   'classes': 'collapse'}),
                ('group2', {'fields': ('spam','eggs'), 'classes': 'collapse wide'}),
            )


New (1.0)::

    class ModelOneAdmin(admin.ModelAdmin):
        fields = ('foo', 'bar')

    class ModelTwoAdmin(admin.ModelAdmin):
        fieldsets = (
            ('group1', {'fields': ('foo','bar'),   'classes': 'collapse'}),
            ('group2', {'fields': ('spam','eggs'), 'classes': 'collapse wide'}),
        )


.. seealso::

    * More detailed information about the changes and the reasons behind them
      can be found on the `NewformsAdminBranch wiki page`__

    * The new admin comes with a ton of new features; you can read about them in
      the :doc:`admin documentation </ref/contrib/admin/index>`.

    __ https://code.djangoproject.com/wiki/NewformsAdminBranch

URLs
----

Update your root ``urls.py``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you're using the admin site, you need to update your root ``urls.py``.

Old (0.96) ``urls.py``::

    from django.conf.urls.defaults import *

    urlpatterns = patterns('',
        (r'^admin/', include('django.contrib.admin.urls')),

        # ... the rest of your URLs here ...
    )

New (1.0) ``urls.py``::

    from django.conf.urls.defaults import *

    # The next two lines enable the admin and load each admin.py file:
    from django.contrib import admin
    admin.autodiscover()

    urlpatterns = patterns('',
        (r'^admin/(.*)', admin.site.root),

        # ... the rest of your URLs here ...
    )

Views
-----

Use ``django.forms`` instead of ``newforms``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Replace ``django.newforms`` with ``django.forms`` -- Django 1.0 renamed the
``newforms`` module (introduced in 0.96) to plain old ``forms``. The
``oldforms`` module was also removed.

If you're already using the ``newforms`` library, and you used our recommended
``import`` statement syntax, all you have to do is change your import
statements.

Old::

    from django import newforms as forms

New::

    from django import forms

If you're using the old forms system (formerly known as ``django.forms`` and
``django.oldforms``), you'll have to rewrite your forms. A good place to start
is the :doc:`forms documentation </topics/forms/index>`

Handle uploaded files using the new API
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Replace use of uploaded files -- that is, entries in ``request.FILES`` -- as
simple dictionaries with the new
:class:`~django.core.files.uploadedfile.UploadedFile`. The old dictionary
syntax no longer works.

Thus, in a view like::

      def my_view(request):
          f = request.FILES['file_field_name']
          ...

...you'd need to make the following changes:

===================== =====================
Old (0.96)            New (1.0)
===================== =====================
``f['content']``      ``f.read()``
``f['filename']``     ``f.name``
``f['content-type']`` ``f.content_type``
===================== =====================

Work with file fields using the new API
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The internal implementation of :class:`django.db.models.FileField` have changed.
A visible result of this is that the way you access special attributes (URL,
filename, image size, etc.) of these model fields has changed. You will need to
make the following changes, assuming your model's
:class:`~django.db.models.FileField` is called ``myfile``:

=================================== ========================
Old (0.96)                           New (1.0)
=================================== ========================
``myfile.get_content_filename()``   ``myfile.content.path``
``myfile.get_content_url()``        ``myfile.content.url``
``myfile.get_content_size()``       ``myfile.content.size``
``myfile.save_content_file()``      ``myfile.content.save()``
``myfile.get_content_width()``      ``myfile.content.width``
``myfile.get_content_height()``     ``myfile.content.height``
=================================== ========================

Note that the ``width`` and ``height`` attributes only make sense for
:class:`~django.db.models.ImageField` fields. More details can be found in the
:doc:`model API </ref/models/fields>` documentation.

Use ``Paginator`` instead of ``ObjectPaginator``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The ``ObjectPaginator`` in 0.96 has been removed and replaced with an improved
version, :class:`django.core.paginator.Paginator`.

Templates
---------

Learn to love autoescaping
~~~~~~~~~~~~~~~~~~~~~~~~~~

By default, the template system now automatically HTML-escapes the output of
every variable. To learn more, see :ref:`automatic-html-escaping`.

To disable auto-escaping for an individual variable, use the :tfilter:`safe`
filter:

.. code-block:: html+django

      This will be escaped: {{ data }}
      This will not be escaped: {{ data|safe }}

To disable auto-escaping for an entire template, wrap the template (or just a
particular section of the template) in the :ttag:`autoescape` tag:

.. code-block:: html+django

      {% autoescape off %}
         ... unescaped template content here ...
      {% endautoescape %}

Less-common changes
===================

The following changes are smaller, more localized changes. They should only
affect more advanced users, but it's probably worth reading through the list and
checking your code for these things.

Signals
-------

* Add ``**kwargs`` to any registered signal handlers.

* Connect, disconnect, and send signals via methods on the
  :class:`~django.dispatch.Signal` object instead of through module methods in
  ``django.dispatch.dispatcher``.

* Remove any use of the ``Anonymous`` and ``Any`` sender options; they no longer
  exist. You can still receive signals sent by any sender by using
  ``sender=None``

* Make any custom signals you've declared into instances of
  :class:`django.dispatch.Signal` instead of anonymous objects.

Here's quick summary of the code changes you'll need to make:

=================================================  ======================================
Old (0.96)                                         New (1.0)
=================================================  ======================================
``def callback(sender)``                           ``def callback(sender, **kwargs)``
``sig = object()``                                 ``sig = django.dispatch.Signal()``
``dispatcher.connect(callback, sig)``              ``sig.connect(callback)``
``dispatcher.send(sig, sender)``                   ``sig.send(sender)``
``dispatcher.connect(callback, sig, sender=Any)``  ``sig.connect(callback, sender=None)``
=================================================  ======================================

Comments
--------

If you were using Django 0.96's ``django.contrib.comments`` app, you'll need to
upgrade to the new comments app introduced in 1.0. See the upgrade guide
for details.

Template tags
-------------

:ttag:`spaceless` tag
~~~~~~~~~~~~~~~~~~~~~

The spaceless template tag now removes *all* spaces between HTML tags, instead
of preserving a single space.

Local flavors
-------------

U.S. local flavor
~~~~~~~~~~~~~~~~~

``django.contrib.localflavor.usa`` has been renamed to
``django.contrib.localflavor.us``. This change was made to match the naming
scheme of other local flavors. To migrate your code, all you need to do is
change the imports.

Sessions
--------

Getting a new session key
~~~~~~~~~~~~~~~~~~~~~~~~~

``SessionBase.get_new_session_key()`` has been renamed to
``_get_new_session_key()``. ``get_new_session_object()`` no longer exists.

Fixtures
--------

Loading a row no longer calls ``save()``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Previously, loading a row automatically ran the model's ``save()`` method. This
is no longer the case, so any fields (for example: timestamps) that were
auto-populated by a ``save()`` now need explicit values in any fixture.

Settings
--------

Better exceptions
~~~~~~~~~~~~~~~~~

The old :exc:`EnvironmentError` has split into an
:exc:`ImportError` when Django fails to find the settings module
and a :exc:`RuntimeError` when you try to reconfigure settings
after having already used them.

:setting:`LOGIN_URL` has moved
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The :setting:`LOGIN_URL` constant moved from ``django.contrib.auth`` into the
``settings`` module. Instead of using ``from django.contrib.auth import
LOGIN_URL`` refer to :setting:`settings.LOGIN_URL <LOGIN_URL>`.

:setting:`APPEND_SLASH` behavior has been updated
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In 0.96, if a URL didn't end in a slash or have a period in the final
component of its path, and :setting:`APPEND_SLASH` was True, Django would
redirect to the same URL, but with a slash appended to the end. Now, Django
checks to see whether the pattern without the trailing slash would be matched
by something in your URL patterns. If so, no redirection takes place, because
it is assumed you deliberately wanted to catch that pattern.

For most people, this won't require any changes. Some people, though, have URL
patterns that look like this::

    r'/some_prefix/(.*)$'

Previously, those patterns would have been redirected to have a trailing
slash. If you always want a slash on such URLs, rewrite the pattern as::

    r'/some_prefix/(.*/)$'

Smaller model changes
---------------------

Different exception from ``get()``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Managers now return a :exc:`~django.core.exceptions.MultipleObjectsReturned`
exception instead of :exc:`AssertionError`:

Old (0.96)::

    try:
        Model.objects.get(...)
    except AssertionError:
        handle_the_error()

New (1.0)::

  try:
      Model.objects.get(...)
  except Model.MultipleObjectsReturned:
      handle_the_error()

``LazyDate`` has been fired
~~~~~~~~~~~~~~~~~~~~~~~~~~~

The ``LazyDate`` helper class no longer exists.

Default field values and query arguments can both be callable objects, so
instances of ``LazyDate`` can be replaced with a reference to ``datetime.datetime.now``:

Old (0.96)::

    class Article(models.Model):
        title = models.CharField(maxlength=100)
        published = models.DateField(default=LazyDate())

New (1.0)::

    import datetime

    class Article(models.Model):
        title = models.CharField(max_length=100)
        published = models.DateField(default=datetime.datetime.now)

``DecimalField`` is new, and ``FloatField`` is now a proper float
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Old (0.96)::

    class MyModel(models.Model):
        field_name = models.FloatField(max_digits=10, decimal_places=3)
        ...

New (1.0)::

    class MyModel(models.Model):
        field_name = models.DecimalField(max_digits=10, decimal_places=3)
        ...

If you forget to make this change, you will see errors about ``FloatField``
not taking a ``max_digits`` attribute in ``__init__``, because the new
``FloatField`` takes no precision-related arguments.

If you're using MySQL or PostgreSQL, no further changes are needed. The
database column types for ``DecimalField`` are the same as for the old
``FloatField``.

If you're using SQLite, you need to force the database to view the
appropriate columns as decimal types, rather than floats. To do this, you'll
need to reload your data. Do this after you have made the change to using
``DecimalField`` in your code and updated the Django code.

.. warning::

  **Back up your database first!**

  For SQLite, this means making a copy of the single file that stores the
  database (the name of that file is the ``DATABASE_NAME`` in your
  settings.py file).

To upgrade each application to use a ``DecimalField``, you can do the
following, replacing ``<app>`` in the code below with each app's name:

.. code-block:: console

      $ ./manage.py dumpdata --format=xml <app> > data-dump.xml
      $ ./manage.py reset <app>
      $ ./manage.py loaddata data-dump.xml

Notes:

1. It's important that you remember to use XML format in the first step of
   this process. We are exploiting a feature of the XML data dumps that makes
   porting floats to decimals with SQLite possible.

2. In the second step you will be asked to confirm that you are prepared to
   lose the data for the application(s) in question. Say yes; we'll restore
   this data in the third step, of course.

3. ``DecimalField`` is not used in any of the apps shipped with Django prior
   to this change being made, so you do not need to worry about performing
   this procedure for any of the standard Django models.

If something goes wrong in the above process, just copy your backed up
database file over the original file and start again.

Internationalization
--------------------

:func:`django.views.i18n.set_language` now requires a POST request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Previously, a GET request was used. The old behavior meant that state (the
locale used to display the site) could be changed by a GET request, which is
against the HTTP specification's recommendations. Code calling this view must
ensure that a POST request is now made, instead of a GET. This means you can
no longer use a link to access the view, but must use a form submission of
some kind (e.g. a button).

``_()`` is no longer in builtins
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

``_()`` (the callable object whose name is a single underscore) is no longer
monkeypatched into builtins -- that is, it's no longer available magically in
every module.

If you were previously relying on ``_()`` always being present, you should now
explicitly import ``ugettext`` or ``ugettext_lazy``, if appropriate, and alias
it to ``_`` yourself::

    from django.utils.translation import ugettext as _

HTTP request/response objects
-----------------------------

Dictionary access to ``HttpRequest``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

``HttpRequest`` objects no longer directly support dictionary-style
access; previously, both ``GET`` and ``POST`` data were directly
available on the ``HttpRequest`` object (e.g., you could check for a
piece of form data by using ``if 'some_form_key' in request`` or by
reading ``request['some_form_key']``. This is no longer supported; if
you need access to the combined ``GET`` and ``POST`` data, use
``request.REQUEST`` instead.

It is strongly suggested, however, that you always explicitly look in
the appropriate dictionary for the type of request you expect to
receive (``request.GET`` or ``request.POST``); relying on the combined
``request.REQUEST`` dictionary can mask the origin of incoming data.

Accessing ``HTTPResponse`` headers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

``django.http.HttpResponse.headers`` has been renamed to ``_headers`` and
:class:`~django.http.HttpResponse` now supports containment checking directly.
So use ``if header in response:`` instead of ``if header in response.headers:``.

Generic relations
-----------------

Generic relations have been moved out of core
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The generic relation classes -- ``GenericForeignKey`` and ``GenericRelation``
-- have moved into the :mod:`django.contrib.contenttypes` module.

Testing
-------

:meth:`django.test.Client.login` has changed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Old (0.96)::

    from django.test import Client
    c = Client()
    c.login('/path/to/login','myuser','mypassword')

New (1.0)::

    # ... same as above, but then:
    c.login(username='myuser', password='mypassword')

Management commands
-------------------

Running management commands from your code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:mod:`django.core.management` has been greatly refactored.

Calls to management services in your code now need to use
``call_command``. For example, if you have some test code that calls flush and
load_data::

      from django.core import management
      management.flush(verbosity=0, interactive=False)
      management.load_data(['test_data'], verbosity=0)

...you'll need to change this code to read::

      from django.core import management
      management.call_command('flush', verbosity=0, interactive=False)
      management.call_command('loaddata', 'test_data', verbosity=0)

Subcommands must now precede options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

``django-admin.py`` and ``manage.py`` now require subcommands to precede
options. So:

.. code-block:: console

      $ django-admin.py --settings=foo.bar runserver

...no longer works and should be changed to:

.. code-block:: console

      $ django-admin.py runserver --settings=foo.bar

Syndication
-----------

``Feed.__init__`` has changed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The ``__init__()`` method of the syndication framework's ``Feed`` class now
takes an ``HttpRequest`` object as its second parameter, instead of the feed's
URL. This allows the syndication framework to work without requiring the sites
framework. This only affects code that subclasses ``Feed`` and overrides the
``__init__()`` method, and code that calls ``Feed.__init__()`` directly.

Data structures
---------------

``SortedDictFromList`` is gone
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

``django.newforms.forms.SortedDictFromList`` was removed.
``django.utils.datastructures.SortedDict`` can now be instantiated with
a sequence of tuples.

To update your code:

1. Use ``django.utils.datastructures.SortedDict`` wherever you were
   using ``django.newforms.forms.SortedDictFromList``.

2. Because ``django.utils.datastructures.SortedDict.copy`` doesn't
   return a deepcopy as ``SortedDictFromList.copy()`` did, you will need
   to update your code if you were relying on a deepcopy. Do this by using
   ``copy.deepcopy`` directly.

Database backend functions
--------------------------

Database backend functions have been renamed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Almost *all* of the database backend-level functions have been renamed and/or
relocated. None of these were documented, but you'll need to change your code
if you're using any of these functions, all of which are in :mod:`django.db`:

=======================================  ===================================================
Old (0.96)                               New (1.0)
=======================================  ===================================================
``backend.get_autoinc_sql``              ``connection.ops.autoinc_sql``
``backend.get_date_extract_sql``         ``connection.ops.date_extract_sql``
``backend.get_date_trunc_sql``           ``connection.ops.date_trunc_sql``
``backend.get_datetime_cast_sql``        ``connection.ops.datetime_cast_sql``
``backend.get_deferrable_sql``           ``connection.ops.deferrable_sql``
``backend.get_drop_foreignkey_sql``      ``connection.ops.drop_foreignkey_sql``
``backend.get_fulltext_search_sql``      ``connection.ops.fulltext_search_sql``
``backend.get_last_insert_id``           ``connection.ops.last_insert_id``
``backend.get_limit_offset_sql``         ``connection.ops.limit_offset_sql``
``backend.get_max_name_length``          ``connection.ops.max_name_length``
``backend.get_pk_default_value``         ``connection.ops.pk_default_value``
``backend.get_random_function_sql``      ``connection.ops.random_function_sql``
``backend.get_sql_flush``                ``connection.ops.sql_flush``
``backend.get_sql_sequence_reset``       ``connection.ops.sequence_reset_sql``
``backend.get_start_transaction_sql``    ``connection.ops.start_transaction_sql``
``backend.get_tablespace_sql``           ``connection.ops.tablespace_sql``
``backend.quote_name``                   ``connection.ops.quote_name``
``backend.get_query_set_class``          ``connection.ops.query_set_class``
``backend.get_field_cast_sql``           ``connection.ops.field_cast_sql``
``backend.get_drop_sequence``            ``connection.ops.drop_sequence_sql``
``backend.OPERATOR_MAPPING``             ``connection.operators``
``backend.allows_group_by_ordinal``      ``connection.features.allows_group_by_ordinal``
``backend.allows_unique_and_pk``         ``connection.features.allows_unique_and_pk``
``backend.autoindexes_primary_keys``     ``connection.features.autoindexes_primary_keys``
``backend.needs_datetime_string_cast``   ``connection.features.needs_datetime_string_cast``
``backend.needs_upper_for_iops``         ``connection.features.needs_upper_for_iops``
``backend.supports_constraints``         ``connection.features.supports_constraints``
``backend.supports_tablespaces``         ``connection.features.supports_tablespaces``
``backend.uses_case_insensitive_names``  ``connection.features.uses_case_insensitive_names``
``backend.uses_custom_queryset``         ``connection.features.uses_custom_queryset``
=======================================  ===================================================

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.0.1 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.0.1.txt`)

==========================
Django 1.0.1 release notes
==========================

Welcome to Django 1.0.1!

This is the first "bugfix" release in the Django 1.0 series, improving
the stability and performance of the Django 1.0 codebase. As such,
Django 1.0.1 contains no new features (and, pursuant to :doc:`our
compatibility policy </misc/api-stability/>`, maintains backwards
compatibility with Django 1.0), but does contain a number of fixes
and other improvements. Django 1.0.1 is a recommended upgrade for any
development or deployment currently using or targeting Django 1.0.


Fixes and improvements in Django 1.0.1
======================================

Django 1.0.1 contains over two hundred fixes to the original Django
1.0 codebase; full details of every fix are available in `the
history of the 1.0.X branch`_, but here are some of the
highlights:

* Several fixes in ``django.contrib.comments``, pertaining to RSS
  feeds of comments, default ordering of comments and the XHTML and
  internationalization of the default templates for comments.

* Multiple fixes for Django's support of Oracle databases, including
  pagination support for GIS QuerySets, more efficient slicing of
  results and improved introspection of existing databases.

* Several fixes for query support in the Django object-relational
  mapper, including repeated setting and resetting of ordering and
  fixes for working with ``INSERT``-only queries.

* Multiple fixes for inline forms in formsets.

* Multiple fixes for ``unique`` and ``unique_together`` model
  constraints in automatically-generated forms.

* Fixed support for custom callable ``upload_to`` declarations when
  handling file uploads through automatically-generated forms.

* Fixed support for sorting an admin change list based on a callable
  attributes in ``list_display``.

* A fix to the application of autoescaping for literal strings passed
  to the ``join`` template filter. Previously, literal strings passed
  to ``join`` were automatically escaped, contrary to :ref:`the
  documented behavior for autoescaping and literal strings
  <string-literals-and-automatic-escaping>`. Literal strings
  passed to ``join`` are no longer automatically escaped, meaning you
  must now manually escape them; this is an incompatibility if you
  were relying on this bug, but not if you were relying on escaping
  behaving as documented.

* Improved and expanded translation files for many of the languages
  Django supports by default.

* And as always, a large number of improvements to Django's
  documentation, including both corrections to existing documents and
  expanded and new documentation.

.. _the history of the 1.0.X branch: https://github.com/django/django/commits/stable/1.0.x

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.0.2 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.0.2.txt`)

==========================
Django 1.0.2 release notes
==========================

Welcome to Django 1.0.2!

This is the second "bugfix" release in the Django 1.0 series,
improving the stability and performance of the Django 1.0 codebase. As
such, Django 1.0.2 contains no new features (and, pursuant to
:doc:`our compatibility policy </misc/api-stability>`, maintains backwards compatibility with Django
1.0.0), but does contain a number of fixes and other
improvements. Django 1.0.2 is a recommended upgrade for any
development or deployment currently using or targeting Django 1.0.


Fixes and improvements in Django 1.0.2
======================================

The primary reason behind this release is to remedy an issue in the
recently-released Django 1.0.1; the packaging scripts used for Django
1.0.1 omitted some directories from the final release package,
including one directory required by ``django.contrib.gis`` and part of
Django's unit-test suite.

Django 1.0.2 contains updated packaging scripts, and the release
package contains the directories omitted from Django 1.0.1. As such,
this release contains all of the fixes and improvements from Django
1.0.1; see :doc:`the Django 1.0.1 release notes </releases/1.0.1>` for
details.

Additionally, in the period since Django 1.0.1 was released:

* Updated Hebrew and Danish translations have been added.

* The default ``__repr__`` method of Django models has been made more
  robust in the face of bad Unicode data coming from the
  ``__unicode__`` method; rather than raise an exception in such
  cases, ``repr()`` will now contain the string "[Bad Unicode data]"
  in place of the invalid Unicode.

* A bug involving the interaction of Django's ``SafeUnicode`` class
  and the MySQL adapter has been resolved; ``SafeUnicode`` instances
  (generated, for example, by template rendering) can now be assigned
  to model attributes and saved to MySQL without requiring an explicit
  intermediate cast to ``unicode``.

* A bug affecting filtering on a nullable ``DateField`` in SQLite has
  been resolved.

* Several updates and improvements have been made to Django's
  documentation.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.0 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.0.txt`)

========================
Django 1.0 release notes
========================

Welcome to Django 1.0!

We've been looking forward to this moment for over three years, and it's finally
here. Django 1.0 represents the largest milestone in Django's development to
date: a Web framework that a group of perfectionists can truly be proud of.

Django 1.0 represents over three years of community development as an Open
Source project. Django's received contributions from hundreds of developers,
been translated into fifty languages, and today is used by developers on every
continent and in every kind of job.

An interesting historical note: when Django was first released in July 2005, the
initial released version of Django came from an internal repository at revision
number 8825. Django 1.0 represents revision 8961 of our public repository. It
seems fitting that our 1.0 release comes at the moment where community
contributions overtake those made privately.

Stability and forwards-compatibility
====================================

The release of Django 1.0 comes with a promise of API
stability and forwards-compatibility. In a nutshell, this means that code you
develop against Django 1.0 will continue to work against 1.1 unchanged, and you
should need to make only minor changes for any 1.X release.

See the :doc:`API stability guide </misc/api-stability>` for full details.

Backwards-incompatible changes
==============================

Django 1.0 has a number of backwards-incompatible changes from Django 0.96. If
you have apps written against Django 0.96 that you need to port, see our
detailed porting guide:

.. toctree::
   :maxdepth: 1

   1.0-porting-guide

A complete list of backwards-incompatible changes can be found at
https://code.djangoproject.com/wiki/BackwardsIncompatibleChanges.

What's new in Django 1.0
========================

A *lot*!

Since Django 0.96, we've made over 4,000 code commits, fixed more than 2,000
bugs, and edited, added, or removed around 350,000 lines of code. We've also
added 40,000 lines of new documentation, and greatly improved what was already
there.

In fact, new documentation is one of our favorite features of Django 1.0, so we
might as well start there. First, there's a new documentation site:

* https://docs.djangoproject.com/

The documentation has been greatly improved, cleaned up, and generally made
awesome. There's now dedicated search, indexes, and more.

We can't possibly document everything that's new in 1.0, but the documentation
will be your definitive guide. Anywhere you see something like:

.. versionadded:: 1.0

   This feature is new in Django 1.0

You'll know that you're looking at something new or changed.

The other major highlights of Django 1.0 are:

Re-factored admin application
-----------------------------

The Django administrative interface (``django.contrib.admin``) has been
completely refactored; admin definitions are now completely decoupled from model
definitions (no more ``class Admin`` declaration in models!), rewritten to use
Django's new form-handling library (introduced in the 0.96 release as
``django.newforms``, and now available as simply ``django.forms``) and
redesigned with extensibility and customization in mind. Full documentation for
the admin application is available online in the official Django documentation:

See the :doc:`admin reference </ref/contrib/admin/index>` for details

Improved Unicode handling
-------------------------

Django's internals have been refactored to use Unicode throughout; this
drastically simplifies the task of dealing with non-Western-European content and
data in Django. Additionally, utility functions have been provided to ease
interoperability with third-party libraries and systems which may or may not
handle Unicode gracefully. Details are available in Django's Unicode-handling
documentation.

See :doc:`/ref/unicode`.

An improved ORM
---------------

Django's object-relational mapper -- the component which provides the mapping
between Django model classes and your database, and which mediates your database
queries -- has been dramatically improved by a massive refactoring. For most
users of Django this is backwards-compatible; the public-facing API for database
querying underwent a few minor changes, but most of the updates took place in
the ORM's internals. A guide to the changes, including backwards-incompatible
modifications and mentions of new features opened up by this refactoring, is
`available on the Django wiki`__.

__ https://code.djangoproject.com/wiki/QuerysetRefactorBranch

Automatic escaping of template variables
----------------------------------------

To provide improved security against cross-site scripting (XSS) vulnerabilities,
Django's template system now automatically escapes the output of variables. This
behavior is configurable, and allows both variables and larger template
constructs to be marked as safe (requiring no escaping) or unsafe (requiring
escaping). A full guide to this feature is in the documentation for the
:ttag:`autoescape` tag.

``django.contrib.gis`` (GeoDjango)
----------------------------------

A project over a year in the making, this adds world-class GIS (`Geographic
Information Systems`_) support to Django, in the form of a ``contrib``
application. Its documentation is currently being maintained externally, and
will be merged into the main Django documentation shortly. Huge thanks go to
Justin Bronn, Jeremy Dunck, Brett Hoerner and Travis Pinney for their efforts in
creating and completing this feature.

See http://geodjango.org/ for details.

.. _Geographic Information Systems: https://en.wikipedia.org/wiki/Geographic_information_system

Pluggable file storage
----------------------

Django's built-in ``FileField`` and ``ImageField`` now can take advantage of
pluggable file-storage backends, allowing extensive customization of where and
how uploaded files get stored by Django. For details, see :doc:`the files
documentation </topics/files>`; big thanks go to Marty Alchin for putting in the
hard work to get this completed.

Jython compatibility
--------------------

Thanks to a lot of work from Leo Soto during a Google Summer of Code project,
Django's codebase has been refactored to remove incompatibilities with
`Jython`_, an implementation of Python written in Java, which runs Python code
on the Java Virtual Machine. Django is now compatible with the forthcoming
Jython 2.5 release.

See :doc:`/howto/jython`.

.. _Jython: http://www.jython.org/

Generic relations in forms and admin
------------------------------------

Classes are now included in ``django.contrib.contenttypes`` which can be used to
support generic relations in both the admin interface and in end-user forms. See
:ref:`the documentation for generic relations <generic-relations>` for details.

``INSERT``/``UPDATE`` distinction
---------------------------------

Although Django's default behavior of having a model's ``save()`` method
automatically determine whether to perform an ``INSERT`` or an ``UPDATE`` at the
SQL level is suitable for the majority of cases, there are occasional situations
where forcing one or the other is useful. As a result, models can now support an
additional parameter to ``save()`` which can force a specific operation.

See :ref:`ref-models-force-insert` for details.

Split ``CacheMiddleware``
-------------------------

Django's ``CacheMiddleware`` has been split into three classes:
``CacheMiddleware`` itself still exists and retains all of its previous
functionality, but it is now built from two separate middleware classes which
handle the two parts of caching (inserting into and reading from the cache)
separately, offering additional flexibility for situations where combining these
functions into a single middleware posed problems.

Full details, including updated notes on appropriate use, are in :doc:`the
caching documentation </topics/cache>`.

Refactored ``django.contrib.comments``
--------------------------------------

As part of a Google Summer of Code project, Thejaswi Puthraya carried out a
major rewrite and refactoring of Django's bundled comment system, greatly
increasing its flexibility and customizability.

Removal of deprecated features
------------------------------

A number of features and methods which had previously been marked as deprecated,
and which were scheduled for removal prior to the 1.0 release, are no longer
present in Django. These include imports of the form library from
``django.newforms`` (now located simply at ``django.forms``), the
``form_for_model`` and ``form_for_instance`` helper functions (which have been
replaced by ``ModelForm``) and a number of deprecated features which were
replaced by the dispatcher, file-uploading and file-storage refactorings
introduced in the Django 1.0 alpha releases.

Known issues
============

We've done our best to make Django 1.0 as solid as possible, but unfortunately
there are a couple of issues that we know about in the release.

Multi-table model inheritance with ``to_field``
-----------------------------------------------

If you're using :ref:`multiple table model inheritance
<multi-table-inheritance>`, be aware of this caveat: child models using a custom
``parent_link`` and ``to_field`` will cause database integrity errors. A set of
models like the following are **not valid**::

    class Parent(models.Model):
        name = models.CharField(max_length=10)
        other_value = models.IntegerField(unique=True)

    class Child(Parent):
        father = models.OneToOneField(Parent, primary_key=True, to_field="other_value", parent_link=True)
        value = models.IntegerField()

This bug will be fixed in the next release of Django.

Caveats with support of certain databases
-----------------------------------------

Django attempts to support as many features as possible on all database
backends. However, not all database backends are alike, and in particular many of the supported database differ greatly from version to version. It's a good idea to checkout our :doc:`notes on supported database </ref/databases>`:

- :ref:`mysql-notes`
- :ref:`sqlite-notes`
- :ref:`oracle-notes`

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.1.2 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.1.2.txt`)

==========================
Django 1.1.2 release notes
==========================

Welcome to Django 1.1.2!

This is the second "bugfix" release in the Django 1.1 series,
improving the stability and performance of the Django 1.1 codebase.

Django 1.1.2 maintains backwards compatibility with Django
1.1.0, but contain a number of fixes and other
improvements. Django 1.1.2 is a recommended upgrade for any
development or deployment currently using or targeting Django 1.1.

For full details on the new features, backwards incompatibilities, and
deprecated features in the 1.1 branch, see the :doc:`/releases/1.1`.

Backwards-incompatible changes in 1.1.2
=======================================

Test runner exit status code
----------------------------

The exit status code of the test runners (``tests/runtests.py`` and ``python
manage.py test``) no longer represents the number of failed tests, since a
failure of 256 or more tests resulted in a wrong exit status code.  The exit
status code for the test runner is now 0 for success (no failing tests) and 1
for any number of test failures.  If needed, the number of test failures can be
found at the end of the test runner's output.

Cookie encoding
---------------

To fix bugs with cookies in Internet Explorer, Safari, and possibly other
browsers, our encoding of cookie values was changed so that the characters
comma and semi-colon are treated as non-safe characters, and are therefore
encoded as ``\054`` and ``\073`` respectively.  This could produce backwards
incompatibilities, especially if you are storing comma or semi-colon in
cookies and have JavaScript code that parses and manipulates cookie values
client-side.

One new feature
===============

Ordinarily, a point release would not include new features, but in the
case of Django 1.1.2, we have made an exception to this rule. Django
1.2 (the next major release of Django) will contain a feature that
will improve protection against Cross-Site Request Forgery (CSRF)
attacks. This feature requires the use of a new :ttag:`csrf_token`
template tag in all forms that Django renders.

To make it easier to support both 1.1.X and 1.2.X versions of Django with
the same templates, we have decided to introduce the :ttag:`csrf_token` template
tag to the 1.1.X branch. In the 1.1.X branch, :ttag:`csrf_token` does nothing -
it has no effect on templates or form processing. However, it means that the
same template will work with Django 1.2.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.1.3 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.1.3.txt`)

==========================
Django 1.1.3 release notes
==========================

Welcome to Django 1.1.3!

This is the third "bugfix" release in the Django 1.1 series,
improving the stability and performance of the Django 1.1 codebase.

With one exception, Django 1.1.3 maintains backwards compatibility
with Django 1.1.2. It also contains a number of fixes and other
improvements. Django 1.1.2 is a recommended upgrade for any
development or deployment currently using or targeting Django 1.1.

For full details on the new features, backwards incompatibilities, and
deprecated features in the 1.1 branch, see the :doc:`/releases/1.1`.

Backwards incompatible changes
==============================

Restricted filters in admin interface
-------------------------------------

The Django administrative interface, django.contrib.admin, supports
filtering of displayed lists of objects by fields on the corresponding
models, including across database-level relationships. This is
implemented by passing lookup arguments in the querystring portion of
the URL, and options on the ModelAdmin class allow developers to
specify particular fields or relationships which will generate
automatic links for filtering.

One historically-undocumented and -unofficially-supported feature has
been the ability for a user with sufficient knowledge of a model's
structure and the format of these lookup arguments to invent useful
new filters on the fly by manipulating the querystring.

However, it has been demonstrated that this can be abused to gain
access to information outside of an admin user's permissions; for
example, an attacker with access to the admin and sufficient knowledge
of model structure and relations could construct query strings which --
with repeated use of regular-expression lookups supported by the
Django database API -- expose sensitive information such as users'
password hashes.

To remedy this, django.contrib.admin will now validate that
querystring lookup arguments either specify only fields on the model
being viewed, or cross relations which have been explicitly
whitelisted by the application developer using the pre-existing
mechanism mentioned above. This is backwards-incompatible for any
users relying on the prior ability to insert arbitrary lookups.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.1.4 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.1.4.txt`)

==========================
Django 1.1.4 release notes
==========================

Welcome to Django 1.1.4!

This is the fourth "bugfix" release in the Django 1.1 series,
improving the stability and performance of the Django 1.1 codebase.

With one exception, Django 1.1.4 maintains backwards compatibility
with Django 1.1.3. It also contains a number of fixes and other
improvements. Django 1.1.4 is a recommended upgrade for any
development or deployment currently using or targeting Django 1.1.

For full details on the new features, backwards incompatibilities, and
deprecated features in the 1.1 branch, see the :doc:`/releases/1.1`.

Backwards incompatible changes
==============================

CSRF exception for AJAX requests
--------------------------------

Django includes a CSRF-protection mechanism, which makes use of a
token inserted into outgoing forms. Middleware then checks for the
token's presence on form submission, and validates it.

Prior to Django 1.2.5, our CSRF protection made an exception for AJAX
requests, on the following basis:

* Many AJAX toolkits add an X-Requested-With header when using
  XMLHttpRequest.

* Browsers have strict same-origin policies regarding
  XMLHttpRequest.

* In the context of a browser, the only way that a custom header
  of this nature can be added is with XMLHttpRequest.

Therefore, for ease of use, we did not apply CSRF checks to requests
that appeared to be AJAX on the basis of the X-Requested-With header.
The Ruby on Rails web framework had a similar exemption.

Recently, engineers at Google made members of the Ruby on Rails
development team aware of a combination of browser plugins and
redirects which can allow an attacker to provide custom HTTP headers
on a request to any website. This can allow a forged request to appear
to be an AJAX request, thereby defeating CSRF protection which trusts
the same-origin nature of AJAX requests.

Michael Koziarski of the Rails team brought this to our attention, and
we were able to produce a proof-of-concept demonstrating the same
vulnerability in Django's CSRF handling.

To remedy this, Django will now apply full CSRF validation to all
requests, regardless of apparent AJAX origin. This is technically
backwards-incompatible, but the security risks have been judged to
outweigh the compatibility concerns in this case.

Additionally, Django will now accept the CSRF token in the custom HTTP
header X-CSRFTOKEN, as well as in the form submission itself, for ease
of use with popular JavaScript toolkits which allow insertion of
custom headers into all AJAX requests.

Please see the :ref:`CSRF docs for example jQuery code <csrf-ajax>`
that demonstrates this technique, ensuring that you are looking at the
documentation for your version of Django, as the exact code necessary
is different for some older versions of Django.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.1 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.1.txt`)

========================
Django 1.1 release notes
========================

July 29, 2009

Welcome to Django 1.1!

Django 1.1 includes a number of nifty :ref:`new features <whats-new-1.1>`, lots
of bug fixes, and an easy upgrade path from Django 1.0.

.. _backwards-incompatible-changes-1.1:

Backwards-incompatible changes in 1.1
=====================================

Django has a policy of :doc:`API stability </misc/api-stability>`. This means
that, in general, code you develop against Django 1.0 should continue to work
against 1.1 unchanged. However, we do sometimes make backwards-incompatible
changes if they're necessary to resolve bugs, and there are a handful of such
(minor) changes between Django 1.0 and Django 1.1.

Before upgrading to Django 1.1 you should double-check that the following
changes don't impact you, and upgrade your code if they do.

Changes to constraint names
---------------------------

Django 1.1 modifies the method used to generate database constraint names so
that names are consistent regardless of machine word size. This change is
backwards incompatible for some users.

If you are using a 32-bit platform, you're off the hook; you'll observe no
differences as a result of this change.

However, **users on 64-bit platforms may experience some problems** using the
``reset`` management command. Prior to this change, 64-bit platforms
would generate a 64-bit, 16 character digest in the constraint name; for
example::

    ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_5e8f10c132091d1e FOREIGN KEY ...

Following this change, all platforms, regardless of word size, will generate a
32-bit, 8 character digest in the constraint name; for example::

    ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_32091d1e FOREIGN KEY ...

As a result of this change, you will not be able to use the ``reset``
management command on any table made by a 64-bit machine. This is because the
new generated name will not match the historically generated name; as a
result, the SQL constructed by the reset command will be invalid.

If you need to reset an application that was created with 64-bit constraints,
you will need to manually drop the old constraint prior to invoking
``reset``.

Test cases are now run in a transaction
---------------------------------------

Django 1.1 runs tests inside a transaction, allowing better test performance
(see `test performance improvements`_ for details).

This change is slightly backwards incompatible if existing tests need to test
transactional behavior, if they rely on invalid assumptions about the test
environment, or if they require a specific test case ordering.

For these cases, :class:`~django.test.TransactionTestCase` can be used instead.
This is a just a quick fix to get around test case errors revealed by the new
rollback approach; in the long-term tests should be rewritten to correct the
test case.

.. _removed-setremoteaddrfromforwardedfor-middleware:

Removed ``SetRemoteAddrFromForwardedFor`` middleware
----------------------------------------------------

For convenience, Django 1.0 included an optional middleware class --
``django.middleware.http.SetRemoteAddrFromForwardedFor`` -- which updated the
value of ``REMOTE_ADDR`` based on the HTTP ``X-Forwarded-For`` header commonly
set by some proxy configurations.

It has been demonstrated that this mechanism cannot be made reliable enough for
general-purpose use, and that (despite documentation to the contrary) its
inclusion in Django may lead application developers to assume that the value of
``REMOTE_ADDR`` is "safe" or in some way reliable as a source of authentication.

While not directly a security issue, we've decided to remove this middleware
with the Django 1.1 release. It has been replaced with a class that does nothing
other than raise a ``DeprecationWarning``.

If you've been relying on this middleware, the easiest upgrade path is:

* Examine `the code as it existed before it was removed`__.

* Verify that it works correctly with your upstream proxy, modifying
  it to support your particular proxy (if necessary).

* Introduce your modified version of ``SetRemoteAddrFromForwardedFor`` as a
  piece of middleware in your own project.

__ https://github.com/django/django/blob/91f18400cc0fb37659e2dbaab5484ff2081f1f30/django/middleware/http.py#L33

Names of uploaded files are available later
-------------------------------------------

.. currentmodule:: django.db.models

In Django 1.0, files uploaded and stored in a model's :class:`FileField` were
saved to disk before the model was saved to the database. This meant that the
actual file name assigned to the file was available before saving. For example,
it was available in a model's pre-save signal handler.

In Django 1.1 the file is saved as part of saving the model in the database, so
the actual file name used on disk cannot be relied on until *after* the model
has been saved.

Changes to how model formsets are saved
---------------------------------------

In Django 1.1, :class:`~django.forms.models.BaseModelFormSet` now calls
``ModelForm.save()``.

This is backwards-incompatible if you were modifying ``self.initial`` in a model
formset's ``__init__``, or if you relied on the internal ``_total_form_count``
or ``_initial_form_count`` attributes of BaseFormSet. Those attributes are now
public methods.

Fixed the ``join`` filter's escaping behavior
---------------------------------------------

The :tfilter:`join` filter no longer escapes the literal value that is
passed in for the connector.

This is backwards incompatible for the special situation of the literal string
containing one of the five special HTML characters. Thus, if you were writing
``{{ foo|join:"&" }}``, you now have to write ``{{ foo|join:"&amp;" }}``.

The previous behavior was a bug and contrary to what was documented
and expected.

Permanent redirects and the ``redirect_to()`` generic view
----------------------------------------------------------

Django 1.1 adds a ``permanent`` argument to the
``django.views.generic.simple.redirect_to()`` view. This is technically
backwards-incompatible if you were using the ``redirect_to`` view with a
format-string key called 'permanent', which is highly unlikely.

.. _deprecated-features-1.1:

Features deprecated in 1.1
==========================

One feature has been marked as deprecated in Django 1.1:

* You should no longer use ``AdminSite.root()`` to register that admin
  views. That is, if your URLconf contains the line::

        (r'^admin/(.*)', admin.site.root),

  You should change it to read::

        (r'^admin/', include(admin.site.urls)),

You should begin to remove use of this feature from your code immediately.

``AdminSite.root`` will raise a ``PendingDeprecationWarning`` if used in
Django 1.1. This warning is hidden by default. In Django 1.2, this warning will
be upgraded to a ``DeprecationWarning``, which will be displayed loudly. Django
1.3 will remove ``AdminSite.root()`` entirely.

For more details on our deprecation policies and strategy, see
:doc:`/internals/release-process`.

.. _whats-new-1.1:

What's new in Django 1.1
========================

Quite a bit: since Django 1.0, we've made 1,290 code commits, fixed 1,206 bugs,
and added roughly 10,000 lines of documentation.

The major new features in Django 1.1 are:

ORM improvements
----------------

.. currentmodule:: django.db.models

Two major enhancements have been added to Django's object-relational mapper
(ORM): aggregate support, and query expressions.

Aggregate support
~~~~~~~~~~~~~~~~~

It's now possible to run SQL aggregate queries (i.e. ``COUNT()``, ``MAX()``,
``MIN()``, etc.) from within Django's ORM. You can choose to either return the
results of the aggregate directly, or else annotate the objects in a
:class:`~django.db.models.query.QuerySet` with the results of the aggregate
query.

This feature is available as new
:meth:`~django.db.models.query.QuerySet.aggregate` and
:meth:`~django.db.models.query.QuerySet.annotate` methods, and is covered in
detail in :doc:`the ORM aggregation documentation </topics/db/aggregation>`.

Query expressions
~~~~~~~~~~~~~~~~~

Queries can now refer to a another field on the query and can traverse
relationships to refer to fields on related models. This is implemented in the
new :class:`~django.db.models.F` object; for full details, including examples,
consult the :class:`F expressions documentation <django.db.models.F>`.

Model improvements
------------------

A number of features have been added to Django's model layer:

"Unmanaged" models
~~~~~~~~~~~~~~~~~~

You can now control whether or not Django manages the life-cycle of the database
tables for a model using the :attr:`~Options.managed` model option. This
defaults to ``True``, meaning that Django will create the appropriate database
tables in ``syncdb`` and remove them as part of the ``reset``
command. That is, Django *manages* the database table's lifecycle.

If you set this to ``False``, however, no database table creating or deletion
will be automatically performed for this model. This is useful if the model
represents an existing table or a database view that has been created by some
other means.

For more details, see the documentation for the :attr:`~Options.managed`
option.

Proxy models
~~~~~~~~~~~~

You can now create :ref:`proxy models <proxy-models>`: subclasses of existing
models that only add Python-level (rather than database-level) behavior and
aren't represented by a new table. That is, the new model is a *proxy* for some
underlying model, which stores all the real data.

All the details can be found in the :ref:`proxy models documentation
<proxy-models>`. This feature is similar on the surface to unmanaged models,
so the documentation has an explanation of :ref:`how proxy models differ from
unmanaged models <proxy-vs-unmanaged-models>`.

Deferred fields
~~~~~~~~~~~~~~~

In some complex situations, your models might contain fields which could
contain a lot of data (for example, large text fields), or require expensive
processing to convert them to Python objects. If you know you don't need those
particular fields, you can now tell Django not to retrieve them from the
database.

You'll do this with the new queryset methods
:meth:`~django.db.models.query.QuerySet.defer` and
:meth:`~django.db.models.query.QuerySet.only`.

Testing improvements
--------------------

A few notable improvements have been made to the :doc:`testing framework
</topics/testing/index>`.

Test performance improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. currentmodule:: django.test

Tests written using Django's :doc:`testing framework </topics/testing/index>` now run
dramatically faster (as much as 10 times faster in many cases).

This was accomplished through the introduction of transaction-based tests: when
using :class:`django.test.TestCase`, your tests will now be run in a transaction
which is rolled back when finished, instead of by flushing and re-populating the
database. This results in an immense speedup for most types of unit tests. See
the documentation for :class:`TestCase` and :class:`TransactionTestCase` for a
full description, and some important notes on database support.

Test client improvements
------------------------

A couple of small -- but highly useful -- improvements have been made to the
test client:

* The test :class:`Client` now can automatically follow redirects with the
  ``follow`` argument to :meth:`Client.get` and :meth:`Client.post`. This
  makes testing views that issue redirects simpler.

* It's now easier to get at the template context in the response returned
  the test client: you'll simply access the context as
  ``request.context[key]``. The old way, which treats ``request.context`` as
  a list of contexts, one for each rendered template in the inheritance
  chain, is still available if you need it.

New admin features
------------------

Django 1.1 adds a couple of nifty new features to Django's admin interface:

Editable fields on the change list
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can now make fields editable on the admin list views via the new
:ref:`list_editable <admin-list-editable>` admin option. These fields will show
up as form widgets on the list pages, and can be edited and saved in bulk.

Admin "actions"
~~~~~~~~~~~~~~~

You can now define :doc:`admin actions </ref/contrib/admin/actions>` that can
perform some action to a group of models in bulk. Users will be able to select
objects on the change list page and then apply these bulk actions to all
selected objects.

Django ships with one pre-defined admin action to delete a group of objects in
one fell swoop.

Conditional view processing
---------------------------

Django now has much better support for :doc:`conditional view processing
</topics/conditional-view-processing>` using the standard ``ETag`` and
``Last-Modified`` HTTP headers. This means you can now easily short-circuit
view processing by testing less-expensive conditions. For many views this can
lead to a serious improvement in speed and reduction in bandwidth.

URL namespaces
--------------

Django 1.1 improves :ref:`named URL patterns <naming-url-patterns>` with the
introduction of URL "namespaces."

In short, this feature allows the same group of URLs, from the same application,
to be included in a Django URLConf multiple times, with varying (and potentially
nested) named prefixes which will be used when performing reverse resolution. In
other words, reusable applications like Django's admin interface may be
registered multiple times without URL conflicts.

For full details, see :ref:`the documentation on defining URL namespaces
<topics-http-defining-url-namespaces>`.

GeoDjango
---------

In Django 1.1, GeoDjango_ (i.e. ``django.contrib.gis``) has several new
features:

* Support for SpatiaLite_ -- a spatial database for SQLite -- as a spatial
  backend.

* Geographic aggregates (``Collect``, ``Extent``, ``MakeLine``, ``Union``)
  and ``F`` expressions.

* New ``GeoQuerySet`` methods: ``collect``, ``geojson``, and
  ``snap_to_grid``.

* A new list interface methods for ``GEOSGeometry`` objects.

For more details, see the GeoDjango documentation.

.. _geodjango: http://geodjango.org/
.. _spatialite: http://www.gaia-gis.it/gaia-sins/

Other improvements
------------------

Other new features and changes introduced since Django 1.0 include:

* The :doc:`CSRF protection middleware </ref/csrf>` has been split into
  two classes -- ``CsrfViewMiddleware`` checks incoming requests, and
  ``CsrfResponseMiddleware`` processes outgoing responses. The combined
  ``CsrfMiddleware`` class (which does both) remains for
  backwards-compatibility, but using the split classes is now recommended in
  order to allow fine-grained control of when and where the CSRF processing
  takes place.

* ``reverse()`` and code which uses it (e.g., the ``{% url %}`` template tag)
  now works with URLs in Django's administrative site, provided that the admin
  URLs are set up via ``include(admin.site.urls)`` (sending admin requests to
  the ``admin.site.root`` view still works, but URLs in the admin will not be
  "reversible" when configured this way).

* The ``include()`` function in Django URLconf modules can now accept sequences
  of URL patterns (generated by ``patterns()``) in addition to module names.

* Instances of Django forms (see :doc:`the forms overview </topics/forms/index>`)
  now have two additional methods, ``hidden_fields()`` and ``visible_fields()``,
  which return the list of hidden -- i.e., ``<input type="hidden">`` -- and
  visible fields on the form, respectively.

* The ``redirect_to`` generic view
  now accepts an additional keyword argument
  ``permanent``. If ``permanent`` is ``True``, the view will emit an HTTP
  permanent redirect (status code 301). If ``False``, the view will emit an HTTP
  temporary redirect (status code 302).

* A new database lookup type -- ``week_day`` -- has been added for ``DateField``
  and ``DateTimeField``. This type of lookup accepts a number between 1 (Sunday)
  and 7 (Saturday), and returns objects where the field value matches that day
  of the week. See :ref:`the full list of lookup types <field-lookups>` for
  details.

* The ``{% for %}`` tag in Django's template language now accepts an optional
  ``{% empty %}`` clause, to be displayed when ``{% for %}`` is asked to loop
  over an empty sequence. See :doc:`the list of built-in template tags
  </ref/templates/builtins>` for examples of this.

* The :djadmin:`dumpdata` management command now accepts individual
  model names as arguments, allowing you to export the data just from
  particular models.

* There's a new :tfilter:`safeseq` template filter which works just like
  :tfilter:`safe` for lists, marking each item in the list as safe.

* :doc:`Cache backends </topics/cache>` now support ``incr()`` and
  ``decr()`` commands to increment and decrement the value of a cache key.
  On cache backends that support atomic increment/decrement -- most
  notably, the memcached backend -- these operations will be atomic, and
  quite fast.

* Django now can :doc:`easily delegate authentication to the Web server
  </howto/auth-remote-user>` via a new authentication backend that supports
  the standard ``REMOTE_USER`` environment variable used for this purpose.

* There's a new :func:`django.shortcuts.redirect` function that makes it
  easier to issue redirects given an object, a view name, or a URL.

* The ``postgresql_psycopg2`` backend now supports :ref:`native PostgreSQL
  autocommit <postgresql-notes>`. This is an advanced, PostgreSQL-specific
  feature, that can make certain read-heavy applications a good deal
  faster.

What's next?
============

We'll take a short break, and then work on Django 1.2 will begin -- no rest for
the weary! If you'd like to help, discussion of Django development, including
progress toward the 1.2 release, takes place daily on the django-developers
mailing list:

* https://groups.google.com/group/django-developers

... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. Feel free to
join the discussions!

Django's online documentation also includes pointers on how to contribute to
Django:

* :doc:`How to contribute to Django </internals/contributing/index>`

Contributions on any level -- developing code, writing documentation or simply
triaging tickets and helping to test proposed bugfixes -- are always welcome and
appreciated.

And that's the way it is.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.10.1 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.10.1.txt`)

===========================
Django 1.10.1 release notes
===========================

*September 1, 2016*

Django 1.10.1 fixes several bugs in 1.10.

Bugfixes
========

* Fixed a crash in MySQL connections where ``SELECT @@SQL_AUTO_IS_NULL``
  doesn't return a result (:ticket:`26991`).

* Allowed ``User.is_authenticated`` and ``User.is_anonymous`` properties to be
  compared using ``==``, ``!=``, and ``|`` (:ticket:`26988`, :ticket:`27154`).

* Removed the broken ``BaseCommand.usage()`` method which was for
  ``optparse`` support (:ticket:`27000`).

* Fixed a checks framework crash with an empty ``Meta.default_permissions``
  (:ticket:`26997`).

* Fixed a regression in the number of queries when using ``RadioSelect`` with a
  ``ModelChoiceField`` form field (:ticket:`27001`).

* Fixed a crash if ``request.META['CONTENT_LENGTH']`` is an empty string
  (:ticket:`27005`).

* Fixed the ``isnull`` lookup on a ``ForeignKey`` with its ``to_field``
  pointing to a ``CharField`` or pointing to a ``CharField`` defined with
  ``primary_key=True`` (:ticket:`26983`).

* Prevented the ``migrate`` command from raising
  ``InconsistentMigrationHistory`` in the presence of unapplied squashed
  migrations (:ticket:`27004`).

* Fixed a regression in ``Client.force_login()`` which required specifying a
  ``backend`` rather than automatically using the first one if multiple
  backends are configured (:ticket:`27027`).

* Made ``QuerySet.bulk_create()`` properly initialize model instances on
  backends, such as PostgreSQL, that support returning the IDs of the created
  records so that many-to-many relationships can be used on the new objects
  (:ticket:`27026`).

* Fixed crash of ``django.views.static.serve()`` with ``show_indexes`` enabled
  (:ticket:`26973`).

* Fixed ``ClearableFileInput`` to avoid the ``required`` HTML attribute when
  initial data exists (:ticket:`27037`).

* Fixed annotations with database functions when combined with lookups on
  PostGIS (:ticket:`27014`).

* Reallowed the ``{% for %}`` tag to unpack any iterable (:ticket:`27058`).

* Made ``makemigrations`` skip inconsistent history checks on non-default
  databases if database routers aren't in use or if no apps can be migrated
  to the database (:ticket:`27054`, :ticket:`27110`, :ticket:`27142`).

* Removed duplicated managers in ``Model._meta.managers`` (:ticket:`27073`).

* Fixed ``contrib.admindocs`` crash when a view is in a class, such as some of
  the admin views (:ticket:`27018`).

* Reverted a few admin checks that checked ``field.many_to_many`` back to
  ``isinstance(field, models.ManyToManyField)`` since it turned out the checks
  weren't suitable to be generalized like that (:ticket:`26998`).

* Added the database alias to the ``InconsistentMigrationHistory`` message
  raised by ``makemigrations`` and ``migrate`` (:ticket:`27089`).

* Fixed the creation of ``ContentType`` and ``Permission`` objects for models
  of applications without migrations when calling the ``migrate`` command with
  no migrations to apply (:ticket:`27044`).

* Included the already applied migration state changes in the ``Apps`` instance
  provided to the ``pre_migrate`` signal receivers to allow ``ContentType``
  renaming to be performed on model rename (:ticket:`27100`).

* Reallowed subclassing ``UserCreationForm`` without ``USERNAME_FIELD`` in
  ``Meta.fields`` (:ticket:`27111`).

* Fixed a regression in model forms where model fields with a ``default`` that
  didn't appear in POST data no longer used the ``default`` (:ticket:`27039`).

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.10 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.10.txt`)

=========================
Django 1.10 release notes
=========================

*August 1, 2016*

Welcome to Django 1.10!

These release notes cover the :ref:`new features <whats-new-1.10>`, as well as
some :ref:`backwards incompatible changes <backwards-incompatible-1.10>` you'll
want to be aware of when upgrading from Django 1.9 or older versions. We've
:ref:`dropped some features <removed-features-1.10>` that have reached the end
of their deprecation cycle, and we've :ref:`begun the deprecation process for
some features <deprecated-features-1.10>`.

See the :doc:`/howto/upgrade-version` guide if you're updating an existing
project.

Python compatibility
====================

Like Django 1.9, Django 1.10 requires Python 2.7, 3.4, or 3.5. We **highly
recommend** and only officially support the latest release of each series.

.. _whats-new-1.10:

What's new in Django 1.10
=========================

Full text search for PostgreSQL
-------------------------------

``django.contrib.postgres`` now includes a :doc:`collection of database
functions </ref/contrib/postgres/search>` to allow the use of the full text
search engine. You can search across multiple fields in your relational
database, combine the searches with other lookups, use different language
configurations and weightings, and rank the results by relevance.

It also now includes trigram support, using the :lookup:`trigram_similar`
lookup, and the :class:`~django.contrib.postgres.search.TrigramSimilarity` and
:class:`~django.contrib.postgres.search.TrigramDistance` expressions.

New-style middleware
--------------------

:doc:`A new style of middleware is introduced </topics/http/middleware>` to
solve the lack of strict request/response layering of the old-style of
middleware described in `DEP 0005
<https://github.com/django/deps/blob/master/final/0005-improved-middleware.rst>`_.
You'll need to :ref:`adapt old, custom middleware <upgrading-middleware>` and
switch from the ``MIDDLEWARE_CLASSES`` setting to the new :setting:`MIDDLEWARE`
setting to take advantage of the improvements.

Official support for Unicode usernames
--------------------------------------

The :class:`~django.contrib.auth.models.User` model in ``django.contrib.auth``
originally only accepted ASCII letters in usernames. Although it wasn't a
deliberate choice, Unicode characters have always been accepted when using
Python 3.

The username validator now explicitly accepts Unicode letters by
default on Python 3 only. This default behavior can be overridden by changing
the :attr:`~django.contrib.auth.models.User.username_validator` attribute of
the ``User`` model, or to any proxy of that model, using either
:class:`~django.contrib.auth.validators.ASCIIUsernameValidator` or
:class:`~django.contrib.auth.validators.UnicodeUsernameValidator`. Custom user
models may also use those validators.

Minor features
--------------

:mod:`django.contrib.admin`
~~~~~~~~~~~~~~~~~~~~~~~~~~~

* For sites running on a subpath, the default :attr:`URL for the "View site"
  link <django.contrib.admin.AdminSite.site_url>` at the top of each admin page
  will now point to ``request.META['SCRIPT_NAME']`` if set, instead of ``/``.

* The success message that appears after adding or editing an object now
  contains a link to the object's change form.

* All inline JavaScript is removed so you can enable the
  ``Content-Security-Policy`` HTTP header if you wish.

* The new :attr:`InlineModelAdmin.classes
  <django.contrib.admin.InlineModelAdmin.classes>` attribute allows specifying
  classes on inline fieldsets. Inlines with a ``collapse`` class will be
  initially collapsed and their header will have a small "show" link.

* If a user doesn't have the add permission, the ``object-tools`` block on a
  model's changelist will now be rendered (without the add button, of course).
  This makes it easier to add custom tools in this case.

* The :class:`~django.contrib.admin.models.LogEntry` model now stores change
  messages in a JSON structure so that the message can be dynamically translated
  using the current active language. A new ``LogEntry.get_change_message()``
  method is now the preferred way of retrieving the change message.

* Selected objects for fields in ``ModelAdmin.raw_id_fields`` now have a link
  to object's change form.

* Added "No date" and "Has date" choices for ``DateFieldListFilter`` if the
  field is nullable.

* The jQuery library embedded in the admin is upgraded from version 2.1.4 to
  2.2.3.

:mod:`django.contrib.auth`
~~~~~~~~~~~~~~~~~~~~~~~~~~

* Added support for the :ref:`Argon2 password hash <argon2_usage>`. It's
  recommended over PBKDF2, however, it's not the default as it requires a
  third-party library.

* The default iteration count for the PBKDF2 password hasher has been increased
  by 25%. This backwards compatible change will not affect users who have
  subclassed ``django.contrib.auth.hashers.PBKDF2PasswordHasher`` to change the
  default value.

* The :func:`~django.contrib.auth.views.logout` view sends "no-cache" headers
  to prevent an issue where Safari caches redirects and prevents a user from
  being able to log out.

* Added the optional ``backend`` argument to :func:`~django.contrib.auth.login`
  to allow using it without credentials.

* The new :setting:`LOGOUT_REDIRECT_URL` setting controls the redirect of the
  :func:`~django.contrib.auth.views.logout` view, if the view doesn't get a
  ``next_page`` argument.

* The new ``redirect_authenticated_user`` parameter for the
  :func:`~django.contrib.auth.views.login` view allows redirecting
  authenticated users visiting the login page.

* The new :class:`~django.contrib.auth.backends.AllowAllUsersModelBackend` and
  :class:`~django.contrib.auth.backends.AllowAllUsersRemoteUserBackend` ignore
  the value of ``User.is_active``, while
  :class:`~django.contrib.auth.backends.ModelBackend` and
  :class:`~django.contrib.auth.backends.RemoteUserBackend` now reject inactive
  users.

:mod:`django.contrib.gis`
~~~~~~~~~~~~~~~~~~~~~~~~~

* :ref:`Distance lookups <distance-lookups>` now accept expressions as the
  distance value parameter.

* The new :attr:`GEOSGeometry.unary_union
  <django.contrib.gis.geos.GEOSGeometry.unary_union>` property computes the
  union of all the elements of this geometry.

* Added the :meth:`GEOSGeometry.covers()
  <django.contrib.gis.geos.GEOSGeometry.covers>` binary predicate.

* Added the :meth:`GDALBand.statistics()
  <django.contrib.gis.gdal.GDALBand.statistics>` method and
  :attr:`~django.contrib.gis.gdal.GDALBand.mean`
  and :attr:`~django.contrib.gis.gdal.GDALBand.std` attributes.

* Added support for the :class:`~django.contrib.gis.db.models.MakeLine`
  aggregate and :class:`~django.contrib.gis.db.models.functions.GeoHash`
  function on SpatiaLite.

* Added support for the
  :class:`~django.contrib.gis.db.models.functions.Difference`,
  :class:`~django.contrib.gis.db.models.functions.Intersection`, and
  :class:`~django.contrib.gis.db.models.functions.SymDifference`
  functions on MySQL.

* Added support for instantiating empty GEOS geometries.

* The new :attr:`~django.contrib.gis.geos.WKTWriter.trim` and
  :attr:`~django.contrib.gis.geos.WKTWriter.precision` properties
  of :class:`~django.contrib.gis.geos.WKTWriter` allow controlling
  output of the fractional part of the coordinates in WKT.

* Added the :attr:`LineString.closed
  <django.contrib.gis.geos.LineString.closed>` and
  :attr:`MultiLineString.closed
  <django.contrib.gis.geos.MultiLineString.closed>` properties.

* The :doc:`GeoJSON serializer </ref/contrib/gis/serializers>` now outputs the
  primary key of objects in the ``properties`` dictionary if specific fields
  aren't specified.

* The ability to replicate input data on the :meth:`GDALBand.data()
  <django.contrib.gis.gdal.GDALBand.data>` method was added. Band data can
  now be updated with repeated values efficiently.

* Added database functions
  :class:`~django.contrib.gis.db.models.functions.IsValid` and
  :class:`~django.contrib.gis.db.models.functions.MakeValid`, as well as the
  :lookup:`isvalid` lookup, all for PostGIS. This allows filtering and
  repairing invalid geometries on the database side.

* Added raster support for all :doc:`spatial lookups
  </ref/contrib/gis/geoquerysets>`.

:mod:`django.contrib.postgres`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* For convenience, :class:`~django.contrib.postgres.fields.HStoreField` now
  casts its keys and values to strings.

:mod:`django.contrib.sessions`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* The :djadmin:`clearsessions` management command now removes file-based
  sessions.

:mod:`django.contrib.sites`
~~~~~~~~~~~~~~~~~~~~~~~~~~~

* The :class:`~django.contrib.sites.models.Site` model now supports
  :ref:`natural keys <topics-serialization-natural-keys>`.

:mod:`django.contrib.staticfiles`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* The :ttag:`static` template tag now uses ``django.contrib.staticfiles``
  if it's in ``INSTALLED_APPS``. This is especially useful for third-party apps
  which can now always use ``{% load static %}`` (instead of
  ``{% load staticfiles %}`` or ``{% load static from staticfiles %}``) and
  not worry about whether or not the ``staticfiles`` app is installed.

* You can :ref:`more easily customize <customize-staticfiles-ignore-patterns>`
  the ``collectstatic --ignore_patterns`` option with a custom ``AppConfig``.

Cache
~~~~~

* The file-based cache backend now uses the highest pickling protocol.

CSRF
~~~~

* The default :setting:`CSRF_FAILURE_VIEW`, ``views.csrf.csrf_failure()`` now
  accepts an optional ``template_name`` parameter, defaulting to
  ``'403_csrf.html'``, to control the template used to render the page.

* To protect against `BREACH`_ attacks, the CSRF protection mechanism now
  changes the form token value on every request (while keeping an invariant
  secret which can be used to validate the different tokens).

.. _BREACH: http://breachattack.com/

Database backends
~~~~~~~~~~~~~~~~~

* Temporal data subtraction was unified on all backends.

* If the database supports it, backends can set
  ``DatabaseFeatures.can_return_ids_from_bulk_insert=True`` and implement
  ``DatabaseOperations.fetch_returned_insert_ids()`` to set primary keys
  on objects created using ``QuerySet.bulk_create()``.

* Added keyword arguments to the ``as_sql()`` methods of various expressions
  (``Func``, ``When``, ``Case``, and ``OrderBy``) to allow database backends to
  customize them without mutating ``self``, which isn't safe when using
  different database backends. See the ``arg_joiner`` and ``**extra_context``
  parameters of :meth:`Func.as_sql() <django.db.models.Func.as_sql>` for an
  example.

File Storage
~~~~~~~~~~~~

* Storage backends now present a timezone-aware API with new methods
  :meth:`~django.core.files.storage.Storage.get_accessed_time`,
  :meth:`~django.core.files.storage.Storage.get_created_time`, and
  :meth:`~django.core.files.storage.Storage.get_modified_time`. They return a
  timezone-aware ``datetime`` if :setting:`USE_TZ` is ``True`` and a naive
  ``datetime`` in the local timezone otherwise.

* The new :meth:`Storage.generate_filename()
  <django.core.files.storage.Storage.generate_filename>` method makes it easier
  to implement custom storages that don't use the ``os.path`` calls previously
  in :class:`~django.db.models.FileField`.

Forms
~~~~~

* Form and widget ``Media`` is now served using
  :mod:`django.contrib.staticfiles` if installed.

* The ``<input>`` tag rendered by :class:`~django.forms.CharField` now includes
  a ``minlength`` attribute if the field has a ``min_length``.

* Required form fields now have the ``required`` HTML attribute. Set the new
  :attr:`Form.use_required_attribute <django.forms.Form.use_required_attribute>`
  attribute to ``False`` to disable it. The ``required`` attribute isn't
  included on forms of formsets because the browser validation may not be
  correct when adding and deleting formsets.

Generic Views
~~~~~~~~~~~~~

* The :class:`~django.views.generic.base.View` class can now be imported from
  ``django.views``.

Internationalization
~~~~~~~~~~~~~~~~~~~~

* The :func:`~django.conf.urls.i18n.i18n_patterns` helper function can now be
  used in a root URLConf specified using :attr:`request.urlconf
  <django.http.HttpRequest.urlconf>`.

* By setting the new ``prefix_default_language`` parameter for
  :func:`~django.conf.urls.i18n.i18n_patterns` to ``False``, you can allow
  accessing the default language without a URL prefix.

* :func:`~django.views.i18n.set_language` now returns a 204 status code (No
  Content) for AJAX requests when there is no ``next`` parameter in ``POST`` or
  ``GET``.

* The :class:`~django.views.i18n.JavaScriptCatalog` and
  :class:`~django.views.i18n.JSONCatalog` class-based views supersede the
  deprecated ``javascript_catalog()`` and ``json_catalog()`` function-based
  views. The new views are almost equivalent to the old ones except that by
  default the new views collect all JavaScript strings in the ``djangojs``
  translation domain from all installed apps rather than only the JavaScript
  strings from :setting:`LOCALE_PATHS`.

Management Commands
~~~~~~~~~~~~~~~~~~~

* :func:`~django.core.management.call_command` now returns the value returned
  from the ``command.handle()`` method.

* The new :option:`check --fail-level` option allows specifying the message
  level that will cause the command to exit with a non-zero status.

* The new :option:`makemigrations --check` option makes the command exit
  with a non-zero status when model changes without migrations are detected.

* :djadmin:`makemigrations` now displays the path to the migration files that
  it generates.

* The :option:`shell --interface` option now accepts ``python`` to force use of
  the "plain" Python interpreter.

* The new :option:`shell --command` option lets you run a command as Django and
  exit, instead of opening the interactive shell.

* Added a warning to :djadmin:`dumpdata` if a proxy model is specified (which
  results in no output) without its concrete parent.

* The new :attr:`BaseCommand.requires_migrations_checks
  <django.core.management.BaseCommand.requires_migrations_checks>` attribute
  may be set to ``True`` if you want your command to print a warning, like
  :djadmin:`runserver` does, if the set of migrations on disk don't match the
  migrations in the database.

* To assist with testing, :func:`~django.core.management.call_command` now
  accepts a command object as the first argument.

* The :djadmin:`shell` command supports tab completion on systems using
  ``libedit``, e.g. Mac OSX.

* The :djadmin:`inspectdb` command lets you choose what tables should be
  inspected by specifying their names as arguments.

Migrations
~~~~~~~~~~

* Added support for serialization of ``enum.Enum`` objects.

* Added the ``elidable`` argument to the
  :class:`~django.db.migrations.operations.RunSQL` and
  :class:`~django.db.migrations.operations.RunPython` operations to allow them
  to be removed when squashing migrations.

* Added support for :ref:`non-atomic migrations <non-atomic-migrations>` by
  setting the ``atomic`` attribute on a ``Migration``.

* The ``migrate`` and ``makemigrations`` commands now :ref:`check for a
  consistent migration history <migration-history-consistency>`. If they find
  some unapplied dependencies of an applied migration,
  ``InconsistentMigrationHistory`` is raised.

* The :func:`~django.db.models.signals.pre_migrate` and
  :func:`~django.db.models.signals.post_migrate` signals now dispatch their
  migration ``plan`` and ``apps``.

Models
~~~~~~

* Reverse foreign keys from proxy models are now propagated to their
  concrete class. The reverse relation attached by a
  :class:`~django.db.models.ForeignKey` pointing to a proxy model is now
  accessible as a descriptor on the proxied model class and may be referenced in
  queryset filtering.

* The new :meth:`Field.rel_db_type() <django.db.models.Field.rel_db_type>`
  method returns the database column data type for fields such as ``ForeignKey``
  and ``OneToOneField`` that point to another field.

* The :attr:`~django.db.models.Func.arity` class attribute is added to
  :class:`~django.db.models.Func`. This attribute can be used to set the number
  of arguments the function accepts.

* Added :class:`~django.db.models.BigAutoField` which acts much like an
  :class:`~django.db.models.AutoField` except that it is guaranteed
  to fit numbers from ``1`` to ``9223372036854775807``.

* :meth:`QuerySet.in_bulk() <django.db.models.query.QuerySet.in_bulk>`
  may be called without any arguments to return all objects in the queryset.

* :attr:`~django.db.models.ForeignKey.related_query_name` now supports
  app label and class interpolation using the ``'%(app_label)s'`` and
  ``'%(class)s'`` strings.

* Allowed overriding model fields inherited from abstract base classes.

* The :func:`~django.db.models.prefetch_related_objects` function is now a
  public API.

* :meth:`QuerySet.bulk_create() <django.db.models.query.QuerySet.bulk_create>`
  sets the primary key on objects when using PostgreSQL.

* Added the :class:`~django.db.models.functions.Cast` database function.

* A proxy model may now inherit multiple proxy models that share a common
  non-abstract parent class.

* Added :class:`~django.db.models.functions.datetime.Extract` functions
  to extract datetime components as integers, such as year and hour.

* Added :class:`~django.db.models.functions.datetime.Trunc` functions to
  truncate a date or datetime to a significant component. They enable queries
  like sales-per-day or sales-per-hour.

* ``Model.__init__()`` now sets values of virtual fields from its keyword
  arguments.

* The new :attr:`Meta.base_manager_name
  <django.db.models.Options.base_manager_name>` and
  :attr:`Meta.default_manager_name
  <django.db.models.Options.default_manager_name>` options allow controlling
  the :attr:`~django.db.models.Model._base_manager` and
  :attr:`~django.db.models.Model._default_manager`, respectively.

Requests and Responses
~~~~~~~~~~~~~~~~~~~~~~

* Added ``request.user`` to the debug view.

* Added :class:`~django.http.HttpResponse` methods
  :meth:`~django.http.HttpResponse.readable()` and
  :meth:`~django.http.HttpResponse.seekable()` to make an instance a
  stream-like object and allow wrapping it with :py:class:`io.TextIOWrapper`.

* Added the :attr:`HttpResponse.content_type
  <django.http.HttpRequest.content_type>` and
  :attr:`~django.http.HttpRequest.content_params` attributes which are
  parsed from the ``CONTENT_TYPE`` header.

* The parser for ``request.COOKIES`` is simplified to better match the behavior
  of browsers. ``request.COOKIES`` may now contain cookies that are invalid
  according to :rfc:`6265` but are possible to set via ``document.cookie``.

Serialization
~~~~~~~~~~~~~

* The ``django.core.serializers.json.DjangoJSONEncoder`` now knows how to
  serialize lazy strings, typically used for translatable content.

Templates
~~~~~~~~~

* Added the ``autoescape`` option to the
  :class:`~django.template.backends.django.DjangoTemplates` backend and the
  :class:`~django.template.Engine` class.

* Added the ``is`` and ``is not`` comparison operators to the :ttag:`if` tag.

* Allowed :tfilter:`dictsort` to order a list of lists by an element at a
  specified index.

* The :func:`~django.template.context_processors.debug` context processor
  contains queries for all database aliases instead of only the default alias.

* Added relative path support for string arguments of the :ttag:`extends` and
  :ttag:`include` template tags.

Tests
~~~~~

* To better catch bugs, :class:`~django.test.TestCase` now checks deferrable
  database constraints at the end of each test.

* Tests and test cases can be :ref:`marked with tags <topics-tagging-tests>`
  and run selectively with the new :option:`test --tag` and :option:`test
  --exclude-tag` options.

* You can now login and use sessions with the test client even if
  :mod:`django.contrib.sessions` is not in :setting:`INSTALLED_APPS`.

URLs
~~~~

* An addition in :func:`django.setup()` allows URL resolving that happens
  outside of the request/response cycle (e.g. in management commands and
  standalone scripts) to take :setting:`FORCE_SCRIPT_NAME` into account when it
  is set.

Validators
~~~~~~~~~~

* :class:`~django.core.validators.URLValidator` now limits the length of
  domain name labels to 63 characters and the total length of domain
  names to 253 characters per :rfc:`1034`.

* :func:`~django.core.validators.int_list_validator` now accepts an optional
  ``allow_negative`` boolean parameter, defaulting to ``False``, to allow
  negative integers.

.. _backwards-incompatible-1.10:

Backwards incompatible changes in 1.10
======================================

.. warning::

    In addition to the changes outlined in this section, be sure to review the
    :ref:`removed-features-1.10` for the features that have reached the end of
    their deprecation cycle and therefore been removed. If you haven't updated
    your code within the deprecation timeline for a given feature, its removal
    may appear as a backwards incompatible change.

Database backend API
--------------------

* GIS's ``AreaField`` uses an unspecified underlying numeric type that could in
  practice be any numeric Python type. ``decimal.Decimal`` values retrieved
  from the database are now converted to ``float`` to make it easier to combine
  them with values used by the GIS libraries.

* In order to enable temporal subtraction you must set the
  ``supports_temporal_subtraction`` database feature flag to ``True`` and
  implement the ``DatabaseOperations.subtract_temporals()`` method. This
  method should return the SQL and parameters required to compute the
  difference in microseconds between the ``lhs`` and ``rhs`` arguments in the
  datatype used to store :class:`~django.db.models.DurationField`.

``select_related()`` prohibits non-relational fields for nested relations
-------------------------------------------------------------------------

Django 1.8 added validation for non-relational fields in ``select_related()``::

    >>> Book.objects.select_related('title')
    Traceback (most recent call last):
    ...
    FieldError: Non-relational field given in select_related: 'title'

But it didn't prohibit nested non-relation fields as it does now::

    >>> Book.objects.select_related('author__name')
    Traceback (most recent call last):
    ...
    FieldError: Non-relational field given in select_related: 'name'

``_meta.get_fields()`` returns consistent reverse fields for proxy models
-------------------------------------------------------------------------

Before Django 1.10, the :meth:`~django.db.models.options.Options.get_fields`
method returned different reverse fields when called on a proxy model compared
to its proxied concrete class. This inconsistency was fixed by returning the
full set of fields pointing to a concrete class or one of its proxies in both
cases.

:attr:`AbstractUser.username <django.contrib.auth.models.User.username>` ``max_length`` increased to 150
--------------------------------------------------------------------------------------------------------

A migration for :attr:`django.contrib.auth.models.User.username` is included.
If you have a custom user model inheriting from ``AbstractUser``, you'll need
to generate and apply a database migration for your user model.

We considered an increase to 254 characters to more easily allow the use of
email addresses (which are limited to 254 characters) as usernames but rejected
it due to a MySQL limitation.  When using the ``utf8mb4`` encoding (recommended
for proper Unicode support), MySQL can only create unique indexes with 191
characters by default. Therefore, if you need a longer length, please use a
custom user model.

If you want to preserve the 30 character limit for usernames, use a custom form
when creating a user or changing usernames::

    from django.contrib.auth.forms import UserCreationForm

    class MyUserCreationForm(UserCreationForm):
        username = forms.CharField(
            max_length=30,
            help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.',
        )

If you wish to keep this restriction in the admin, set ``UserAdmin.add_form``
to use this form::

    from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
    from django.contrib.auth.models import User

    class UserAdmin(BaseUserAdmin):
        add_form = MyUserCreationForm

    admin.site.unregister(User)
    admin.site.register(User, UserAdmin)

Dropped support for PostgreSQL 9.1
----------------------------------

Upstream support for PostgreSQL 9.1 ends in September 2016. As a consequence,
Django 1.10 sets PostgreSQL 9.2 as the minimum version it officially supports.

``runserver`` output goes through logging
-----------------------------------------

Request and response handling of the ``runserver`` command is sent to the
:ref:`django-server-logger` logger instead of to ``sys.stderr``. If you
disable Django's logging configuration or override it with your own, you'll
need to add the appropriate logging configuration if you want to see that
output::

    'formatters': {
        'django.server': {
            '()': 'django.utils.log.ServerFormatter',
            'format': '[%(server_time)s] %(message)s',
        }
    },
    'handlers': {
        'django.server': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'django.server',
        },
    },
    'loggers': {
        'django.server': {
            'handlers': ['django.server'],
            'level': 'INFO',
            'propagate': False,
        }
    }

``auth.CustomUser`` and ``auth.ExtensionUser`` test models were removed
-----------------------------------------------------------------------

Since the introduction of migrations for the contrib apps in Django 1.8, the
tables of these custom user test models were not created anymore making them
unusable in a testing context.

Apps registry is no longer auto-populated when unpickling models outside of Django
----------------------------------------------------------------------------------

The apps registry is no longer auto-populated when unpickling models. This was
added in Django 1.7.2 as an attempt to allow unpickling models outside of
Django, such as in an RQ worker, without calling ``django.setup()``, but it
creates the possibility of a deadlock. To adapt your code in the case of RQ,
you can `provide your own worker script <http://python-rq.org/docs/workers/>`_
that calls ``django.setup()``.

Removed null assignment check for non-null foreign key fields
-------------------------------------------------------------

In older versions, assigning ``None`` to a non-nullable ``ForeignKey`` or
``OneToOneField`` raised ``ValueError('Cannot assign None: "model.field" does
not allow null values.')``. For consistency with other model fields which don't
have a similar check, this check is removed.

Removed weak password hashers from the default ``PASSWORD_HASHERS`` setting
---------------------------------------------------------------------------

Django 0.90 stored passwords as unsalted MD5. Django 0.91 added support for
salted SHA1 with automatic upgrade of passwords when a user logs in. Django 1.4
added PBKDF2 as the default password hasher.

If you have an old Django project with MD5 or SHA1 (even salted) encoded
passwords, be aware that these can be cracked fairly easily with today's
hardware. To make Django users acknowledge continued use of weak hashers, the
following hashers are removed from the default :setting:`PASSWORD_HASHERS`
setting::

    'django.contrib.auth.hashers.SHA1PasswordHasher'
    'django.contrib.auth.hashers.MD5PasswordHasher'
    'django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher'
    'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher'
    'django.contrib.auth.hashers.CryptPasswordHasher'

Consider using a :ref:`wrapped password hasher <wrapping-password-hashers>` to
strengthen the hashes in your database. If that's not feasible, add the
:setting:`PASSWORD_HASHERS` setting to your project and add back any hashers
that you need.

You can check if your database has any of the removed hashers like this::

    from django.contrib.auth import get_user_model
    User = get_user_model()

    # Unsalted MD5/SHA1:
    User.objects.filter(password__startswith='md5$$')
    User.objects.filter(password__startswith='sha1$$')
    # Salted MD5/SHA1:
    User.objects.filter(password__startswith='md5$').exclude(password__startswith='md5$$')
    User.objects.filter(password__startswith='sha1$').exclude(password__startswith='sha1$$')
    # Crypt hasher:
    User.objects.filter(password__startswith='crypt$$')

    from django.db.models import CharField
    from django.db.models.functions import Length
    CharField.register_lookup(Length)
    # Unsalted MD5 passwords might not have an 'md5$$' prefix:
    User.objects.filter(password__length=32)

``Field.get_prep_lookup()`` and ``Field.get_db_prep_lookup()`` methods are removed
----------------------------------------------------------------------------------

If you have a custom field that implements either of these methods, register a
custom lookup for it. For example::

    from django.db.models import Field
    from django.db.models.lookups import Exact

    class MyField(Field):
        ...

    class MyFieldExact(Exact):
        def get_prep_lookup(self):
            # do_custom_stuff_for_myfield
            ....

    MyField.register_lookup(MyFieldExact)

:mod:`django.contrib.gis`
-------------------------

* Support for SpatiaLite < 3.0 and GEOS < 3.3 is dropped.

* The ``add_postgis_srs()`` backwards compatibility alias for
  ``django.contrib.gis.utils.add_srs_entry()`` is removed.

* On Oracle/GIS, the :class:`~django.contrib.gis.db.models.functions.Area`
  aggregate function now returns a ``float`` instead of ``decimal.Decimal``.
  (It's still wrapped in a measure of square meters.)

* The default :class:`~django.contrib.gis.geos.GEOSGeometry` representation (WKT
  output) is trimmed by default. That is, instead of
  ``POINT (23.0000000000000000 5.5000000000000000)``, you'll get
  ``POINT (23 5.5)``.

Maximum size of a request body and the number of GET/POST parameters is limited
-------------------------------------------------------------------------------

Two new settings help mitigate denial-of-service attacks via large requests:

* :setting:`DATA_UPLOAD_MAX_MEMORY_SIZE` limits the size that a request body
  may be. File uploads don't count towards this limit.
* :setting:`DATA_UPLOAD_MAX_NUMBER_FIELDS` limits the number of GET/POST
  parameters that are parsed.

Applications that receive unusually large form posts may need to tune these
settings.

Miscellaneous
-------------

* The ``repr()`` of a ``QuerySet`` is wrapped in ``<QuerySet >`` to
  disambiguate it from a plain list when debugging.

* ``utils.version.get_version()`` returns :pep:`440` compliant release
  candidate versions (e.g. '1.10rc1' instead of '1.10c1').

* CSRF token values are now required to be strings of 64 alphanumerics; values
  of 32 alphanumerics, as set by older versions of Django by default, are
  automatically replaced by strings of 64 characters. Other values are
  considered invalid. This should only affect developers or users who replace
  these tokens.

* The ``LOGOUT_URL`` setting is removed as Django hasn't made use of it
  since pre-1.0. If you use it in your project, you can add it to your
  project's settings. The default value was ``'/accounts/logout/'``.

* Objects with a ``close()`` method such as files and generators passed to
  :class:`~django.http.HttpResponse` are now closed immediately instead of when
  the WSGI server calls ``close()`` on the response.

* A redundant ``transaction.atomic()`` call in ``QuerySet.update_or_create()``
  is removed. This may affect query counts tested by
  ``TransactionTestCase.assertNumQueries()``.

* Support for ``skip_validation`` in ``BaseCommand.execute(**options)`` is
  removed. Use ``skip_checks`` (added in Django 1.7) instead.

* :djadmin:`loaddata` now raises a ``CommandError`` instead of showing a
  warning when the specified fixture file is not found.

* Instead of directly accessing the ``LogEntry.change_message`` attribute, it's
  now better to call the ``LogEntry.get_change_message()`` method which will
  provide the message in the current language.

* The default error views now raise ``TemplateDoesNotExist`` if a nonexistent
  ``template_name`` is specified.

* The unused ``choices`` keyword argument of the ``Select`` and
  ``SelectMultiple`` widgets' ``render()`` method is removed. The ``choices``
  argument of the ``render_options()`` method is also removed, making
  ``selected_choices`` the first argument.

* Tests that violate deferrable database constraints will now error when run on
  a database that supports deferrable constraints.

* Built-in management commands now use indexing of keys in ``options``, e.g.
  ``options['verbosity']``, instead of ``options.get()`` and no longer perform
  any type coercion. This could be a problem if you're calling commands using
  ``Command.execute()`` (which bypasses the argument parser that sets a default
  value) instead of :func:`~django.core.management.call_command`. Instead of
  calling ``Command.execute()``, pass the command object as the first argument
  to ``call_command()``.

* :class:`~django.contrib.auth.backends.ModelBackend` and
  :class:`~django.contrib.auth.backends.RemoteUserBackend` now reject inactive
  users. This means that inactive users can't login and will be logged
  out if they are switched from ``is_active=True`` to ``False``. If you need
  the previous behavior, use the new
  :class:`~django.contrib.auth.backends.AllowAllUsersModelBackend` or
  :class:`~django.contrib.auth.backends.AllowAllUsersRemoteUserBackend`
  in :setting:`AUTHENTICATION_BACKENDS` instead.

* In light of the previous change, the test client's
  :meth:`~django.test.Client.login()` method no longer always rejects inactive
  users but instead delegates this decision to the authentication backend.
  :meth:`~django.test.Client.force_login()` also delegates the decision to the
  authentication backend, so if you're using the default backends, you need to
  use an active user.

* :func:`django.views.i18n.set_language` may now return a 204 status code for
  AJAX requests.

* The ``base_field`` attribute of
  :class:`~django.contrib.postgres.fields.RangeField` is now a type of field,
  not an instance of a field.  If you have created a custom subclass of
  :class:`~django.contrib.postgres.fields.RangeField`, you should change the
  ``base_field`` attribute.

* Middleware classes are now initialized when the server starts rather than
  during the first request.

* If you override ``is_authenticated()`` or ``is_anonymous()`` in a custom user
  model, you must convert them to attributes or properties as described in
  :ref:`the deprecation note <user-is-auth-anon-deprecation>`.

* When using :attr:`ModelAdmin.save_as=True
  <django.contrib.admin.ModelAdmin.save_as>`, the "Save as new" button now
  redirects to the change view for the new object instead of to the model's
  changelist. If you need the previous behavior, set the new
  :attr:`ModelAdmin.save_as_continue
  <django.contrib.admin.ModelAdmin.save_as_continue>` attribute to ``False``.

* Required form fields now have the ``required`` HTML attribute. Set the
  :attr:`Form.use_required_attribute <django.forms.Form.use_required_attribute>`
  attribute to ``False`` to disable it. You could also add the ``novalidate``
  attribute to ``<form>`` if you don't want browser validation.

* The WSGI handler no longer removes content of responses from ``HEAD``
  requests or responses with a ``status_code`` of 100-199, 204, or 304. Most
  Web servers already implement this behavior. Responses retrieved using the
  Django test client continue to have these "response fixes" applied.

* ``Model.__init__()`` now receives ``django.db.models.DEFERRED`` as the value
  of deferred fields.

* The ``Model._deferred`` attribute is removed as dynamic model classes when
  using ``QuerySet.defer()`` and ``only()`` is removed.

* :meth:`Storage.save() <django.core.files.storage.Storage.save>` no longer
  replaces ``'\'`` with ``'/'``. This behavior is moved to
  :class:`~django.core.files.storage.FileSystemStorage` since this is a storage
  specific implementation detail. Any Windows user with a custom storage
  implementation that relies on this behavior will need to implement it in the
  custom storage's ``save()`` method.

* Private :class:`~django.db.models.FileField` methods ``get_directory_name()``
  and ``get_filename()`` are no longer called (and are now deprecated) which is
  a backwards incompatible change for users overriding those methods on custom
  fields. To adapt such code, override ``FileField.generate_filename()`` or
  :meth:`Storage.generate_filename()
  <django.core.files.storage.Storage.generate_filename>` instead. It
  might be possible to use :attr:`~django.db.models.FileField.upload_to` also.

* The subject of mail sent by ``AdminEmailHandler`` is no longer truncated at
  989 characters. If you were counting on a limited length, truncate the subject
  yourself.

* Private expressions ``django.db.models.expressions.Date`` and ``DateTime``
  are removed. The new :class:`~django.db.models.functions.datetime.Trunc`
  expressions provide the same functionality.

* The ``_base_manager`` and ``_default_manager`` attributes are removed from
  model instances. They remain accessible on the model class.

* Accessing a deleted field on a model instance, e.g. after ``del obj.field``,
  reloads the field's value instead of raising ``AttributeError``.

* If you subclass ``AbstractBaseUser`` and override ``clean()``, be sure it
  calls ``super()``. :meth:`.AbstractBaseUser.normalize_username` is called in
  a new :meth:`.AbstractBaseUser.clean` method.

* Private API ``django.forms.models.model_to_dict()`` returns a queryset rather
  than a list of primary keys for ``ManyToManyField``\s .

.. _deprecated-features-1.10:

Features deprecated in 1.10
===========================

Direct assignment to a reverse foreign key or many-to-many relation
-------------------------------------------------------------------

Instead of assigning related objects using direct assignment::

    >>> new_list = [obj1, obj2, obj3]
    >>> e.related_set = new_list

Use the :meth:`~django.db.models.fields.related.RelatedManager.set` method
added in Django 1.9::

        >>> e.related_set.set([obj1, obj2, obj3])

This prevents confusion about an assignment resulting in an implicit save.

Non-timezone-aware :class:`~django.core.files.storage.Storage` API
------------------------------------------------------------------

The old, non-timezone-aware methods ``accessed_time()``, ``created_time()``,
and ``modified_time()`` are deprecated in favor of the new ``get_*_time()``
methods.

Third-party storage backends should implement the new methods and mark the old
ones as deprecated. Until then, the new ``get_*_time()`` methods on the base
:class:`~django.core.files.storage.Storage` class convert ``datetime``\s from
the old methods as required and emit a deprecation warning as they do so.

Third-party storage backends may retain the old methods as long as they
wish to support earlier versions of Django.

:mod:`django.contrib.gis`
-------------------------

* The ``get_srid()`` and ``set_srid()`` methods of
  :class:`~django.contrib.gis.geos.GEOSGeometry` are deprecated in favor
  of the :attr:`~django.contrib.gis.geos.GEOSGeometry.srid` property.

* The ``get_x()``, ``set_x()``, ``get_y()``, ``set_y()``, ``get_z()``, and
  ``set_z()`` methods of :class:`~django.contrib.gis.geos.Point` are deprecated
  in favor of the ``x``, ``y``, and ``z`` properties.

* The ``get_coords()`` and ``set_coords()`` methods of
  :class:`~django.contrib.gis.geos.Point` are deprecated in favor of the
  ``tuple`` property.

* The ``cascaded_union`` property of
  :class:`~django.contrib.gis.geos.MultiPolygon` is deprecated in favor of the
  :attr:`~django.contrib.gis.geos.GEOSGeometry.unary_union` property.

* The ``django.contrib.gis.utils.precision_wkt()`` function is deprecated in
  favor of :class:`~django.contrib.gis.geos.WKTWriter`.

``CommaSeparatedIntegerField`` model field
------------------------------------------

``CommaSeparatedIntegerField`` is deprecated in favor of
:class:`~django.db.models.CharField` with the
:func:`~django.core.validators.validate_comma_separated_integer_list`
validator::

    from django.core.validators import validate_comma_separated_integer_list
    from django.db import models

    class MyModel(models.Model):
        numbers = models.CharField(..., validators=[validate_comma_separated_integer_list])

If you're using Oracle, ``CharField`` uses a different database field  type
(``NVARCHAR2``) than ``CommaSeparatedIntegerField`` (``VARCHAR2``). Depending
on your database settings, this might imply a different encoding, and thus a
different length (in bytes) for the same contents. If your stored values are
longer than the 4000 byte limit of ``NVARCHAR2``, you should use ``TextField``
(``NCLOB``) instead. In this case, if you have any queries that group by the
field (e.g. annotating the model with an aggregation or using ``distinct()``)
you'll need to change them (to defer the field).

Using a model name as a query lookup when ``default_related_name`` is set
-------------------------------------------------------------------------

Assume the following models::

    from django.db import models

    class Foo(models.Model):
        pass

    class Bar(models.Model):
        foo = models.ForeignKey(Foo)

        class Meta:
            default_related_name = 'bars'

In older versions, :attr:`~django.db.models.Options.default_related_name`
couldn't be used as a query lookup. This is fixed and support for the old
lookup name is deprecated. For example, since ``default_related_name`` is set
in model ``Bar``, instead of using the model name ``bar`` as the lookup::

    >>> bar = Bar.objects.get(pk=1)
    >>> Foo.objects.get(bar=bar)

use the default_related_name ``bars``::

    >>> Foo.objects.get(bars=bar)

.. _search-lookup-replacement:

``__search`` query lookup
-------------------------

The ``search`` lookup, which supports MySQL only and is extremely limited in
features, is deprecated. Replace it with a custom lookup::

    from django.db import models

    class Search(models.Lookup):
        lookup_name = 'search'

        def as_mysql(self, compiler, connection):
            lhs, lhs_params = self.process_lhs(compiler, connection)
            rhs, rhs_params = self.process_rhs(compiler, connection)
            params = lhs_params + rhs_params
            return 'MATCH (%s) AGAINST (%s IN BOOLEAN MODE)' % (lhs, rhs), params

    models.CharField.register_lookup(Search)
    models.TextField.register_lookup(Search)

.. _user-is-auth-anon-deprecation:

Using ``User.is_authenticated()`` and ``User.is_anonymous()`` as methods
------------------------------------------------------------------------

The ``is_authenticated()`` and ``is_anonymous()`` methods of
:class:`~django.contrib.auth.models.AbstractBaseUser` and
:class:`~django.contrib.auth.models.AnonymousUser` classes are now
properties. They will still work as methods until Django 2.0, but all usage
in Django now uses attribute access.

For example, if you use
:class:`~django.contrib.auth.middleware.AuthenticationMiddleware` and want
to know whether the user is currently logged-in you would use::

    if request.user.is_authenticated:
        ... # Do something for logged-in users.
    else:
        ... # Do something for anonymous users.

instead of ``request.user.is_authenticated()``.

This change avoids accidental information leakage if you forget to call the
method, e.g.::

    if request.user.is_authenticated:
        return sensitive_information

If you override these methods in a custom user model, you must change them to
properties or attributes.

Django uses a ``CallableBool`` object to allow these attributes to work as both
a property and a method. Thus, until the deprecation period ends, you cannot
compare these properties using the ``is`` operator. That is, the following
won't work::

    if request.user.is_authenticated is True:
        ...

Custom manager classes available through ``prefetch_related`` must define a ``_apply_rel_filters()`` method
-----------------------------------------------------------------------------------------------------------

If you defined a custom manager class available through
:meth:`~django.db.models.query.QuerySet.prefetch_related` you must make sure
it defines a ``_apply_rel_filters()`` method.

This method must accept a :class:`~django.db.models.query.QuerySet` instance
as its single argument and return a filtered version of the queryset for the
model instance the manager is bound to.

The "escape" half of ``django.utils.safestring``
------------------------------------------------

The ``mark_for_escaping()`` function and the classes it uses: ``EscapeData``,
``EscapeBytes``, ``EscapeText``, ``EscapeString``, and ``EscapeUnicode`` are
deprecated.

As a result, the "lazy" behavior of the ``escape`` filter (where it would
always be applied as the last filter no matter where in the filter chain it
appeared) is deprecated. The filter will change to immediately apply
:func:`~django.utils.html.conditional_escape` in Django 2.0.

``Manager.use_for_related_fields`` and inheritance changes
----------------------------------------------------------

``Manager.use_for_related_fields`` is deprecated in favor of setting
:attr:`Meta.base_manager_name <django.db.models.Options.base_manager_name>` on
the model.

Model ``Manager`` inheritance will follow MRO inheritance rules in Django 2.0,
changing the current behavior where managers defined on non-abstract base
classes aren't inherited by child classes. A deprecating warning with
instructions on how to adapt your code is raised if you have any affected
managers. You'll either redeclare a manager from an abstract model on the child
class to override the manager from the concrete model, or you'll set the
model's ``Meta.manager_inheritance_from_future=True`` option to opt-in to the
new inheritance behavior.

During the deprecation period, ``use_for_related_fields`` will be honored and
raise a warning, even if a ``base_manager_name`` is set. This allows
third-party code to preserve legacy behavior while transitioning to the new
API. The warning can be silenced by setting
``silence_use_for_related_fields_deprecation=True`` on the manager.

Miscellaneous
-------------

* The ``makemigrations --exit`` option is deprecated in favor of the
  :option:`makemigrations --check` option.

* ``django.utils.functional.allow_lazy()`` is deprecated in favor of the new
  :func:`~django.utils.functional.keep_lazy` function which can be used with a
  more natural decorator syntax.

* The ``shell --plain`` option is deprecated in favor of ``-i python`` or
  ``--interface python``.

* Importing from the ``django.core.urlresolvers`` module is deprecated in
  favor of its new location, :mod:`django.urls`.

* The template ``Context.has_key()`` method is deprecated in favor of ``in``.

* The private attribute ``virtual_fields`` of ``Model._meta`` is
  deprecated in favor of ``private_fields``.

* The private keyword arguments ``virtual_only`` in
  ``Field.contribute_to_class()`` and ``virtual`` in
  ``Model._meta.add_field()`` are deprecated in favor of ``private_only``
  and ``private``, respectively.

* The ``javascript_catalog()`` and ``json_catalog()`` views are deprecated in
  favor of class-based views :class:`~django.views.i18n.JavaScriptCatalog`
  and :class:`~django.views.i18n.JSONCatalog`.

* In multi-table inheritance, implicit promotion of a ``OneToOneField`` to a
  ``parent_link`` is deprecated. Add ``parent_link=True`` to such fields.

* The private API ``Widget._format_value()`` is made public and renamed to
  :meth:`~django.forms.Widget.format_value`. The old name will work
  through a deprecation period.

* Private ``FileField`` methods ``get_directory_name()`` and ``get_filename()``
  are deprecated in favor of performing this work in
  :meth:`Storage.generate_filename()
  <django.core.files.storage.Storage.generate_filename>`).

* Old-style middleware that uses  ``settings.MIDDLEWARE_CLASSES`` are
  deprecated. :ref:`Adapt old, custom middleware <upgrading-middleware>` and
  use the new :setting:`MIDDLEWARE` setting.

.. _removed-features-1.10:

Features removed in 1.10
========================

These features have reached the end of their deprecation cycle and are removed
in Django 1.10. See :ref:`deprecated-features-1.8` for details, including how
to remove usage of these features.

* Support for calling a ``SQLCompiler`` directly as an alias for calling its
  ``quote_name_unless_alias`` method is removed.

* The ``cycle`` and ``firstof`` template tags are removed from the ``future``
  template tag library.

* ``django.conf.urls.patterns()`` is removed.

* Support for the ``prefix`` argument to
  ``django.conf.urls.i18n.i18n_patterns()`` is removed.

* ``SimpleTestCase.urls`` is removed.

* Using an incorrect count of unpacked values in the ``for`` template tag
  raises an exception rather than failing silently.

* The ability to :func:`~django.urls.reverse` URLs using a dotted Python path
  is removed.

* The ability to use a dotted Python path for the ``LOGIN_URL`` and
  ``LOGIN_REDIRECT_URL`` settings is removed.

* Support for ``optparse`` is dropped for custom management commands.

* The class ``django.core.management.NoArgsCommand`` is removed.

* ``django.core.context_processors`` module is removed.

* ``django.db.models.sql.aggregates`` module is removed.

* ``django.contrib.gis.db.models.sql.aggregates`` module is removed.

* The following methods and properties of ``django.db.sql.query.Query`` are
  removed:

  * Properties: ``aggregates`` and ``aggregate_select``
  * Methods: ``add_aggregate``, ``set_aggregate_mask``, and
    ``append_aggregate_mask``.

* ``django.template.resolve_variable`` is removed.

* The following private APIs are removed from
  :class:`django.db.models.options.Options` (``Model._meta``):

  * ``get_field_by_name()``
  * ``get_all_field_names()``
  * ``get_fields_with_model()``
  * ``get_concrete_fields_with_model()``
  * ``get_m2m_with_model()``
  * ``get_all_related_objects()``
  * ``get_all_related_objects_with_model()``
  * ``get_all_related_many_to_many_objects()``
  * ``get_all_related_m2m_objects_with_model()``

* The ``error_message`` argument of ``django.forms.RegexField`` is removed.

* The ``unordered_list`` filter no longer supports old style lists.

* Support for string ``view`` arguments to ``url()`` is removed.

* The backward compatible shim  to rename ``django.forms.Form._has_changed()``
  to ``has_changed()`` is removed.

* The ``removetags`` template filter is removed.

* The ``remove_tags()`` and ``strip_entities()`` functions in
  ``django.utils.html`` is removed.

* The ``is_admin_site`` argument to
  ``django.contrib.auth.views.password_reset()`` is removed.

* ``django.db.models.field.subclassing.SubfieldBase`` is removed.

* ``django.utils.checksums`` is removed.

* The ``original_content_type_id`` attribute on
  ``django.contrib.admin.helpers.InlineAdminForm`` is removed.

* The backwards compatibility shim to allow ``FormMixin.get_form()`` to be
  defined with no default value for its ``form_class`` argument is removed.

* The following settings are removed, and :doc:`you must upgrade
  </ref/templates/upgrading>` to the :setting:`TEMPLATES` setting:

  * ``ALLOWED_INCLUDE_ROOTS``
  * ``TEMPLATE_CONTEXT_PROCESSORS``
  * ``TEMPLATE_DEBUG``
  * ``TEMPLATE_DIRS``
  * ``TEMPLATE_LOADERS``
  * ``TEMPLATE_STRING_IF_INVALID``

* The backwards compatibility alias ``django.template.loader.BaseLoader`` is
  removed.

* Django template objects returned by
  :func:`~django.template.loader.get_template` and
  :func:`~django.template.loader.select_template` no longer accept a
  :class:`~django.template.Context` in their
  :meth:`~django.template.backends.base.Template.render()` method.

* :doc:`Template response APIs </ref/template-response>` enforce the use of
  :class:`dict` and backend-dependent template objects instead of
  :class:`~django.template.Context` and :class:`~django.template.Template`
  respectively.

* The ``current_app`` parameter for the following function and classes is
  removed:

  * ``django.shortcuts.render()``
  * ``django.template.Context()``
  * ``django.template.RequestContext()``
  * ``django.template.response.TemplateResponse()``

* The ``dictionary`` and ``context_instance`` parameters for the following
  functions are removed:

  * ``django.shortcuts.render()``
  * ``django.shortcuts.render_to_response()``
  * ``django.template.loader.render_to_string()``

* The ``dirs`` parameter for the following functions is removed:

  * ``django.template.loader.get_template()``
  * ``django.template.loader.select_template()``
  * ``django.shortcuts.render()``
  * ``django.shortcuts.render_to_response()``

* Session verification is enabled regardless of whether or not
  ``'django.contrib.auth.middleware.SessionAuthenticationMiddleware'`` is in
  ``MIDDLEWARE_CLASSES``. ``SessionAuthenticationMiddleware`` no longer has
  any purpose and can be removed from ``MIDDLEWARE_CLASSES``. It's kept as
  a stub until Django 2.0 as a courtesy for users who don't read this note.

* Private attribute ``django.db.models.Field.related`` is removed.

* The ``--list`` option of the ``migrate`` management command is removed.

* The ``ssi`` template tag is removed.

* Support for the ``=`` comparison operator in the ``if`` template tag is
  removed.

* The backwards compatibility shims to allow ``Storage.get_available_name()``
  and ``Storage.save()`` to be defined without a ``max_length`` argument are
  removed.

* Support for the legacy ``%(<foo>)s`` syntax in ``ModelFormMixin.success_url``
  is removed.

* ``GeoQuerySet`` aggregate methods ``collect()``, ``extent()``, ``extent3d()``,
  ``make_line()``, and ``unionagg()`` are removed.

* The ability to specify ``ContentType.name`` when creating a content type
  instance is removed.

* Support for the old signature of ``allow_migrate`` is removed.

* Support for the syntax of ``{% cycle %}`` that uses comma-separated arguments
  is removed.

* The warning that :class:`~django.core.signing.Signer` issued when given an
  invalid separator is now a ``ValueError``.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.2.1 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.2.1.txt`)

==========================
Django 1.2.1 release notes
==========================

Django 1.2.1 was released almost immediately after 1.2.0 to correct two small
bugs: one was in the documentation packaging script, the other was a bug_ that
affected datetime form field widgets when localization was enabled.

.. _bug: https://code.djangoproject.com/ticket/13560

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.2.2 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.2.2.txt`)

==========================
Django 1.2.2 release notes
==========================

Welcome to Django 1.2.2!

This is the second "bugfix" release in the Django 1.2 series,
improving the stability and performance of the Django 1.2 codebase.

Django 1.2.2 maintains backwards compatibility with Django
1.2.1, but contain a number of fixes and other
improvements. Django 1.2.2 is a recommended upgrade for any
development or deployment currently using or targeting Django 1.2.

For full details on the new features, backwards incompatibilities, and
deprecated features in the 1.2 branch, see the :doc:`/releases/1.2`.

One new feature
===============

Ordinarily, a point release would not include new features, but in the
case of Django 1.2.2, we have made an exception to this rule.

In order to test a bug fix that forms part of the 1.2.2 release, it
was necessary to add a feature -- the ``enforce_csrf_checks`` flag --
to the :ref:`test client <test-client>`. This flag forces
the test client to perform full CSRF checks on forms. The default
behavior of the test client hasn't changed, but if you want to do
CSRF checks with the test client, it is now possible to do so.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.2.3 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.2.3.txt`)

==========================
Django 1.2.3 release notes
==========================

Django 1.2.3 fixed a couple of release problems in the 1.2.2 release and was
released two days after 1.2.2.

This release corrects the following problems:

* The patch_ applied for the security issue covered in Django 1.2.2 caused
  issues with non-ASCII responses using CSRF tokens.

* The patch also caused issues with some forms, most notably the user-editing
  forms in the Django administrative interface.

* The packaging manifest did not contain the full list of required files.

.. _patch: https://code.djangoproject.com/changeset/13699

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.2.4 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.2.4.txt`)

==========================
Django 1.2.4 release notes
==========================

Welcome to Django 1.2.4!

This is the fourth "bugfix" release in the Django 1.2 series,
improving the stability and performance of the Django 1.2 codebase.

With one exception, Django 1.2.4 maintains backwards compatibility
with Django 1.2.3. It also contains a number of fixes and other
improvements. Django 1.2.4 is a recommended upgrade for any
development or deployment currently using or targeting Django 1.2.

For full details on the new features, backwards incompatibilities, and
deprecated features in the 1.2 branch, see the :doc:`/releases/1.2`.

Backwards incompatible changes
==============================

Restricted filters in admin interface
-------------------------------------

The Django administrative interface, django.contrib.admin, supports
filtering of displayed lists of objects by fields on the corresponding
models, including across database-level relationships. This is
implemented by passing lookup arguments in the querystring portion of
the URL, and options on the ModelAdmin class allow developers to
specify particular fields or relationships which will generate
automatic links for filtering.

One historically-undocumented and -unofficially-supported feature has
been the ability for a user with sufficient knowledge of a model's
structure and the format of these lookup arguments to invent useful
new filters on the fly by manipulating the querystring.

However, it has been demonstrated that this can be abused to gain
access to information outside of an admin user's permissions; for
example, an attacker with access to the admin and sufficient knowledge
of model structure and relations could construct query strings which --
with repeated use of regular-expression lookups supported by the
Django database API -- expose sensitive information such as users'
password hashes.

To remedy this, django.contrib.admin will now validate that
querystring lookup arguments either specify only fields on the model
being viewed, or cross relations which have been explicitly
whitelisted by the application developer using the pre-existing
mechanism mentioned above. This is backwards-incompatible for any
users relying on the prior ability to insert arbitrary lookups.

One new feature
===============

Ordinarily, a point release would not include new features, but in the
case of Django 1.2.4, we have made an exception to this rule.

One of the bugs fixed in Django 1.2.4 involves a set of
circumstances whereby a running a test suite on a multiple database
configuration could cause the original source database (i.e., the
actual production database) to be dropped, causing catastrophic loss
of data. In order to provide a fix for this problem, it was necessary
to introduce a new setting -- :setting:`TEST_DEPENDENCIES` -- that
allows you to define any creation order dependencies in your database
configuration.

Most users -- even users with multiple-database configurations -- need
not be concerned about the data loss bug, or the manual configuration of
:setting:`TEST_DEPENDENCIES`. See the `original problem report`_
documentation on :ref:`controlling the creation order of test
databases <topics-testing-creation-dependencies>` for details.

.. _original problem report: https://code.djangoproject.com/ticket/14415

GeoDjango
=========

The function-based :setting:`TEST_RUNNER` previously used to execute
the GeoDjango test suite, ``django.contrib.gis.tests.run_gis_tests``,
was finally deprecated in favor of a class-based test runner,
``django.contrib.gis.tests.GeoDjangoTestSuiteRunner``, added in this
release.

In addition, the GeoDjango test suite is now included when
:ref:`running the Django test suite <running-unit-tests>` with ``runtests.py``
and using :ref:`spatial database backends <spatial-backends>`.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.2.5 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.2.5.txt`)

==========================
Django 1.2.5 release notes
==========================

Welcome to Django 1.2.5!

This is the fifth "bugfix" release in the Django 1.2 series,
improving the stability and performance of the Django 1.2 codebase.

With four exceptions, Django 1.2.5 maintains backwards compatibility
with Django 1.2.4. It also contains a number of fixes and other
improvements. Django 1.2.5 is a recommended upgrade for any
development or deployment currently using or targeting Django 1.2.

For full details on the new features, backwards incompatibilities, and
deprecated features in the 1.2 branch, see the :doc:`/releases/1.2`.

Backwards incompatible changes
==============================

CSRF exception for AJAX requests
--------------------------------

Django includes a CSRF-protection mechanism, which makes use of a
token inserted into outgoing forms. Middleware then checks for the
token's presence on form submission, and validates it.

Prior to Django 1.2.5, our CSRF protection made an exception for AJAX
requests, on the following basis:

* Many AJAX toolkits add an X-Requested-With header when using
  XMLHttpRequest.

* Browsers have strict same-origin policies regarding
  XMLHttpRequest.

* In the context of a browser, the only way that a custom header
  of this nature can be added is with XMLHttpRequest.

Therefore, for ease of use, we did not apply CSRF checks to requests
that appeared to be AJAX on the basis of the X-Requested-With header.
The Ruby on Rails web framework had a similar exemption.

Recently, engineers at Google made members of the Ruby on Rails
development team aware of a combination of browser plugins and
redirects which can allow an attacker to provide custom HTTP headers
on a request to any website. This can allow a forged request to appear
to be an AJAX request, thereby defeating CSRF protection which trusts
the same-origin nature of AJAX requests.

Michael Koziarski of the Rails team brought this to our attention, and
we were able to produce a proof-of-concept demonstrating the same
vulnerability in Django's CSRF handling.

To remedy this, Django will now apply full CSRF validation to all
requests, regardless of apparent AJAX origin. This is technically
backwards-incompatible, but the security risks have been judged to
outweigh the compatibility concerns in this case.

Additionally, Django will now accept the CSRF token in the custom HTTP
header X-CSRFTOKEN, as well as in the form submission itself, for ease
of use with popular JavaScript toolkits which allow insertion of
custom headers into all AJAX requests.

Please see the :ref:`CSRF docs for example jQuery code <csrf-ajax>`
that demonstrates this technique, ensuring that you are looking at the
documentation for your version of Django, as the exact code necessary
is different for some older versions of Django.

FileField no longer deletes files
---------------------------------

In earlier Django versions, when a model instance containing a
:class:`~django.db.models.FileField` was deleted,
:class:`~django.db.models.FileField` took it upon itself to also delete the
file from the backend storage. This opened the door to several potentially
serious data-loss scenarios, including rolled-back transactions and fields on
different models referencing the same file. In Django 1.2.5,
:class:`~django.db.models.FileField` will never delete files from the backend
storage. If you need cleanup of orphaned files, you'll need to handle it
yourself (for instance, with a custom management command that can be run
manually or scheduled to run periodically via e.g. cron).

Use of custom SQL to load initial data in tests
-----------------------------------------------

Django provides a custom SQL hooks as a way to inject hand-crafted SQL
into the database synchronization process. One of the possible uses
for this custom SQL is to insert data into your database. If your
custom SQL contains ``INSERT`` statements, those insertions will be
performed every time your database is synchronized. This includes the
synchronization of any test databases that are created when you run a
test suite.

However, in the process of testing the Django 1.3, it was discovered
that this feature has never completely worked as advertised. When
using database backends that don't support transactions, or when using
a TransactionTestCase, data that has been inserted using custom SQL
will not be visible during the testing process.

Unfortunately, there was no way to rectify this problem without
introducing a backwards incompatibility. Rather than leave
SQL-inserted initial data in an uncertain state, Django now enforces
the policy that data inserted by custom SQL will *not* be visible
during testing.

This change only affects the testing process. You can still use custom
SQL to load data into your production database as part of the ``syncdb``
process. If you require data to exist during test conditions, you
should either insert it using :ref:`test fixtures
<topics-testing-fixtures>`, or using the ``setUp()`` method of your
test case.

ModelAdmin.lookup_allowed signature changed
-------------------------------------------

Django 1.2.4 introduced a method ``lookup_allowed`` on ``ModelAdmin``, to cope
with a security issue (changeset `[15033]
<https://code.djangoproject.com/changeset/15033>`_). Although this method was
never documented, it seems some people have overridden ``lookup_allowed``,
especially to cope with regressions introduced by that changeset. While the
method is still undocumented and not marked as stable, it may be helpful to know
that the signature of this function has changed.

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.2.6 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.2.6.txt`)

==========================
Django 1.2.6 release notes
==========================

*September 9, 2011*

Welcome to Django 1.2.6!

This is the sixth bugfix/security release in the Django 1.2 series, fixing
several security issues present in Django 1.2.5.  Django 1.2.6 is a
recommended upgrade for all users of any Django release in the 1.2.X series.

For a full list of issues addressed in this release, see the `security
advisory`_.

.. _security advisory: https://www.djangoproject.com/weblog/2011/sep/09/security-releases-issued/

---

### 大一小学期 Week 3 Python Exam 2016 Docs Releases 1.2.7 (`大一小学期/Week_3-Python/exam/2016/docs/releases/1.2.7.txt`)

==========================
Django 1.2.7 release notes
==========================

*September 10, 2011*

Welcome to Django 1.2.7!

This is the seventh bugfix/security release in the Django 1.2 series. It
replaces Django 1.2.6 due to problems with the 1.2.6 release tarball.
Django 1.2.7 is a recommended upgrade for all users of any Django release in
the 1.2.X series.

For more information, see the `release advisory`_.

.. _release advisory: https://www.djangoproject.com/weblog/2011/sep/10/127/

---

--- METRICS ---
- Files Extracted: 101
- Estimated Token Budget: ~313246 tokens
- Canonical Reference: https://codewiki.google/github.com/PKUanonym/REKCARC-TSC-UHT
