Django 简明教程
Django - Basics
Django 是一个高级 Python Web 框架,它鼓励快速开发以及干净、实用设计。借助 Django,您可以更快、用更少的代码构建更好的 Web 应用程序。
Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. Django makes it easier to build better web apps quickly and with less code.
Note − Django 是 Django 软件基金会的注册商标,并根据 BSD 许可证获得许可。
Note − Django is a registered trademark of the Django Software Foundation, and is licensed under BSD License.
History of Django
-
2003 − Started by Adrian Holovaty and Simon Willison as an internal project at the Lawrence Journal-World newspaper.
-
2005 − Released July 2005 and named it Django, after the jazz guitarist Django Reinhardt.
-
2005 − Mature enough to handle several high-traffic sites.
-
Current − Django is now an open source project with contributors across the world.
Django – Design Philosophies
Django 有以下设计理念 −
Django comes with the following design philosophies −
-
Loosely Coupled − Django aims to make each element of its stack independent of the others.
-
Less Coding − Less code so in turn a quick development.
-
Don’t Repeat Yourself (DRY) − Everything should be developed only in exactly one place instead of repeating it again and again.
-
Fast Development − Django’s philosophy is to do all it can to facilitate hyper-fast development.
-
Clean Design − Django strictly maintains a clean design throughout its own code and makes it easy to follow best web-development practices.
Advantages of Django
以下是使用 Django 的一些优势,在此处列出 −
Here are few advantages of using Django which can be listed out here −
-
Object-Relational Mapping (ORM) Support − Django provides a bridge between the data model and the database engine, and supports a large set of database systems including MySQL, Oracle, Postgres, etc. Django also supports NoSQL database through Django-nonrel fork. For now, the only NoSQL databases supported are MongoDB and google app engine.
-
Multilingual Support − Django supports multilingual websites through its built-in internationalization system. So you can develop your website, which would support multiple languages.
-
Framework Support − Django has built-in support for Ajax, RSS, Caching and various other frameworks.
-
Administration GUI − Django provides a nice ready-to-use user interface for administrative activities.
-
Development Environment − Django comes with a lightweight web server to facilitate end-to-end application development and testing.
Django - Overview
正如您所知,Django 是一个 Python Web 框架。与大多数现代框架一样,Django 支持 MVC 模式。我们先来看看模型-视图-控制器 (MVC) 模式是什么,然后我们再来看看 Django 对模型-视图-模板 (MVT) 模式的特殊性。
As you already know, Django is a Python web framework. And like most modern framework, Django supports the MVC pattern. First let’s see what is the Model-View-Controller (MVC) pattern, and then we will look at Django’s specificity for the Model-View-Template (MVT) pattern.
MVC Pattern
当谈论提供 UI(Web 或桌面)的应用程序时,我们通常会讨论 MVC 架构。顾名思义,MVC 模式基于三个组件:模型、视图和控制器。{s2} 了解更多信息。
When talking about applications that provides UI (web or desktop), we usually talk about MVC architecture. And as the name suggests, MVC pattern is based on three components: Model, View, and Controller. Check our MVC tutorial here to know more.
DJANGO MVC - MVT Pattern
模型-视图-模板 (MVT) 与 MVC 稍有不同。事实上,这两种模式之间的主要区别在于 Django 本身负责控制器部分(控制模型和视图之间交互的软件代码),而我们保留了模板。模板是一个混合了 Django 模板语言 (DTL) 的 HTML 文件。
The Model-View-Template (MVT) is slightly different from MVC. In fact the main difference between the two patterns is that Django itself takes care of the Controller part (Software Code that controls the interactions between the Model and View), leaving us with the template. The template is a HTML file mixed with Django Template Language (DTL).
下图说明了 MVT 模式的每个组件如何协同交互来响应用户请求 -
The following diagram illustrates how each of the components of the MVT pattern interacts with each other to serve a user request −
开发人员提供模型、视图和模板,然后将其映射到网址,Django 展现魔力提供给用户。
The developer provides the Model, the view and the template then just maps it to a URL and Django does the magic to serve it to the user.
Django - Environment
Django 开发环境包括安装和设置 Python、Django 和数据库系统。由于 Django 涉及到 Web 应用程序,因此值得一提的是,你还需要设置一个 Web 服务器。
Django development environment consists of installing and setting up Python, Django, and a Database System. Since Django deals with web application, it’s worth mentioning that you would need a web server setup as well.
Step 1 – Installing Python
Django 用 100% 纯 Python 代码编写,因此你需要在你的系统上安装 Python。最新版本 Django 需要使用 Python 2.6.5 或更高版本 (针对 2.6.x 分支) 或 2.7.3 或更高版本 (针对 2.7.x 分支)。
Django is written in 100% pure Python code, so you’ll need to install Python on your system. Latest Django version requires Python 2.6.5 or higher for the 2.6.x branch or higher than 2.7.3 for the 2.7.x branch.
如果你的电脑使用最新的 Linux 或 Mac OS X 发行版,那你可能已经安装了 Python。你可以通过在命令提示符中键入 python 命令来验证这一点。如果你看到类似这样的内容,则表明已经安装了 Python。
If you’re on one of the latest Linux or Mac OS X distribution, you probably already have Python installed. You can verify it by typing python command at a command prompt. If you see something like this, then Python is installed.
$ python
Python 2.7.5 (default, Jun 17 2014, 18:11:42)
[GCC 4.8.2 20140120 (Red Hat 4.8.2-16)] on linux2
否则,你可以在 http://www.python.org/download 链接中下载并安装最新版本的 Python。
Otherwise, you can download and install the latest version of Python from the link http://www.python.org/download.
Step 2 - Installing Django
安装 Django 非常容易,但所需的安装步骤取决于你的操作系统。由于 Python 是一个平台无关的语言,因此 Django 有适用于所有操作系统的通用软件包。
Installing Django is very easy, but the steps required for its installation depends on your operating system. Since Python is a platform-independent language, Django has one package that works everywhere regardless of your operating system.
你可以从 http://www.djangoproject.com/download 链接中下载最新版本的 Django。
You can download the latest version of Django from the link http://www.djangoproject.com/download.
UNIX/Linux and Mac OS X Installation
如果你运行的是 Linux 或 Mac OS 系统,则有两种安装 Django 的方法——
You have two ways of installing Django if you are running Linux or Mac OS system −
-
You can use the package manager of your OS, or use easy_install or pip if installed.
-
Install it manually using the official archive you downloaded before.
我们将介绍第二种方案,因为第一种方案取决于你的操作系统发行版。如果你决定按照第一种方案进行操作,请小心你安装的 Django 版本。
We will cover the second option as the first one depends on your OS distribution. If you have decided to follow the first option, just be careful about the version of Django you are installing.
假设你从上述链接中获取了你的归档文件,它应该是类似 Django-x.xx.tar.gz 的内容:
Let’s say you got your archive from the link above, it should be something like Django-x.xx.tar.gz:
提取并安装。
Extract and install.
$ tar xzvf Django-x.xx.tar.gz
$ cd Django-x.xx
$ sudo python setup.py install
你可以通过运行此命令来测试你的安装——
You can test your installation by running this command −
$ django-admin.py --version
如果在屏幕上看到打印的当前 Django 版本,则表明一切就绪。
If you see the current version of Django printed on the screen, then everything is set.
Note - 对于某些版本的 Django,它将是 django-admin,其中的“.py”被删除。
Note − For some version of Django it will be django-admin the ".py" is removed.
Windows Installation
我们假设你的电脑上已经安装了 Django 归档文件和 python。
We assume you have your Django archive and python installed on your computer.
首先,PATH 验证。
First, PATH verification.
在某些版本的 Windows(例如 Windows 7)上,您可能需要确保 Path 系统变量的路径中含有以下内容 C:\Python27\;C:\Python27\Lib\site-packages\django\bin\,当然这取决于您的 Python 版本。
On some version of windows (windows 7) you might need to make sure the Path system variable has the path the following C:\Python27\;C:\Python27\Lib\site-packages\django\bin\ in it, of course depending on your Python version.
然后提取并安装 Django。
Then, extract and install Django.
c:\>cd c:\Django-x.xx
接下来,通过运行以下命令安装 Django,在 Windows Shell “cmd” 中需要对此命令拥有管理员权限 −
Next, install Django by running the following command for which you will need administrative privileges in windows shell "cmd" −
c:\Django-x.xx>python setup.py install
若要测试安装,请打开命令提示符并键入以下命令 −
To test your installation, open a command prompt and type the following command −
c:\>django-admin.py --version
如果在屏幕上看到当前版本的 Django 打印出来,则一切就绪。
If you see the current version of Django printed on screen, then everything is set.
或
OR
启动 “cmd” 提示符并依次键入 python −
Launch a "cmd" prompt and type python then −
c:\> python
>>> import django
>>> print django.get_version()
Step 3 – Database Setup
Django 支持多个主要的数据库引擎,您可以根据自己的习惯来设置其中的任何一个。
Django supports several major database engines and you can set up any of them based on your comfort.
您可以参考相关文档来安装和配置您选择的数据库。
You can refer to respective documentation to installing and configuring a database of your choice.
Note − 5 号和 6 号是 NoSQL 数据库。
Note − Number 5 and 6 are NoSQL databases.
Step 4 – Web Server
Django 带有一个用于开发和测试应用程序的轻量级 Web 服务器。此服务器预配置为与 Django 配合使用,更重要的是,每当您修改代码时都会重新启动。
Django comes with a lightweight web server for developing and testing applications. This server is pre-configured to work with Django, and more importantly, it restarts whenever you modify the code.
然而,Django 的确支持 Apache 和其他流行的 Web 服务器,例如 Lighttpd。我们将在处理不同示例时在后续章节中讨论这两种方法。
However, Django does support Apache and other popular web servers such as Lighttpd. We will discuss both the approaches in coming chapters while working with different examples.
Django - Creating a Project
既然我们已经安装了 Django,我们开始使用它。在 Django 中,你想要创建的每个 Web 应用程序都被称为一个项目;而一个项目是应用程序的总和。应用程序是依赖于 MVT 模式的一组代码文件。举个例子,假设我们要构建一个网站,网站是我们的项目,论坛、新闻、联系引擎是应用程序。这种结构使得在项目之间移动应用程序变得更容易,因为每个应用程序都是独立的。
Now that we have installed Django, let’s start using it. In Django, every web app you want to create is called a project; and a project is a sum of applications. An application is a set of code files relying on the MVT pattern. As example let’s say we want to build a website, the website is our project and, the forum, news, contact engine are applications. This structure makes it easier to move an application between projects since every application is independent.
Create a Project
无论你在 Windows 还是 Linux 上,只需打开一个终端或一个 cmd 提示符,然后导航到想要创建项目的位置,然后使用以下代码 −
Whether you are on Windows or Linux, just get a terminal or a cmd prompt and navigate to the place you want your project to be created, then use this code −
$ django-admin startproject myproject
这将创建一个具有以下结构的 “myproject” 文件夹 −
This will create a "myproject" folder with the following structure −
myproject/
manage.py
myproject/
__init__.py
settings.py
urls.py
wsgi.py
The Project Structure
“myproject” 文件夹只是你的项目容器,它实际上包含两个元素 −
The “myproject” folder is just your project container, it actually contains two elements −
-
manage.py − This file is kind of your project local django-admin for interacting with your project via command line (start the development server, sync db…). To get a full list of command accessible via manage.py you can use the code −
$ python manage.py help
-
The “myproject” subfolder − This folder is the actual python package of your project. It contains four files − init.py − Just for python, treat this folder as package. settings.py − As the name indicates, your project settings. urls.py − All links of your project and the function to call. A kind of ToC of your project. wsgi.py − If you need to deploy your project over WSGI.
Setting Up Your Project
你的项目在子文件夹 myproject/settings.py
中设置。下面是你可能需要设置的一些重要选项 −
Your project is set up in the subfolder myproject/settings.py. Following are some important options you might need to set −
DEBUG = True
此选项允许你设置你的项目是否处于调试模式。调试模式让你了解你的项目的错误。切勿为实时项目将其设置为 “True”。但是,如果你希望 Django 灯光服务器提供静态文件,则必须将其设置为 “True”。仅在开发模式下执行此操作。
This option lets you set if your project is in debug mode or not. Debug mode lets you get more information about your project’s error. Never set it to ‘True’ for a live project. However, this has to be set to ‘True’ if you want the Django light server to serve static files. Do it only in the development mode.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'database.sql',
'USER': '',
'PASSWORD': '',
'HOST': '',
'PORT': '',
}
}
数据库在 “Database” 词典中设置。上面的示例适用于 SQLite 引擎。如前所述,Django 还支持 −
Database is set in the ‘Database’ dictionary. The example above is for SQLite engine. As stated earlier, Django also supports −
-
MySQL (django.db.backends.mysql)
-
PostGreSQL (django.db.backends.postgresql_psycopg2)
-
Oracle (django.db.backends.oracle) and NoSQL DB
-
MongoDB (django_mongodb_engine)
在设置任何新引擎之前,请确保你安装了正确的数据库驱动程序。
Before setting any new engine, make sure you have the correct db driver installed.
你还可以设置其他选项,例如:TIME_ZONE
、LANGUAGE_CODE
、TEMPLATE
……
You can also set others options like: TIME_ZONE, LANGUAGE_CODE, TEMPLATE…
现在你的项目已经创建并配置,确保它正常工作 −
Now that your project is created and configured make sure it’s working −
$ python manage.py runserver
运行以上代码后,你会看到类似以下内容 −
You will get something like the following on running the above code −
Validating models...
0 errors found
September 03, 2015 - 11:41:50
Django version 1.6.11, using settings 'myproject.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Django - Apps Life Cycle
项目是许多应用程序的总和。每个应用程序都有一个目标,可以重复使用到其他项目中,例如网站上的联系表单可以是一个应用程序,可以重复使用到其他网站。将其视为您项目的模块。
A project is a sum of many applications. Every application has an objective and can be reused into another project, like the contact form on a website can be an application, and can be reused for others. See it as a module of your project.
Create an Application
我们假设您在您的项目文件夹中。在我们的主“myproject”文件夹中,然后管理。py -
We assume you are in your project folder. In our main “myproject” folder, the same folder then manage.py −
$ python manage.py startapp myapp
您刚刚创建了 myapp 应用程序,和项目一样,Django 使用应用程序结构创建一个“myapp”文件夹 -
You just created myapp application and like project, Django create a “myapp” folder with the application structure −
myapp/
__init__.py
admin.py
models.py
tests.py
views.py
-
init.py − Just to make sure python handles this folder as a package.
-
admin.py − This file helps you make the app modifiable in the admin interface.
-
models.py − This is where all the application models are stored.
-
tests.py − This is where your unit tests are.
-
views.py − This is where your application views are.
Get the Project to Know About Your Application
在此阶段,我们有了“myapp”应用程序,现在我们需要将其注册到 Django 项目“myproject”中。为此,请更新项目的 settings.py 文件中的 INSTALLED_APPS 元组(添加您的应用程序名称) -
At this stage we have our "myapp" application, now we need to register it with our Django project "myproject". To do so, update INSTALLED_APPS tuple in the settings.py file of your project (add your app name) −
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
)
Django - Admin Interface
Django 为管理活动提供了一个即用型的用户界面。我们都知道管理界面对于 Web 项目有多么重要。Django 根据您的项目模型自动生成管理用户界面。
Django provides a ready-to-use user interface for administrative activities. We all know how an admin interface is important for a web project. Django automatically generates admin UI based on your project models.
Starting the Admin Interface
管理界面依赖于 django.countrib 模块。为使其正常工作,您需要确保在 myproject/settings.py 文件的 INSTALLED_APPS 和 MIDDLEWARE_CLASSES 元组中导入了一些模块。
The Admin interface depends on the django.countrib module. To have it working you need to make sure some modules are imported in the INSTALLED_APPS and MIDDLEWARE_CLASSES tuples of the myproject/settings.py file.
对于 INSTALLED_APPS,确保您有 −
For INSTALLED_APPS make sure you have −
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
)
对于 MIDDLEWARE_CLASSES −
For MIDDLEWARE_CLASSES −
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
在启动服务器之前,要访问管理界面,需要初始化数据库 −
Before launching your server, to access your Admin Interface, you need to initiate the database −
$ python manage.py migrate
syncdb 将创建数据库类型所需的必要表格或集合,以便管理界面运行。即使没有超级用户,也会提示您创建一个。
syncdb will create necessary tables or collections depending on your db type, necessary for the admin interface to run. Even if you don’t have a superuser, you will be prompted to create one.
如果您已经拥有超级用户或忘记了超级用户,可以使用以下代码随时创建一个 −
If you already have a superuser or have forgotten it, you can always create one using the following code −
$ python manage.py createsuperuser
现在要启动管理界面,我们需要确保为管理界面配置了一个 URL。打开 myproject/url.py,您应该拥有类似这样的内容 −
Now to start the Admin Interface, we need to make sure we have configured a URL for our admin interface. Open the myproject/url.py and you should have something like −
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'myproject.views.home', name = 'home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
)
现在只需运行服务器即可。
Now just run the server.
$ python manage.py runserver
您的管理界面可以在 [role="bare"] [role="bare"]http://127.0.0.1:8000/admin/ 访问:
And your admin interface is accessible at: [role="bare"]http://127.0.0.1:8000/admin/
一旦使用超级用户帐户连接,您将看到以下屏幕 −
Once connected with your superuser account, you will see the following screen −
该界面将允许您管理 Django 组和用户,以及应用程序中所有注册的模型。该界面使您可以对模型执行至少“CRUD”(创建、读取、更新、删除)操作。
That interface will let you administrate Django groups and users, and all registered models in your app. The interface gives you the ability to do at least the "CRUD" (Create, Read, Update, Delete) operations on your models.
Django - Creating Views
视图函数,简称“视图”,只是接受 Web 请求并返回 Web 响应的 Python 函数。此响应可以是网页的 HTML 内容,或者重定向,或者 404 错误,或者 XML 文档,或者图像等。示例:你使用视图创建网页,请注意你需要将视图与 URL 关联起来,才能将其视为网页。
A view function, or “view” for short, is simply a Python function that takes a web request and returns a web response. This response can be the HTML contents of a Web page, or a redirect, or a 404 error, or an XML document, or an image, etc. Example: You use view to create web pages, note that you need to associate a view to a URL to see it as a web page.
在 Django 中,必须在应用程序 views.py 文件中创建视图。
In Django, views have to be created in the app views.py file.
Simple View
我们将在 myapp 中创建一个简单的视图来表示"欢迎使用我的应用程序!"
We will create a simple view in myapp to say "welcome to my app!"
请参见以下视图 −
See the following view −
from django.http import HttpResponse
def hello(request):
text = """<h1>welcome to my app !</h1>"""
return HttpResponse(text)
在此视图中,我们使用 HttpResponse 呈现 HTML(正如你可能已经注意到的,我们在这个视图中对 HTML 进行硬编码)。若要将此视图当做一个页面查看,我们只需要将其映射到一个 URL(这将在后面的章节中讨论)。
In this view, we use HttpResponse to render the HTML (as you have probably noticed we have the HTML hard coded in the view). To see this view as a page we just need to map it to a URL (this will be discussed in an upcoming chapter).
我们之前使用 HttpResponse 来呈现视图中的 HTML。这不是呈现页面的最佳方式。Django 支持 MVT 模式,因此若要使先例视图类似 Django - MVT,我们需要 −
We used HttpResponse to render the HTML in the view before. This is not the best way to render pages. Django supports the MVT pattern so to make the precedent view, Django - MVT like, we will need −
模板:myapp/templates/hello.html
A template: myapp/templates/hello.html
现在,我们的视图将类似于 -
And now our view will look like −
from django.shortcuts import render
def hello(request):
return render(request, "myapp/template/hello.html", {})
视图还可以接受参数 -
Views can also accept parameters −
from django.http import HttpResponse
def hello(request, number):
text = "<h1>welcome to my app number %s!</h1>"% number
return HttpResponse(text)
当链接到 URL 时,页面将显示作为参数传递的数字。请注意,参数将通过 URL 传递(下一章中讨论)。
When linked to a URL, the page will display the number passed as a parameter. Note that the parameters will be passed via the URL (discussed in the next chapter).
Django - URL Mapping
现在,我们有了上一章中解释的一个正在工作的视图。我们希望通过一个 URL 访问该视图。Django 有自己的 URL 映射方式,这是通过编辑项目 (myproject/url.py) 文件完成的。url.py 文件类似于 -
Now that we have a working view as explained in the previous chapters. We want to access that view via a URL. Django has his own way for URL mapping and it’s done by editing your project url.py file (myproject/url.py). The url.py file looks like −
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
#Examples
#url(r'^$', 'myproject.view.home', name = 'home'),
#url(r'^blog/', include('blog.urls')),
url(r'^admin', include(admin.site.urls)),
)
当用户对 Web 应用程序上的页面发出请求时,Django 控制器接管,通过 url.py 文件查找相应的视图,然后返回 HTML 响应或 404 未找到错误(如果未找到)。在 url.py 中,最重要的事情是 "urlpatterns" 元组。它定义了 URL 和视图之间的映射关系。映射是 URL 模式中的元组,如下所示 -
When a user makes a request for a page on your web app, Django controller takes over to look for the corresponding view via the url.py file, and then return the HTML response or a 404 not found error, if not found. In url.py, the most important thing is the "urlpatterns" tuple. It’s where you define the mapping between URLs and views. A mapping is a tuple in URL patterns like −
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
#Examples
#url(r'^$', 'myproject.view.home', name = 'home'),
#url(r'^blog/', include('blog.urls')),
url(r'^admin', include(admin.site.urls)),
url(r'^hello/', 'myapp.views.hello', name = 'hello'),
)
标记的行将 URL“/ home”映射到在 myapp/view.py 文件中创建的 hello 视图。正如您在上面看到的那样,一个映射由三个元素组成 -
The marked line maps the URL "/home" to the hello view created in myapp/view.py file. As you can see above a mapping is composed of three elements −
-
The pattern − A regexp matching the URL you want to be resolved and map. Everything that can work with the python 're' module is eligible for the pattern (useful when you want to pass parameters via url).
-
The python path to the view − Same as when you are importing a module.
-
The name − In order to perform URL reversing, you’ll need to use named URL patterns as done in the examples above. Once done, just start the server to access your view via :http://127.0.0.1/hello
Organizing Your URLs
到目前为止,我们已在“myprojects/url.py”文件中创建了 URL,但是如前所述,关于 Django 和创建应用程序,最好的办法是能够在不同的项目中重复使用应用程序。如果您将所有 URL 都保存在“projecturl.py”文件中,您可以轻松地了解问题所在。因此,最佳做法是为每个应用程序创建一个“url.py”,并将其包含在我们的主项目 url.py 文件中(我们之前已包含管理界面用的管理 URL)。
So far, we have created the URLs in “myprojects/url.py” file, however as stated earlier about Django and creating an app, the best point was to be able to reuse applications in different projects. You can easily see what the problem is, if you are saving all your URLs in the “projecturl.py” file. So best practice is to create an “url.py” per application and to include it in our main projects url.py file (we included admin URLs for admin interface before).
How is it Done?
我们需要使用以下代码在 myapp 中创建一个 url.py 文件 -
We need to create an url.py file in myapp using the following code −
from django.conf.urls import patterns, include, url
urlpatterns = patterns('', url(r'^hello/', 'myapp.views.hello', name = 'hello'),)
然后 myproject/url.py 将更改为以下内容 -
Then myproject/url.py will change to the following −
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
#Examples
#url(r'^$', 'myproject.view.home', name = 'home'),
#url(r'^blog/', include('blog.urls')),
url(r'^admin', include(admin.site.urls)),
url(r'^myapp/', include('myapp.urls')),
)
我们已包含 myapp 应用程序中的所有 URL。通过“/ hello”访问的 home.html 现在为“/ myapp/hello”,这是一个更好、更易于理解的 Web 应用程序结构。
We have included all URLs from myapp application. The home.html that was accessed through “/hello” is now “/myapp/hello” which is a better and more understandable structure for the web app.
现在,假设我们在 myapp 中有另一个视图“morning”,并且我们希望在 myapp/url.py 中映射它,那么我们将更改我们的 myapp/url.py 为 -
Now let’s imagine we have another view in myapp “morning” and we want to map it in myapp/url.py, we will then change our myapp/url.py to −
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'^hello/', 'myapp.views.hello', name = 'hello'),
url(r'^morning/', 'myapp.views.morning', name = 'morning'),
)
可以将其重新编排为 -
This can be re-factored to −
from django.conf.urls import patterns, include, url
urlpatterns = patterns('myapp.views',
url(r'^hello/', 'hello', name = 'hello'),
url(r'^morning/', 'morning', name = 'morning'),)
如您所见,我们现在使用 urlpatterns 元组的第一个元素。当您想更改应用程序名称时,这可能很有用。
As you can see, we now use the first element of our urlpatterns tuple. This can be useful when you want to change your app name.
Sending Parameters to Views
我们现在知道如何映射 URL,如何组织它们,现在让我们看看如何向视图发送参数。一个经典示例是文章示例(您想通过“/ articles/article_id”访问文章)。
We now know how to map URL, how to organize them, now let us see how to send parameters to views. A classic sample is the article example (you want to access an article via “/articles/article_id”).
通过在 URL 模式中使用 regexp 捕获参数来传递参数。如果我们在“myapp/view.py”中有一个像下面的视图
Passing parameters is done by capturing them with the regexp in the URL pattern. If we have a view like the following one in “myapp/view.py”
from django.shortcuts import render
from django.http import HttpResponse
def hello(request):
return render(request, "hello.html", {})
def viewArticle(request, articleId):
text = "Displaying article Number : %s"%articleId
return HttpResponse(text)
我们在 myapp/url.py 中进行映射,以便能够通过 “/myapp/article/articleId” 访问它,我们需要在 “myapp/url.py” 中添加以下内容 -
We want to map it in myapp/url.py so we can access it via “/myapp/article/articleId”, we need the following in “myapp/url.py” −
from django.conf.urls import patterns, include, url
urlpatterns = patterns('myapp.views',
url(r'^hello/', 'hello', name = 'hello'),
url(r'^morning/', 'morning', name = 'morning'),
url(r'^article/(\d+)/', 'viewArticle', name = 'article'),)
当 Django 看见 URL: “/myapp/article/42” 时,它将参数 '42' 传递给 viewArticle 视图,你应该在浏览器中看到以下结果 -
When Django will see the url: “/myapp/article/42” it will pass the parameters '42' to the viewArticle view, and in your browser you should get the following result −
请注意,此处参数的顺序很重要。假设我们想要某个月某年的文章列表,让我们添加一个 viewArticles 视图。我们的 view.py 将变成 -
Note that the order of parameters is important here. Suppose we want the list of articles of a month of a year, let’s add a viewArticles view. Our view.py becomes −
from django.shortcuts import render
from django.http import HttpResponse
def hello(request):
return render(request, "hello.html", {})
def viewArticle(request, articleId):
text = "Displaying article Number : %s"%articleId
return HttpResponse(text)
def viewArticles(request, month, year):
text = "Displaying articles of : %s/%s"%(year, month)
return HttpResponse(text)
相应的 url.py 文件将如下所示 -
The corresponding url.py file will look like −
from django.conf.urls import patterns, include, url
urlpatterns = patterns('myapp.views',
url(r'^hello/', 'hello', name = 'hello'),
url(r'^morning/', 'morning', name = 'morning'),
url(r'^article/(\d+)/', 'viewArticle', name = 'article'),
url(r'^articles/(\d{2})/(\d{4})', 'viewArticles', name = 'articles'),)
现在,当你访问 “/myapp/articles/12/2006/” 时,你会得到 'Displaying articles of: 2006/12',但如果你颠倒了参数的顺序,你将无法得到相同的结果。
Now when you go to “/myapp/articles/12/2006/” you will get 'Displaying articles of: 2006/12' but if you reverse the parameters you won’t get the same result.
为了避免这种情况,可以将一个 URL 参数链接到视图参数。为此,我们的 url.py 将变成 -
To avoid that, it is possible to link a URL parameter to the view parameter. For that, our url.py will become −
from django.conf.urls import patterns, include, url
urlpatterns = patterns('myapp.views',
url(r'^hello/', 'hello', name = 'hello'),
url(r'^morning/', 'morning', name = 'morning'),
url(r'^article/(\d+)/', 'viewArticle', name = 'article'),
url(r'^articles/(?P\d{2})/(?P\d{4})', 'viewArticles', name = 'articles'),)
Django - Template System
Django 使得可以将 Python 和 HTML 分开,Python 用于视图,HTML 用于模板。为了将两者关联,Django 依靠 render 函数和 Django 模板语言。
Django makes it possible to separate python and HTML, the python goes in views and HTML goes in templates. To link the two, Django relies on the render function and the Django Template language.
The Render Function
此函数需要三个参数 −
This function takes three parameters −
-
Request − The initial request.
-
The path to the template − This is the path relative to the TEMPLATE_DIRS option in the project settings.py variables.
-
Dictionary of parameters − A dictionary that contains all variables needed in the template. This variable can be created or you can use locals() to pass all local variable declared in the view.
Django Template Language (DTL)
Django 的模板引擎提供了一种迷你语言来定义应用程序面向用户的层。
Django’s template engine offers a mini-language to define the user-facing layer of the application.
Displaying Variables
变量看起来像这样:{{variable}}。模板使用 render 函数的第三个参数中视图发送的变量替换可变对象。我们来更改 hello.html 以显示今天的日期 −
A variable looks like this: {{variable}}. The template replaces the variable by the variable sent by the view in the third parameter of the render function. Let’s change our hello.html to display today’s date −
hello.html
hello.html
<html>
<body>
Hello World!!!<p>Today is {{today}}</p>
</body>
</html>
然后我们的视图更改为 −
Then our view will change to −
def hello(request):
today = datetime.datetime.now().date()
return render(request, "hello.html", {"today" : today})
现在我们访问 URL/myapp/hello 后将获得以下输出 −
We will now get the following output after accessing the URL/myapp/hello −
Hello World!!!
Today is Sept. 11, 2015
您可能已经注意到,如果变量不是字符串,Django 会使用 str 方法来显示它;而且使用相同原则,您可以访问对象属性,就像在 Python 中所做的那样。例如:如果我们想要显示日期年份,我的变量将为:{{ today.year }}。
As you have probably noticed, if the variable is not a string, Django will use the str method to display it; and with the same principle you can access an object attribute just like you do it in Python. For example: if we wanted to display the date year, my variable would be: {{today.year}}.
Filters
它们帮助您在显示时间修改变量。过滤器结构如下所示:{{ var|filters }}。
They help you modify variables at display time. Filters structure looks like the following: {{var|filters}}.
Some examples −
Some examples −
-
{{string|truncatewords:80}} − This filter will truncate the string, so you will see only the first 80 words.
-
{{string|lower}} − Converts the string to lowercase.
-
{{string|escape|linebreaks}} − Escapes string contents, then converts line breaks to tags.
您还可以设置变量的默认值。
You can also set the default for a variable.
Tags
标签允许您执行以下操作:if 条件、for 循环、模板继承等。
Tags lets you perform the following operations: if condition, for loop, template inheritance and more.
Tag if
就像在 Python 中一样,您可以在模板中使用 if、else 和 elif −
Just like in Python you can use if, else and elif in your template −
<html>
<body>
Hello World!!!<p>Today is {{today}}</p>
We are
{% if today.day == 1 %}
the first day of month.
{% elif today.day == 30 %}
the last day of month.
{% else %}
I don't know.
{%endif%}
</body>
</html>
在此新模板中,根据日期,模板将呈现特定值。
In this new template, depending on the date of the day, the template will render a certain value.
Tag for
就像“if”一样,我们有“for”标签,它的工作原理与 Python 中完全相同。让我们更改 hello 视图以将列表传输到我们的模板 −
Just like 'if', we have the 'for' tag, that works exactly like in Python. Let’s change our hello view to transmit a list to our template −
def hello(request):
today = datetime.datetime.now().date()
daysOfWeek = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
return render(request, "hello.html", {"today" : today, "days_of_week" : daysOfWeek})
使用 {{ for }} 显示该列表的模板 −
The template to display that list using {{ for }} −
<html>
<body>
Hello World!!!<p>Today is {{today}}</p>
We are
{% if today.day == 1 %}
the first day of month.
{% elif today.day == 30 %}
the last day of month.
{% else %}
I don't know.
{%endif%}
<p>
{% for day in days_of_week %}
{{day}}
</p>
{% endfor %}
</body>
</html>
我们应该得到类似 −
And we should get something like −
Hello World!!!
Today is Sept. 11, 2015
We are I don't know.
Mon
Tue
Wed
Thu
Fri
Sat
Sun
Block and Extend Tags
如果没有模板继承,模板系统将无法完成。也就是说,在设计模板时,应该有一个带有孔的主模板,子模板将根据其需要进行填充,就像一个页面可能需要一个特殊 css 来突出显示所选选项卡。
A template system cannot be complete without template inheritance. Meaning when you are designing your templates, you should have a main template with holes that the child’s template will fill according to his own need, like a page might need a special css for the selected tab.
让我们更改 hello.html 模板来继承自 main_template.html。
Let’s change the hello.html template to inherit from a main_template.html.
main_template.html
main_template.html
<html>
<head>
<title>
{% block title %}Page Title{% endblock %}
</title>
</head>
<body>
{% block content %}
Body content
{% endblock %}
</body>
</html>
hello.html
hello.html
{% extends "main_template.html" %}
{% block title %}My Hello Page{% endblock %}
{% block content %}
Hello World!!!<p>Today is {{today}}</p>
We are
{% if today.day == 1 %}
the first day of month.
{% elif today.day == 30 %}
the last day of month.
{% else %}
I don't know.
{%endif%}
<p>
{% for day in days_of_week %}
{{day}}
</p>
{% endfor %}
{% endblock %}
在上面的示例中,调用 /myapp/hello 时,我们将仍然获得与以前相同的结果,但现在我们依靠 extends 和 block 来重构我们的代码 −
In the above example, on calling /myapp/hello we will still get the same result as before but now we rely on extends and block to refactor our code −
在 main_template.html 中,我们使用标签 block 来定义块。title 块将包含页面标题,而 content 块将包含页面主要内容。在 home.html 中,我们使用 extends 来从 main_template.html 继承,然后我们填充上述定义的块(内容和标题)。
In the main_template.html we define blocks using the tag block. The title block will contain the page title and the content block will have the page main content. In home.html we use extends to inherit from the main_template.html then we fill the block define above (content and title).
Django - Models
模型是一个代表我们 DB 中的表或集合的类,其中类的每个属性都是表或集合的字段。模型在 app/models.py 中定义(在我们的示例中:myapp/models.py)
A model is a class that represents table or collection in our DB, and where every attribute of the class is a field of the table or collection. Models are defined in the app/models.py (in our example: myapp/models.py)
Creating a Model
以下是作为示例创建的一个 Dreamreal 模型 −
Following is a Dreamreal model created as an example −
from django.db import models
class Dreamreal(models.Model):
website = models.CharField(max_length = 50)
mail = models.CharField(max_length = 50)
name = models.CharField(max_length = 50)
phonenumber = models.IntegerField()
class Meta:
db_table = "dreamreal"
每个模型都从 django.db.models.Model 继承。
Every model inherits from django.db.models.Model.
我们的类有 4 个属性(3 个 CharField 和 1 个 Integer),这些将作为表字段。
Our class has 4 attributes (3 CharField and 1 Integer), those will be the table fields.
带有 db_table 属性的 Meta 类允许我们定义实际表或收藏名称。Django 自动为表或集合命名:myapp_modelName。此类将允许你按自己的喜好强制设置表名。
The Meta class with the db_table attribute lets us define the actual table or collection name. Django names the table or collection automatically: myapp_modelName. This class will let you force the name of the table to what you like.
在创建模型后,你需要 Django 来生成实际数据库 −
After creating your model, you will need Django to generate the actual database −
$python manage.py syncdb
Manipulating Data (CRUD)
我们创建一个“crudops”视图来了解如何在模型中执行 CRUD 操作。此时我们的 myapp/views.py 如下所示 −
Let’s create a "crudops" view to see how we can do CRUD operations on models. Our myapp/views.py will then look like −
myapp/views.py
myapp/views.py
from myapp.models import Dreamreal
from django.http import HttpResponse
def crudops(request):
#Creating an entry
dreamreal = Dreamreal(
website = "www.polo.com", mail = "sorex@polo.com",
name = "sorex", phonenumber = "002376970"
)
dreamreal.save()
#Read ALL entries
objects = Dreamreal.objects.all()
res ='Printing all Dreamreal entries in the DB : <br>'
for elt in objects:
res += elt.name+"<br>"
#Read a specific entry:
sorex = Dreamreal.objects.get(name = "sorex")
res += 'Printing One entry <br>'
res += sorex.name
#Delete an entry
res += '<br> Deleting an entry <br>'
sorex.delete()
#Update
dreamreal = Dreamreal(
website = "www.polo.com", mail = "sorex@polo.com",
name = "sorex", phonenumber = "002376970"
)
dreamreal.save()
res += 'Updating entry<br>'
dreamreal = Dreamreal.objects.get(name = 'sorex')
dreamreal.name = 'thierry'
dreamreal.save()
return HttpResponse(res)
Other Data Manipulation
我们探索其他可以在模型上执行的操作。请注意,CRUD 操作是在我们模型的实例上执行的,现在我们将直接使用表示我们模型的类。
Let’s explore other manipulations we can do on Models. Note that the CRUD operations were done on instances of our model, now we will be working directly with the class representing our model.
我们在 myapp/views.py 中创建一个“datamanipulation”视图
Let’s create a 'datamanipulation' view in myapp/views.py
from myapp.models import Dreamreal
from django.http import HttpResponse
def datamanipulation(request):
res = ''
#Filtering data:
qs = Dreamreal.objects.filter(name = "paul")
res += "Found : %s results<br>"%len(qs)
#Ordering results
qs = Dreamreal.objects.order_by("name")
for elt in qs:
res += elt.name + '<br>'
return HttpResponse(res)
Linking Models
Django ORM 提供 3 种链接模型的方法 −
Django ORM offers 3 ways to link models −
我们在这里看到的第一个案例之一是一对多关系。如你所见,在上面的示例中,Dreamreal 公司可以拥有多个在线网站。定义该关系是通过使用 django.db.models.ForeignKey 来完成的 −
One of the first case we will see here is the one-to-many relationships. As you can see in the above example, Dreamreal company can have multiple online websites. Defining that relation is done by using django.db.models.ForeignKey −
myapp/models.py
myapp/models.py
from django.db import models
class Dreamreal(models.Model):
website = models.CharField(max_length = 50)
mail = models.CharField(max_length = 50)
name = models.CharField(max_length = 50)
phonenumber = models.IntegerField()
online = models.ForeignKey('Online', default = 1)
class Meta:
db_table = "dreamreal"
class Online(models.Model):
domain = models.CharField(max_length = 30)
class Meta:
db_table = "online"
如你在我们更新的 myapp/models.py 中看到的,我们添加了 online 模型并将其链接到了我们的 Dreamreal 模型。
As you can see in our updated myapp/models.py, we added the online model and linked it to our Dreamreal model.
我们通过 manage.py shell 检查所有这一切的工作原理 −
Let’s check how all of this is working via manage.py shell −
首先,让我们在 Django shell 中创建一些公司(Dreamreal 条目)来进行测试 −
First let’s create some companies (Dreamreal entries) for testing in our Django shell −
$python manage.py shell
>>> from myapp.models import Dreamreal, Online
>>> dr1 = Dreamreal()
>>> dr1.website = 'company1.com'
>>> dr1.name = 'company1'
>>> dr1.mail = 'contact@company1'
>>> dr1.phonenumber = '12345'
>>> dr1.save()
>>> dr2 = Dreamreal()
>>> dr1.website = 'company2.com'
>>> dr2.website = 'company2.com'
>>> dr2.name = 'company2'
>>> dr2.mail = 'contact@company2'
>>> dr2.phonenumber = '56789'
>>> dr2.save()
现在是一些托管域名 −
Now some hosted domains −
>>> on1 = Online()
>>> on1.company = dr1
>>> on1.domain = "site1.com"
>>> on2 = Online()
>>> on2.company = dr1
>>> on2.domain = "site2.com"
>>> on3 = Online()
>>> on3.domain = "site3.com"
>>> dr2 = Dreamreal.objects.all()[2]
>>> on3.company = dr2
>>> on1.save()
>>> on2.save()
>>> on3.save()
从在线域名访问托管公司(Dreamreal 条目)的属性很简单 −
Accessing attribute of the hosting company (Dreamreal entry) from an online domain is simple −
>>> on1.company.name
如果我们想了解 Dreamreal 中某公司托管的所有在线域名,我们将使用此代码 −
And if we want to know all the online domain hosted by a Company in Dreamreal we will use the code −
>>> dr1.online_set.all()
要获取 QuerySet,请注意我们之前见过的所有操作方法(filter、all、exclude、order_by……)
To get a QuerySet, note that all manipulating method we have seen before (filter, all, exclude, order_by….)
你还可以访问已链接模型属性以进行筛选操作,我们来假设你想获取 Dreamreal
名称包含 company
的所有在线域名 −
You can also access the linked model attributes for filtering operations, let’s say you want to get all online domains where the Dreamreal name contains 'company' −
>>> Online.objects.filter(company__name__contains = 'company'
Note − 这种类型的查询只受 SQL DB 支持。它不适用于不存在连接符且有两个 _
的非关系型数据库。
Note − That kind of query is just supported for SQL DB. It won’t work for non-relational DB where joins doesn’t exist and there are two '_'.
但这不是链接模型的唯一方式,你也有 OneToOneField
,一个保证两个对象之间关系唯一性的链接。如果我们在线示例中使用了 OneToOneField
,这意味着对于每个 Dreamreal
条目,只有一个 Online
条目是可能的,反之亦然。
But that’s not the only way to link models, you also have OneToOneField, a link that guarantees that the relation between two objects is unique. If we used the OneToOneField in our example above, that would mean for every Dreamreal entry only one Online entry is possible and in the other way to.
最后,有 ManyToManyField
用于表之间的 (n-n) 关系。请注意,这些与基于 SQL 的数据库有关。
And the last one, the ManyToManyField for (n-n) relation between tables. Note, those are relevant for SQL based DB.
Django - Page Redirection
在网络应用程序中,页面重定向有诸多原因。当操作发生或者出错时,你可能希望将用户重定向到其他页面。例如,当用户登录到你的网站时,他经常被定向到主页或者他的个人信息中心。在 Django 中,重定向使用“重定向”方法实现。
Page redirection is needed for many reasons in web application. You might want to redirect a user to another page when a specific action occurs, or basically in case of error. For example, when a user logs in to your website, he is often redirected either to the main home page or to his personal dashboard. In Django, redirection is accomplished using the 'redirect' method.
“重定向”方法采用以下参数:您希望重定向到的网址字符串。视图名称。
The 'redirect' method takes as argument: The URL you want to be redirected to as string A view’s name.
到目前为止,myapp/views 如下所示 -
The myapp/views looks like the following so far −
def hello(request):
today = datetime.datetime.now().date()
daysOfWeek = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
return render(request, "hello.html", {"today" : today, "days_of_week" : daysOfWeek})
def viewArticle(request, articleId):
""" A view that display an article based on his ID"""
text = "Displaying article Number : %s" %articleId
return HttpResponse(text)
def viewArticles(request, year, month):
text = "Displaying articles of : %s/%s"%(year, month)
return HttpResponse(text)
我们来更改 hello 视图,将其重定向到 djangoproject.com,将我们的 viewArticle 视图重定向到内部的“/myapp/articles”。为此,myapp/view.py 将更改为 -
Let’s change the hello view to redirect to djangoproject.com and our viewArticle to redirect to our internal '/myapp/articles'. To do so the myapp/view.py will change to −
from django.shortcuts import render, redirect
from django.http import HttpResponse
import datetime
# Create your views here.
def hello(request):
today = datetime.datetime.now().date()
daysOfWeek = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
return redirect("https://www.djangoproject.com")
def viewArticle(request, articleId):
""" A view that display an article based on his ID"""
text = "Displaying article Number : %s" %articleId
return redirect(viewArticles, year = "2045", month = "02")
def viewArticles(request, year, month):
text = "Displaying articles of : %s/%s"%(year, month)
return HttpResponse(text)
在以上示例中,我们首先从 django.shortcuts 导入 redirect,为了重定向到 Django 官方网站,我们只需将完整的网址作为字符串传递给“重定向”方法,对于第二个示例(viewArticle 视图,“重定向”方法采用视图名称和参数作为参数。
In the above example, first we imported redirect from django.shortcuts and for redirection to the Django official website we just pass the full URL to the 'redirect' method as string, and for the second example (the viewArticle view) the 'redirect' method takes the view name and his parameters as arguments.
访问 /myapp/hello,会看到以下屏幕 -
Accessing /myapp/hello, will give you the following screen −
访问 /myapp/article/42,会看到以下屏幕 -
And accessing /myapp/article/42, will give you the following screen −
还可以通过添加 permanent = True 参数指定“重定向”是暂时的还是永久的。用户不会看到任何区别,但搜索引擎会考虑这些细节来对您的网站进行排名。
It is also possible to specify whether the 'redirect' is temporary or permanent by adding permanent = True parameter. The user will see no difference, but these are details that search engines take into account when ranking of your website.
在映射网址时还能记得到 url.py 中定义的“名称”参数 -
Also remember that 'name' parameter we defined in our url.py while mapping the URLs −
url(r'^articles/(?P\d{2})/(?P\d{4})/', 'viewArticles', name = 'articles'),
该名称(此处为 article)可以用作“重定向”方法的参数,然后我们的 viewArticle 重定向可以从 -
That name (here article) can be used as argument for the 'redirect' method, then our viewArticle redirection can be changed from −
def viewArticle(request, articleId):
""" A view that display an article based on his ID"""
text = "Displaying article Number : %s" %articleId
return redirect(viewArticles, year = "2045", month = "02")
{s0} -
To −
def viewArticle(request, articleId):
""" A view that display an article based on his ID"""
text = "Displaying article Number : %s" %articleId
return redirect(articles, year = "2045", month = "02")
{s1} - 还有一个函数来生成网址;它的用法与 redirect 相同;“反向”方法 (django.core.urlresolvers.reverse)。此方法不会返回 HttpResponseRedirect 对象,而只会返回一个包含与任何传递的参数一起编译的视图网址的字符串。
Note − There is also a function to generate URLs; it is used in the same way as redirect; the 'reverse' method (django.core.urlresolvers.reverse). This function does not return a HttpResponseRedirect object, but simply a string containing the URL to the view compiled with any passed argument.
Django - Sending E-mails
Django 带有一个使用方便的电子邮件发送引擎。与 Python 类似,您需要导入 smtplib。在 Django 中,您只需导入 django.core.mail。若要开始发送电子邮件,请编辑您的项目 settings.py 文件并设置以下选项 −
Django comes with a ready and easy-to-use light engine to send e-mail. Similar to Python you just need an import of smtplib. In Django you just need to import django.core.mail. To start sending e-mail, edit your project settings.py file and set the following options −
-
EMAIL_HOST − smtp server.
-
EMAIL_HOST_USER − Login credential for the smtp server.
-
EMAIL_HOST_PASSWORD − Password credential for the smtp server.
-
EMAIL_PORT − smtp server port.
-
EMAIL_USE_TLS or _SSL − True if secure connection.
Sending a Simple E-mail
让我们创建一个 "sendSimpleEmail" 视图以发送简单电子邮件。
Let’s create a "sendSimpleEmail" view to send a simple e-mail.
from django.core.mail import send_mail
from django.http import HttpResponse
def sendSimpleEmail(request,emailto):
res = send_mail("hello paul", "comment tu vas?", "paul@polo.com", [emailto])
return HttpResponse('%s'%res)
以下是 send_mail 参数的详细信息 −
Here is the details of the parameters of send_mail −
-
subject − E-mail subject.
-
message − E-mail body.
-
from_email − E-mail from.
-
recipient_list − List of receivers’ e-mail address.
-
fail_silently − Bool, if false send_mail will raise an exception in case of error.
-
auth_user − User login if not set in settings.py.
-
auth_password − User password if not set in settings.py.
-
connection − E-mail backend.
-
html_message − (new in Django 1.7) if present, the e-mail will be multipart/alternative.
让我们创建一个 URL 以访问我们的视图 −
Let’s create a URL to access our view −
from django.conf.urls import patterns, url
urlpatterns = paterns('myapp.views', url(r'^simpleemail/(?P<emailto>
[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/',
'sendSimpleEmail' , name = 'sendSimpleEmail'),)
因此,当访问 /myapp/simpleemail/polo@gmail.com 时,您将获得以下页面 −
So when accessing /myapp/simpleemail/polo@gmail.com, you will get the following page −
Sending Multiple Mails with send_mass_mail
该方法返回成功传送消息的数量。这与 send_mail 相同,但需要额外一个参数;datatuple,然后我们的 sendMassEmail 视图将变为 −
The method returns the number of messages successfully delivered. This is same as send_mail but takes an extra parameter; datatuple, our sendMassEmail view will then be −
from django.core.mail import send_mass_mail
from django.http import HttpResponse
def sendMassEmail(request,emailto):
msg1 = ('subject 1', 'message 1', 'polo@polo.com', [emailto1])
msg2 = ('subject 2', 'message 2', 'polo@polo.com', [emailto2])
res = send_mass_mail((msg1, msg2), fail_silently = False)
return HttpResponse('%s'%res)
让我们创建一个 URL 以访问我们的视图 −
Let’s create a URL to access our view −
from django.conf.urls import patterns, url
urlpatterns = paterns('myapp.views', url(r'^massEmail/(?P<emailto1>
[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/(?P<emailto2>
[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})', 'sendMassEmail' , name = 'sendMassEmail'),)
当访问 /myapp/massemail/polo@gmail.com/sorex@gmail.com/ 时,我们会得到 −
When accessing /myapp/massemail/polo@gmail.com/sorex@gmail.com/, we get −
send_mass_mail 参数详细信息 −
send_mass_mail parameters details are −
-
datatuples − A tuple where each element is like (subject, message, from_email, recipient_list).
-
fail_silently − Bool, if false send_mail will raise an exception in case of error.
-
auth_user − User login if not set in settings.py.
-
auth_password − User password if not set in settings.py.
-
connection − E-mail backend.
如上面的图片中可以看到,两封邮件发送成功。
As you can see in the above image, two messages were sent successfully.
Note − 在这个范例中,我们使用 Python smtp 调试服务器,可使用以下方法启动:
Note − In this example we are using Python smtp debuggingserver, that you can launch using −
$python -m smtpd -n -c DebuggingServer localhost:1025
这意味着您发送的所有电子邮件都将打印在 stdout 上,而虚拟服务器在 localhost:1025 上运行。
This means all your sent e-mails will be printed on stdout, and the dummy server is running on localhost:1025.
Sending e-mails to admins and managers using mail_admins and mail_managers methods
Sending e-mails to admins and managers using mail_admins and mail_managers methods
这些方法向设置文件 settings.py 的 ADMINS 选项中定义的网站管理员和 MANAGERS 选项中定义的网站管理者发送电子邮件。我们假设 ADMINS 和 MANAGERS 选项如下所示:
These methods send e-mails to site administrators as defined in the ADMINS option of the settings.py file, and to site managers as defined in MANAGERS option of the settings.py file. Let’s assume our ADMINS and MANAGERS options look like −
ADMINS = (('polo', ' polo@polo.com '),)
ADMINS = (('polo', 'polo@polo.com'),)
MANAGERS = (('popoli', ' popoli@polo.com '),)
MANAGERS = (('popoli', 'popoli@polo.com'),)
from django.core.mail import mail_admins
from django.http import HttpResponse
def sendAdminsEmail(request):
res = mail_admins('my subject', 'site is going down.')
return HttpResponse('%s'%res)
上述代码会向 ADMINS 部分中定义的每位管理员发送一封电子邮件。
The above code will send an e-mail to every admin defined in the ADMINS section.
from django.core.mail import mail_managers
from django.http import HttpResponse
def sendManagersEmail(request):
res = mail_managers('my subject 2', 'Change date on the site.')
return HttpResponse('%s'%res)
上述代码会向 MANAGERS 部分中定义的每位管理者发送一封电子邮件。
The above code will send an e-mail to every manager defined in the MANAGERS section.
参数详细信息 −
Parameters details −
-
Subject − E-mail subject.
-
message − E-mail body.
-
fail_silently − Bool, if false send_mail will raise an exception in case of error.
-
connection − E-mail backend.
-
html_message − (new in Django 1.7) if present, the e-mail will be multipart/alternative.
Sending HTML E-mail
在 Django >= 1.7 中发送 HTML 邮件如同以下代码所示:
Sending HTML message in Django >= 1.7 is as easy as −
from django.core.mail import send_mail
from django.http import HttpResponse
res = send_mail("hello paul", "comment tu vas?", "paul@polo.com",
["polo@gmail.com"], html_message=")
这会生成一个 multipart/alternative 电子邮件。
This will produce a multipart/alternative e-mail.
但是,在 Django < 1.7 中,要通过使用 django.core.mail.EmailMessage 类向对象调用“send”来发送 HTML 邮件 −
But for Django < 1.7 sending HTML messages is done via the django.core.mail.EmailMessage class then calling 'send' on the object −
让我们创建一个“sendHTMLEmail”视图来发送 HTML 邮件。
Let’s create a "sendHTMLEmail" view to send an HTML e-mail.
from django.core.mail import EmailMessage
from django.http import HttpResponse
def sendHTMLEmail(request , emailto):
html_content = "<strong>Comment tu vas?</strong>"
email = EmailMessage("my subject", html_content, "paul@polo.com", [emailto])
email.content_subtype = "html"
res = email.send()
return HttpResponse('%s'%res)
EmailMessage 类创建的参数详细信息 −
Parameters details for the EmailMessage class creation −
-
Subject − E-mail subject.
-
message − E-mail body in HTML.
-
from_email − E-mail from.
-
to − List of receivers’ e-mail address.
-
bcc − List of “Bcc” receivers’ e-mail address.
-
connection − E-mail backend.
让我们创建一个 URL 以访问我们的视图 −
Let’s create a URL to access our view −
from django.conf.urls import patterns, url
urlpatterns = paterns('myapp.views', url(r'^htmlemail/(?P<emailto>
[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/',
'sendHTMLEmail' , name = 'sendHTMLEmail'),)
访问 /myapp/htmlemail/polo@gmail.com 时,会得到 −
When accessing /myapp/htmlemail/polo@gmail.com, we get −
Sending E-mail with Attachment
这是通过在 EmailMessage 对象上使用“attach”方法来完成的。
This is done by using the 'attach' method on the EmailMessage object.
发送带附件的电子邮件的视图为:
A view to send an e-mail with attachment will be −
from django.core.mail import EmailMessage
from django.http import HttpResponse
def sendEmailWithAttach(request, emailto):
html_content = "Comment tu vas?"
email = EmailMessage("my subject", html_content, "paul@polo.com", emailto])
email.content_subtype = "html"
fd = open('manage.py', 'r')
email.attach('manage.py', fd.read(), 'text/plain')
res = email.send()
return HttpResponse('%s'%res)
附加参数的详情:
Details on attach arguments −
-
filename − The name of the file to attach.
-
content − The content of the file to attach.
-
mimetype − The attachment’s content mime type.
Django - Generic Views
在某些情况下,编写视图(如前面看到的那样)确实很繁琐。想象您需要一个静态页面或列表页面。Django 提供了一种设置这些简易视图的简单方法,该方法称为通用视图。
In some cases, writing views, as we have seen earlier is really heavy. Imagine you need a static page or a listing page. Django offers an easy way to set those simple views that is called generic views.
与经典视图不同,通用视图是类而不是函数。Django 在 django.views.generic 中提供了一组通用视图类,而每个通用视图都是这些类之一或从其中一个类继承的类。
Unlike classic views, generic views are classes not functions. Django offers a set of classes for generic views in django.views.generic, and every generic view is one of those classes or a class that inherits from one of them.
共有 10+ 个通用类:
There are 10+ generic classes −
>>> import django.views.generic
>>> dir(django.views.generic)
['ArchiveIndexView', 'CreateView', 'DateDetailView', 'DayArchiveView',
'DeleteView', 'DetailView', 'FormView', 'GenericViewError', 'ListView',
'MonthArchiveView', 'RedirectView', 'TemplateView', 'TodayArchiveView',
'UpdateView', 'View', 'WeekArchiveView', 'YearArchiveView', '__builtins__',
'__doc__', '__file__', '__name__', '__package__', '__path__', 'base', 'dates',
'detail', 'edit', 'list']
您可以将其用于您的通用视图。让我们看一些示例以了解其工作原理。
This you can use for your generic view. Let’s look at some example to see how it works.
Static Pages
让我们从“static.html”模板发布一个静态页面。
Let’s publish a static page from the “static.html” template.
我们的 static.html:
Our static.html −
<html>
<body>
This is a static page!!!
</body>
</html>
如果我们按照之前学习的方式进行操作,则必须将 myapp/views.py 更改为:
If we did that the way we learned before, we would have to change the myapp/views.py to be −
from django.shortcuts import render
def static(request):
return render(request, 'static.html', {})
并将 myapp/urls.py 更改为:
and myapp/urls.py to be −
from django.conf.urls import patterns, url
urlpatterns = patterns("myapp.views", url(r'^static/', 'static', name = 'static'),)
最好的方法是使用通用视图。为此,我们的 myapp/views.py 将变为:
The best way is to use generic views. For that, our myapp/views.py will become −
from django.views.generic import TemplateView
class StaticView(TemplateView):
template_name = "static.html"
而我们的 myapp/urls.py 将变为:
And our myapp/urls.py we will be −
from myapp.views import StaticView
from django.conf.urls import patterns
urlpatterns = patterns("myapp.views", (r'^static/$', StaticView.as_view()),)
在访问 /myapp/static 时,您会获得:
When accessing /myapp/static you get −
对于相同的结果,我们还可以执行以下操作:
For the same result we can also, do the following −
-
No change in the views.py
-
Change the url.py file to be −
from django.views.generic import TemplateView
from django.conf.urls import patterns, url
urlpatterns = patterns("myapp.views",
url(r'^static/',TemplateView.as_view(template_name = 'static.html')),)
如您所见,您只需在第二个方法中更改 url.py 文件。
As you can see, you just need to change the url.py file in the second method.
List and Display Data from DB
我们将列出 Dreamreal 模型中的所有条目。使用 ListView 通用视图类可以轻松做到这一点。编辑 url.py 文件并将其更新为 −
We are going to list all entries in our Dreamreal model. Doing so is made easy by using the ListView generic view class. Edit the url.py file and update it as −
from django.views.generic import ListView
from django.conf.urls import patterns, url
urlpatterns = patterns(
"myapp.views", url(r'^dreamreals/', ListView.as_view(model = Dreamreal,
template_name = "dreamreal_list.html")),
)
此时需要注意的是,通用视图传递给模板的变量是 object_list。如果您想要自己命名,则需要向 as_view 方法添加 context_object_name 参数。然后,url.py 将变为 −
Important to note at this point is that the variable pass by the generic view to the template is object_list. If you want to name it yourself, you will need to add a context_object_name argument to the as_view method. Then the url.py will become −
from django.views.generic import ListView
from django.conf.urls import patterns, url
urlpatterns = patterns("myapp.views",
url(r'^dreamreals/', ListView.as_view(
template_name = "dreamreal_list.html")),
model = Dreamreal, context_object_name = ”dreamreals_objects” ,)
然后,关联的模板将为 −
The associated template will then be −
{% extends "main_template.html" %}
{% block content %}
Dreamreals:<p>
{% for dr in object_list %}
{{dr.name}}</p>
{% endfor %}
{% endblock %}
访问 /myapp/dreamreals/ 将生成以下页面 −
Accessing /myapp/dreamreals/ will produce the following page −
Django - Form Processing
在 Django 中创建表单与创建模型非常相似。同样,我们只需要继承自 Django 类,而类属性将成为表单字段。我们将在 myapp 文件夹中添加一个 forms.py 文件来包含我们的应用表单。我们将创建一个登录表单。
Creating forms in Django, is really similar to creating a model. Here again, we just need to inherit from Django class and the class attributes will be the form fields. Let’s add a forms.py file in myapp folder to contain our app forms. We will create a login form.
myapp/forms.py
myapp/forms.py
#-*- coding: utf-8 -*-
from django import forms
class LoginForm(forms.Form):
user = forms.CharField(max_length = 100)
password = forms.CharField(widget = forms.PasswordInput())
如上所示,字段类型可以采用“widget”参数进行 html 渲染;在我们的案例中,我们希望密码隐藏,不显示。Django 中存在许多其他小组件: DateInput 用于日期, CheckboxInput 用于复选框等。
As seen above, the field type can take "widget" argument for html rendering; in our case, we want the password to be hidden, not displayed. Many others widget are present in Django: DateInput for dates, CheckboxInput for checkboxes, etc.
Using Form in a View
有两种 HTTP 请求,GET 和 POST。在 Django 中,作为参数传递给视图的请求对象有一个名为“method”的属性,其中设置请求的类型,可以通过 request.POST 词典访问通过 POST 传递的所有数据。
There are two kinds of HTTP requests, GET and POST. In Django, the request object passed as parameter to your view has an attribute called "method" where the type of the request is set, and all data passed via POST can be accessed via the request.POST dictionary.
我们将在 myapp/views.py 中创建一个登录视图 −
Let’s create a login view in our myapp/views.py −
#-*- coding: utf-8 -*-
from myapp.forms import LoginForm
def login(request):
username = "not logged in"
if request.method == "POST":
#Get the posted form
MyLoginForm = LoginForm(request.POST)
if MyLoginForm.is_valid():
username = MyLoginForm.cleaned_data['username']
else:
MyLoginForm = Loginform()
return render(request, 'loggedin.html', {"username" : username})
视图将显示通过 loggedin.html 发布的登录表单的结果。为了测试它,我们首先需要登录表单模板。我们称之为 login.html。
The view will display the result of the login form posted through the loggedin.html. To test it, we will first need the login form template. Let’s call it login.html.
<html>
<body>
<form name = "form" action = "{% url "myapp.views.login" %}"
method = "POST" >{% csrf_token %}
<div style = "max-width:470px;">
<center>
<input type = "text" style = "margin-left:20%;"
placeholder = "Identifiant" name = "username" />
</center>
</div>
<br>
<div style = "max-width:470px;">
<center>
<input type = "password" style = "margin-left:20%;"
placeholder = "password" name = "password" />
</center>
</div>
<br>
<div style = "max-width:470px;">
<center>
<button style = "border:0px; background-color:#4285F4; margin-top:8%;
height:35px; width:80%;margin-left:19%;" type = "submit"
value = "Login" >
<strong>Login</strong>
</button>
</center>
</div>
</form>
</body>
</html>
模板将显示一个登录表单,并将结果发布到我们上面的登录视图。您可能已经注意到模板中的标签,其仅用于防止对您的网站进行跨站请求伪造 (CSRF) 攻击。
The template will display a login form and post the result to our login view above. You have probably noticed the tag in the template, which is just to prevent Cross-site Request Forgery (CSRF) attack on your site.
{% csrf_token %}
一旦我们有了登录模板,就需要在表单处理后渲染的 loggedin.html 模板。
Once we have the login template, we need the loggedin.html template that will be rendered after form treatment.
<html>
<body>
You are : <strong>{{username}}</strong>
</body>
</html>
现在,我们只需要我们的 URL 对即可开始:myapp/urls.py
Now, we just need our pair of URLs to get started: myapp/urls.py
from django.conf.urls import patterns, url
from django.views.generic import TemplateView
urlpatterns = patterns('myapp.views',
url(r'^connection/',TemplateView.as_view(template_name = 'login.html')),
url(r'^login/', 'login', name = 'login'))
在访问“/myapp/connection”时,我们将获得以下登录.html 模板渲染 −
When accessing "/myapp/connection", we will get the following login.html template rendered −
在表单发布时,表单有效。在我们的案例中,确保填写这两个字段,您将得到 −
On the form post, the form is valid. In our case make sure to fill the two fields and you will get −
如果您的用户名是 polo,并且您忘记了密码。您将收到以下消息 −
In case your username is polo, and you forgot the password. You will get the following message −
Using Our Own Form Validation
在以上示例中,在验证表单时 −
In the above example, when validating the form −
MyLoginForm.is_valid()
在我们的案例中,我们只使用了 Django 自身表单验证引擎,只确保字段是必需的。现在,我们尝试确保尝试登录的用户作为 Dreamreal 条目存在于我们的数据库中。为此,将 myapp/forms.py 更改为:
We only used Django self-form validation engine, in our case just making sure the fields are required. Now let’s try to make sure the user trying to login is present in our DB as Dreamreal entry. For this, change the myapp/forms.py to −
#-*- coding: utf-8 -*-
from django import forms
from myapp.models import Dreamreal
class LoginForm(forms.Form):
user = forms.CharField(max_length = 100)
password = forms.CharField(widget = forms.PasswordInput())
def clean_message(self):
username = self.cleaned_data.get("username")
dbuser = Dreamreal.objects.filter(name = username)
if not dbuser:
raise forms.ValidationError("User does not exist in our db!")
return username
现在,在调用 “isValid” 方法之后,只有当用户在我们的数据库中时,我们才会获得正确的结果。如果你想检查表单中的某个字段,只需添加一个以 “clean_” 开头的方法,然后将你的字段名称添加到你的表单类中。提升 forms.ValidationError 非常重要。
Now, after calling the "is_valid" method, we will get the correct output, only if the user is in our database. If you want to check a field of your form, just add a method starting by "clean_" then your field name to your form class. Raising a forms.ValidationError is important.
Django - File Uploading
web 应用程序通常需要能够上传文件(个人资料图片、歌曲、pdf、文字……)。让我们在本章讨论如何在上传文件。
It is generally useful for a web app to be able to upload files (profile picture, songs, pdf, words…..). Let’s discuss how to upload files in this chapter.
Uploading an Image
在开始使用图像前,请确保你已安装了 Python 图像库 (PIL)。现在,为了说明如何上传图像,我们将在 myapp/forms.py 中创建一个个人资料表单 −
Before starting to play with an image, make sure you have the Python Image Library (PIL) installed. Now to illustrate uploading an image, let’s create a profile form, in our myapp/forms.py −
#-*- coding: utf-8 -*-
from django import forms
class ProfileForm(forms.Form):
name = forms.CharField(max_length = 100)
picture = forms.ImageFields()
正如你所见,这里的关键区别仅仅是 forms.ImageField 。ImageField 将确保上传的文件是图像。如果不是,表单验证将失败。
As you can see, the main difference here is just the forms.ImageField. ImageField will make sure the uploaded file is an image. If not, the form validation will fail.
现在,我们创建一个“个人资料”模型来保存我们上传的个人资料。这在 myapp/models.py 中完成 −
Now let’s create a "Profile" model to save our uploaded profile. This is done in myapp/models.py −
from django.db import models
class Profile(models.Model):
name = models.CharField(max_length = 50)
picture = models.ImageField(upload_to = 'pictures')
class Meta:
db_table = "profile"
正如你为模型所见,ImageField 需要必填参数 upload_to 。这代表你的图像将被保存到的硬盘驱动器位置。注意参数将被添加到在 settings.py 文件中定义的 MEDIA_ROOT 选项中。
As you can see for the model, the ImageField takes a compulsory argument: upload_to. This represents the place on the hard drive where your images will be saved. Note that the parameter will be added to the MEDIA_ROOT option defined in your settings.py file.
现在我们有了表单和模型,让我们在 myapp/views.py 中创建视图 −
Now that we have the Form and the Model, let’s create the view, in myapp/views.py −
#-*- coding: utf-8 -*-
from myapp.forms import ProfileForm
from myapp.models import Profile
def SaveProfile(request):
saved = False
if request.method == "POST":
#Get the posted form
MyProfileForm = ProfileForm(request.POST, request.FILES)
if MyProfileForm.is_valid():
profile = Profile()
profile.name = MyProfileForm.cleaned_data["name"]
profile.picture = MyProfileForm.cleaned_data["picture"]
profile.save()
saved = True
else:
MyProfileForm = Profileform()
return render(request, 'saved.html', locals())
不要错过的部分是创建 ProfileForm 时有改动,我们增加了第二个参数 request.FILES 。如果没有通过表单验证,它将失败,并给出图片为空的消息。
The part not to miss is, there is a change when creating a ProfileForm, we added a second parameters: request.FILES. If not passed the form validation will fail, giving a message that says the picture is empty.
现在,我们只需要 saved.html 模板和 profile.html 模板,分别用于表单和重定向页面 −
Now, we just need the saved.html template and the profile.html template, for the form and the redirection page −
myapp/templates/saved.html −
myapp/templates/saved.html −
<html>
<body>
{% if saved %}
<strong>Your profile was saved.</strong>
{% endif %}
{% if not saved %}
<strong>Your profile was not saved.</strong>
{% endif %}
</body>
</html>
myapp/templates/profile.html −
myapp/templates/profile.html −
<html>
<body>
<form name = "form" enctype = "multipart/form-data"
action = "{% url "myapp.views.SaveProfile" %}" method = "POST" >{% csrf_token %}
<div style = "max-width:470px;">
<center>
<input type = "text" style = "margin-left:20%;"
placeholder = "Name" name = "name" />
</center>
</div>
<br>
<div style = "max-width:470px;">
<center>
<input type = "file" style = "margin-left:20%;"
placeholder = "Picture" name = "picture" />
</center>
</div>
<br>
<div style = "max-width:470px;">
<center>
<button style = "border:0px;background-color:#4285F4; margin-top:8%;
height:35px; width:80%; margin-left:19%;" type = "submit" value = "Login" >
<strong>Login</strong>
</button>
</center>
</div>
</form>
</body>
</html>
接下来,我们需要一对 URL 来开始:myapp/urls.py
Next, we need our pair of URLs to get started: myapp/urls.py
from django.conf.urls import patterns, url
from django.views.generic import TemplateView
urlpatterns = patterns(
'myapp.views', url(r'^profile/',TemplateView.as_view(
template_name = 'profile.html')), url(r'^saved/', 'SaveProfile', name = 'saved')
)
当访问“/myapp/profile”时,我们将得到以下呈现的 profile.html 模板 −
When accessing "/myapp/profile", we will get the following profile.html template rendered −
在发布表单时,将渲染已保存的模板 −
And on form post, the saved template will be rendered −
我们有一个图像示例,但是,如果你想上传其他类型的文件,而不仅仅是图片,只需在 Model 和 Form 中用 FileField 替换 ImageField 。
We have a sample for image, but if you want to upload another type of file, not just image, just replace the ImageField in both Model and Form with FileField.
Django - Apache Setup
到目前为止,在我们的示例中,我们使用了 Django 开发 Web 服务器。但此服务器仅用于测试,不适合生产环境。一旦进入生产环境,就需要 Apache、Nginx 等真实服务器。让我们在本章中讨论 Apache。
So far, in our examples, we have used the Django dev web server. But this server is just for testing and is not fit for production environment. Once in production, you need a real server like Apache, Nginx, etc. Let’s discuss Apache in this chapter.
通过 Apache 提供 Django 应用程序是使用 mod_wsgi 完成的。所以首先要确保已安装 Apache 和 mod_wsgi。请记住,当我们创建项目并查看项目结构时,其看起来如下 −
Serving Django applications via Apache is done by using mod_wsgi. So the first thing is to make sure you have Apache and mod_wsgi installed. Remember, when we created our project and we looked at the project structure, it looked like −
myproject/
manage.py
myproject/
__init__.py
settings.py
urls.py
wsgi.py
wsgi.py 文件负责 Django 和 Apache 之间的链接。
The wsgi.py file is the one taking care of the link between Django and Apache.
假设我们想与 Apache 共享我们的项目(myproject)。我们只需要设置 Apache 以访问我们的文件夹即可。假设我们将 myproject 文件夹放在默认的 "/var/www/html" 中。在此阶段,将通过 127.0.0.1/myproject 访问项目。这将导致 Apache 仅列出文件夹,如下图所示。
Let’s say we want to share our project (myproject) with Apache. We just need to set Apache to access our folder. Assume we put our myproject folder in the default "/var/www/html". At this stage, accessing the project will be done via 127.0.0.1/myproject. This will result in Apache just listing the folder as shown in the following snapshot.
如所见,Apache 并未处理 Django 内容。若要处理此问题,我们需要在 httpd.conf 中配置 Apache。所以打开 httpd.conf 并添加以下行 −
As seen, Apache is not handling Django stuff. For this to be taken care of, we need to configure Apache in httpd.conf. So open the httpd.conf and add the following line −
WSGIScriptAlias / /var/www/html/myproject/myproject/wsgi.py
WSGIPythonPath /var/www/html/myproject/
<Directory /var/www/html/myproject/>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
如果您能以 127.0.0.1/myapp/connection 访问登录页面,您将会看到以下页面 −
If you can access the login page as 127.0.0.1/myapp/connection, you will get to see the following page −
Django - Cookies Handling
有时候,你可能希望根据 Web 应用程序的要求按每个网站访问者的基础存储一些数据。始终记住,Cookie 存储在客户端,并且根据客户端浏览器安全级别,设置 Cookie 有时会起作用,有时可能不会。
Sometimes you might want to store some data on a per-site-visitor basis as per the requirements of your web application. Always keep in mind, that cookies are saved on the client side and depending on your client browser security level, setting cookies can at times work and at times might not.
为了说明 Django 中的 Cookie 处理,让我们使用之前创建的登录系统创建一个系统。该系统会让你继续登录 X 分钟,在此时间之后,你将退出应用。
To illustrate cookies handling in Django, let’s create a system using the login system we created before. The system will keep you logged in for X minute of time, and beyond that time, you will be out of the app.
为此,你需要设置两个 Cookie,即 last_connection 和 username。
For this, you will need to set up two cookies, last_connection and username.
首先,让我们更改我们的登录视图来存储我们的 username 和 last_connection Cookie −
At first, let’s change our login view to store our username and last_connection cookies −
from django.template import RequestContext
def login(request):
username = "not logged in"
if request.method == "POST":
#Get the posted form
MyLoginForm = LoginForm(request.POST)
if MyLoginForm.is_valid():
username = MyLoginForm.cleaned_data['username']
else:
MyLoginForm = LoginForm()
response = render_to_response(request, 'loggedin.html', {"username" : username},
context_instance = RequestContext(request))
response.set_cookie('last_connection', datetime.datetime.now())
response.set_cookie('username', datetime.datetime.now())
return response
如上方的视图中所示,设置 Cookie 是通过对响应(而不是请求)调用的 set_cookie 方法完成的,还需要注意的是,所有 Cookie 值都作为字符串返回。
As seen in the view above, setting cookie is done by the set_cookie method called on the response not the request, and also note that all cookies values are returned as string.
现在,让我们为登录创建 formView,其中当 Cookie 设置且不早于 10 秒时,我们将不会显示表单 −
Let’s now create a formView for the login form, where we won’t display the form if cookie is set and is not older than 10 second −
def formView(request):
if 'username' in request.COOKIES and 'last_connection' in request.COOKIES:
username = request.COOKIES['username']
last_connection = request.COOKIES['last_connection']
last_connection_time = datetime.datetime.strptime(last_connection[:-7],
"%Y-%m-%d %H:%M:%S")
if (datetime.datetime.now() - last_connection_time).seconds < 10:
return render(request, 'loggedin.html', {"username" : username})
else:
return render(request, 'login.html', {})
else:
return render(request, 'login.html', {})
如上方的 formView 中所示,你可以通过请求的 COOKIES 属性(dict)来访问设置的 Cookie。
As you can see in the formView above accessing the cookie you set, is done via the COOKIES attribute (dict) of the request.
现在,让我们更改 url.py 文件来更改 URL,使其与我们的新视图配对 −
Now let’s change the url.py file to change the URL so it pairs with our new view −
from django.conf.urls import patterns, url
from django.views.generic import TemplateView
urlpatterns = patterns('myapp.views',
url(r'^connection/','formView', name = 'loginform'),
url(r'^login/', 'login', name = 'login'))
访问 /myapp/connection 时,你将获得以下页面 −
When accessing /myapp/connection, you will get the following page −
在提交后,你将被重定向到以下屏幕 −
And you will get redirected to the following screen on submit −
现在,如果 10 秒内再次尝试访问 /myapp/connection,您将被直接重定向到第二个屏幕。如果您在这个范围之外再次访问 /myapp/connection,您将看到登录表单(屏幕 1)。
Now, if you try to access /myapp/connection again in the 10 seconds range, you will get redirected to the second screen directly. And if you access /myapp/connection again out of this range you will get the login form (screen 1).
Django - Sessions
如前所述,我们可以使用客户端 cookie 为 Web 应用程序存储大量有用的数据。我们之前已经看到,我们可以使用客户端 cookie 为 Web 应用程序存储各种有用的数据。这会产生许多安全漏洞,具体取决于你想要保存的数据的重要性。
As discussed earlier, we can use client side cookies to store a lot of useful data for the web app. We have seen before that we can use client side cookies to store various data useful for our web app. This leads to lot of security holes depending on the importance of the data you want to save.
出于安全原因,Django 有一个会话框架,用于处理 cookie。会话用于抽象 cookie 的接收和发送,数据保存在服务器端(如在数据库中),并且客户端 cookie 只拥有一个用于标识的会话 ID。会话对于避免用户浏览器设置为“不接受”cookie 的情况也很有用。
For security reasons, Django has a session framework for cookies handling. Sessions are used to abstract the receiving and sending of cookies, data is saved on server side (like in database), and the client side cookie just has a session ID for identification. Sessions are also useful to avoid cases where the user browser is set to ‘not accept’ cookies.
Setting Up Sessions
在 Django 中,会话启用在你的项目 settings.py 中完成,通过向 MIDDLEWARE_CLASSES 和 INSTALLED_APPS 选项添加几行。这应该在创建项目时完成,但了解它总是好的,所以 MIDDLEWARE_CLASSES 应有:
In Django, enabling session is done in your project settings.py, by adding some lines to the MIDDLEWARE_CLASSES and the INSTALLED_APPS options. This should be done while creating the project, but it’s always good to know, so MIDDLEWARE_CLASSES should have −
'django.contrib.sessions.middleware.SessionMiddleware'
而 INSTALLED_APPS 应有:
And INSTALLED_APPS should have −
'django.contrib.sessions'
默认情况下,Django 将会话信息保存在数据库中(django_session 表或集合),但你可以配置引擎以使用其他方式存储信息,如在 file 或 cache 中。
By default, Django saves session information in database (django_session table or collection), but you can configure the engine to store information using other ways like: in file or in cache.
当会话启用时,每个请求(Django 中任何视图的第一个参数)都会有一个会话(dict)属性。
When session is enabled, every request (first argument of any view in Django) has a session (dict) attribute.
我们创建一个简单的示例,看看如何创建和保存会话。我们之前构建了一个简单的登录系统(请参阅 Django 表单处理章节和 Django Cookie 处理章节)。让我们将用户名保存在一个 cookie 中,因此如果不是注销,在访问登录页面时,你将看不到登录表单。基本上,让我们通过在服务器端保存 cookie 来使我们在 Django Cookie 处理中使用的登录系统更加安全。
Let’s create a simple sample to see how to create and save sessions. We have built a simple login system before (see Django form processing chapter and Django Cookies Handling chapter). Let us save the username in a cookie so, if not signed out, when accessing our login page you won’t see the login form. Basically, let’s make our login system we used in Django Cookies handling more secure, by saving cookies server side.
为此,首先让我们更改登录视图以将我们的用户名 cookie 保存到服务器端:
For this, first lets change our login view to save our username cookie server side −
def login(request):
username = 'not logged in'
if request.method == 'POST':
MyLoginForm = LoginForm(request.POST)
if MyLoginForm.is_valid():
username = MyLoginForm.cleaned_data['username']
request.session['username'] = username
else:
MyLoginForm = LoginForm()
return render(request, 'loggedin.html', {"username" : username}
然后,让我们为登录表单创建 formView 视图,如果设置了 cookie,我们不会显示表单:
Then let us create formView view for the login form, where we won’t display the form if cookie is set −
def formView(request):
if request.session.has_key('username'):
username = request.session['username']
return render(request, 'loggedin.html', {"username" : username})
else:
return render(request, 'login.html', {})
现在,让我们更改 url.py 文件以更改该 URL,以便它与我们的新视图配对:
Now let us change the url.py file to change the url so it pairs with our new view −
from django.conf.urls import patterns, url
from django.views.generic import TemplateView
urlpatterns = patterns('myapp.views',
url(r'^connection/','formView', name = 'loginform'),
url(r'^login/', 'login', name = 'login'))
当你访问 /myapp/connection 时,你将看到以下页面:
When accessing /myapp/connection, you will get to see the following page −
你将被重定向到以下页面:
And you will get redirected to the following page −
现在,如果你再次尝试访问 /myapp/connection,你将直接被重定向到第二个屏幕。
Now if you try to access /myapp/connection again, you will get redirected to the second screen directly.
我们创建一个简单的注销视图来抹除我们的 cookie。
Let’s create a simple logout view that erases our cookie.
def logout(request):
try:
del request.session['username']
except:
pass
return HttpResponse("<strong>You are logged out.</strong>")
并将其与 myapp/url.py 中的注销 URL 配对:
And pair it with a logout URL in myapp/url.py
url(r'^logout/', 'logout', name = 'logout'),
现在,如果你访问 /myapp/logout,你将看到以下页面:
Now, if you access /myapp/logout, you will get the following page −
如果你再次访问 /myapp/connection,你将获得登录表单(屏幕 1)。
If you access /myapp/connection again, you will get the login form (screen 1).
Some More Possible Actions Using Sessions
我们已经了解了如何存储和访问会话,但了解请求的会话属性还有一些其他有用的操作,如下所示:
We have seen how to store and access a session, but it’s good to know that the session attribute of the request have some other useful actions like −
-
set_expiry (value) − Sets the expiration time for the session.
-
get_expiry_age() − Returns the number of seconds until this session expires.
-
get_expiry_date() − Returns the date this session will expire.
-
clear_expired() − Removes expired sessions from the session store.
-
get_expire_at_browser_close() − Returns either True or False, depending on whether the user’s session cookies have expired when the user’s web browser is closed.
Django - Caching
缓存是指保存昂贵计算的结果,以便在下次需要时无需再执行计算。以下是一个解释缓存工作原理的伪代码 −
To cache something is to save the result of an expensive calculation, so that you don’t perform it the next time you need it. Following is a pseudo code that explains how caching works −
given a URL, try finding that page in the cache
if the page is in the cache:
return the cached page
else:
generate the page
save the generated page in the cache (for next time)
return the generated page
Django 自带缓存系统,可以用来保存动态页面,从而避免在需要时再次计算。Django 缓存框架的一个优点是可以缓存 −
Django comes with its own caching system that lets you save your dynamic pages, to avoid calculating them again when needed. The good point in Django Cache framework is that you can cache −
-
The output of a specific view.
-
A part of a template.
-
Your entire site.
要在 Django 中使用缓存,首先需要设置缓存的存放位置。缓存框架提供了多种可能选项 - 可以将缓存保存到数据库、文件系统或直接保存在内存中。设置在项目的 settings.py 文件中完成。
To use cache in Django, first thing to do is to set up where the cache will stay. The cache framework offers different possibilities - cache can be saved in database, on file system or directly in memory. Setting is done in the settings.py file of your project.
Setting Up Cache in Database
只需在项目 settings.py 文件中添加以下内容 −
Just add the following in the project settings.py file −
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_table_name',
}
}
要使此设置起作用并完成设置,我们需要创建名为`my_table_name`的缓存表。为此,你需要执行以下操作 −
For this to work and to complete the setting, we need to create the cache table 'my_table_name'. For this, you need to do the following −
python manage.py createcachetable
Setting Up Cache in File System
只需在项目 settings.py 文件中添加以下内容 −
Just add the following in the project settings.py file −
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
}
}
Setting Up Cache in Memory
这是最有效的缓存方式,要使用它,你可以根据为内存缓存选择的 Python 绑定库使用以下选项之一 −
This is the most efficient way of caching, to use it you can use one of the following options depending on the Python binding library you choose for the memory cache −
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
Or
Or
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'unix:/tmp/memcached.sock',
}
}
Caching the Entire Site
在 Django 中使用缓存最简单的方式是缓存整个站点。这可以通过编辑 project settings.py 中的 MIDDLEWARE_CLASSES 选项来完成。需要添加到该选项中的内容如下 −
The simplest way of using cache in Django is to cache the entire site. This is done by editing the MIDDLEWARE_CLASSES option in the project settings.py. The following need to be added to the option −
MIDDLEWARE_CLASSES += (
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
)
请注意,这里的顺序很重要,更新应在获取中间件之前。
Note that the order is important here, Update should come before Fetch middleware.
然后在同一文件中,你需要设置 −
Then in the same file, you need to set −
CACHE_MIDDLEWARE_ALIAS – The cache alias to use for storage.
CACHE_MIDDLEWARE_SECONDS – The number of seconds each page should be cached.
Caching a View
如果你不想缓存整个站点,可以缓存一个特定视图。这可以通过使用 Django 提供的 cache_page 装饰器来完成。假设我们要缓存 viewArticles 视图的结果 −
If you don’t want to cache the entire site you can cache a specific view. This is done by using the cache_page decorator that comes with Django. Let us say we want to cache the result of the viewArticles view −
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def viewArticles(request, year, month):
text = "Displaying articles of : %s/%s"%(year, month)
return HttpResponse(text)
正如你所见, cache_page 将视图结果缓存的时间作为参数。在我们上面的示例中,结果将缓存 15 分钟。
As you can see cache_page takes the number of seconds you want the view result to be cached as parameter. In our example above, the result will be cached for 15 minutes.
Note − 如上所述,以上视图映射到 −
Note − As we have seen before the above view was map to −
urlpatterns = patterns('myapp.views',
url(r'^articles/(?P<month>\d{2})/(?P<year>\d{4})/', 'viewArticles', name = 'articles'),)
由于 URL 接受参数,每一次不同的调用将被分别缓存。例如,对 /myapp/articles/02/2007 的请求将与 /myapp/articles/03/2008 分开缓存。
Since the URL is taking parameters, each different call will be cached separately. For example, request to /myapp/articles/02/2007 will be cached separately to /myapp/articles/03/2008.
还可以在 url.py 文件中直接缓存视图。以下是生成与上述相同结果的操作。只需编辑 myapp/url.py 文件,并将相关的映射 URL(上面)改成 −
Caching a view can also directly be done in the url.py file. Then the following has the same result as the above. Just edit your myapp/url.py file and change the related mapped URL (above) to be −
urlpatterns = patterns('myapp.views',
url(r'^articles/(?P<month>\d{2})/(?P<year>\d{4})/',
cache_page(60 * 15)('viewArticles'), name = 'articles'),)
当然,在 myapp/views.py 中不再需要它了。
And, of course, it’s no longer needed in myapp/views.py.
Caching a Template Fragment
你也可以使用 cache 标记缓存模板部分。我们使用 hello.html 模板来做演示 −
You can also cache parts of a template, this is done by using the cache tag. Let’s take our hello.html template −
{% extends "main_template.html" %}
{% block title %}My Hello Page{% endblock %}
{% block content %}
Hello World!!!<p>Today is {{today}}</p>
We are
{% if today.day == 1 %}
the first day of month.
{% elif today.day == 30 %}
the last day of month.
{% else %}
I don't know.
{%endif%}
<p>
{% for day in days_of_week %}
{{day}}
</p>
{% endfor %}
{% endblock %}
为了缓存内容块,我们的模板将变成 −
And to cache the content block, our template will become −
{% load cache %}
{% extends "main_template.html" %}
{% block title %}My Hello Page{% endblock %}
{% cache 500 content %}
{% block content %}
Hello World!!!<p>Today is {{today}}</p>
We are
{% if today.day == 1 %}
the first day of month.
{% elif today.day == 30 %}
the last day of month.
{% else %}
I don't know.
{%endif%}
<p>
{% for day in days_of_week %}
{{day}}
</p>
{% endfor %}
{% endblock %}
{% endcache %}
如你所见,cache 标记需要两个参数 − 希望块被缓存的时间(以秒为单位)以及给缓存片段的名称。
As you can see above, the cache tag will take 2 parameters − the time you want the block to be cached (in seconds) and the name to be given to the cache fragment.
Django - Comments
在开始之前,请注意 Django Comments 框架在 1.5 版本后已弃用。现在,你可以使用外部功能执行此操作,但如果你仍然想使用它,它仍包含在 1.6 和 1.7 版本中。从 1.8 版本开始,它已不存在,但你仍然可以在其他 GitHub 帐户上获取代码。
Before starting, note that the Django Comments framework is deprecated, since the 1.5 version. Now you can use external feature for doing so, but if you still want to use it, it’s still included in version 1.6 and 1.7. Starting version 1.8 it’s absent but you can still get the code on a different GitHub account.
注释框架能让你很轻松地为应用程序中的任何模型添加注释。
The comments framework makes it easy to attach comments to any model in your app.
若要开始使用 Django 注释框架 −
To start using the Django comments framework −
编辑项目 settings.py 文件,并在 INSTALLED_APPS 选项中添加 'django.contrib.sites' 和 'django.contrib.comments' −
Edit the project settings.py file and add 'django.contrib.sites', and 'django.contrib.comments', to INSTALLED_APPS option −
INSTALLED_APPS += ('django.contrib.sites', 'django.contrib.comments',)
获取网站 ID −
Get the site id −
>>> from django.contrib.sites.models import Site
>>> Site().save()
>>> Site.objects.all()[0].id
u'56194498e13823167dd43c64'
设置你在 settings.py 文件中获取的 ID −
Set the id you get in the settings.py file −
SITE_ID = u'56194498e13823167dd43c64'
同步 db,以创建所有注释表或集合 −
Sync db, to create all the comments table or collection −
python manage.py syncdb
将注释应用程序的 URL 添加到项目的 urls.py 中 −
Add the comment app’s URLs to your project’s urls.py −
from django.conf.urls import include
url(r'^comments/', include('django.contrib.comments.urls')),
现在我们已安装该框架,让我们更改我们的 hello 模板,以便在 Dreamreal 模型上跟踪评论。我们将列出 Dreamreal 特定条目的评论,并将该条目作为参数传递给 /myapp/hello URL。
Now that we have the framework installed, let’s change our hello templates to tracks comments on our Dreamreal model. We will list, save comments for a specific Dreamreal entry whose name will be passed as parameter to the /myapp/hello URL.
Dreamreal Model
class Dreamreal(models.Model):
website = models.CharField(max_length = 50)
mail = models.CharField(max_length = 50)
name = models.CharField(max_length = 50)
phonenumber = models.IntegerField()
class Meta:
db_table = "dreamreal"
hello view
def hello(request, Name):
today = datetime.datetime.now().date()
daysOfWeek = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
dreamreal = Dreamreal.objects.get(name = Name)
return render(request, 'hello.html', locals())
hello.html template
{% extends "main_template.html" %}
{% load comments %}
{% block title %}My Hello Page{% endblock %}
{% block content %}
<p>
Our Dreamreal Entry:
<p><strong>Name :</strong> {{dreamreal.name}}</p>
<p><strong>Website :</strong> {{dreamreal.website}}</p>
<p><strong>Phone :</strong> {{dreamreal.phonenumber}}</p>
<p><strong>Number of comments :<strong>
{% get_comment_count for dreamreal as comment_count %} {{ comment_count }}</p>
<p>List of comments :</p>
{% render_comment_list for dreamreal %}
</p>
{% render_comment_form for dreamreal %}
{% endblock %}
最后,将 URL 映射到我们的 hello 视图 −
Finally the mapping URL to our hello view −
url(r'^hello/(?P<Name>\w+)/', 'hello', name = 'hello'),
现在,
Now,
-
In our template (hello.html), load the comments framework with − {% load comments %}
-
We get the number of comments for the Dreamreal object pass by the view − {% get_comment_count for dreamreal as comment_count %}
-
We get the list of comments for the objects − {% render_comment_list for dreamreal %}
-
We display the default comments form − {% render_comment_form for dreamreal %}
当访问 /myapp/hello/steve 时,你将获取名称为 Steve 的 Dreamreal 条目的评论信息。访问该 URL,你将获取 −
When accessing /myapp/hello/steve you will get the comments info for the Dreamreal entry whose name is Steve. Accessing that URL will get you −
在发布评论后,你将被重定向至以下页面 −
On posting a comment, you will get redirected to the following page −
如果你再次访问 /myapp/hello/steve,你将看到以下页面 −
If you go to /myapp/hello/steve again, you will get to see the following page −
如你所见,现在评论数量为 1,并且你在评论列表行下方看到了评论。
As you can see, the number of comments is 1 now and you have the comment under the list of comments line.
Django - RSS
Django 带有一个联合提要生成框架。利用此框架,您可以通过对 django.contrib.syndication.views.Feed class 进行子类化来创建 RSS 或 Atom 提要。
Django comes with a syndication feed generating framework. With it you can create RSS or Atom feeds just by subclassing django.contrib.syndication.views.Feed class.
让我们创建一个提要,以了解应用程序上进行的最新评论(另请参阅 Django - 注释框架章节)。为此,我们创建一个 myapp/feeds.py 并定义我们的提要(您可以在代码结构中的任何位置放置您的提要类)。
Let’s create a feed for the latest comments done on the app (Also see Django - Comments Framework chapter). For this, let’s create a myapp/feeds.py and define our feed (You can put your feeds classes anywhere you want in your code structure).
from django.contrib.syndication.views import Feed
from django.contrib.comments import Comment
from django.core.urlresolvers import reverse
class DreamrealCommentsFeed(Feed):
title = "Dreamreal's comments"
link = "/drcomments/"
description = "Updates on new comments on Dreamreal entry."
def items(self):
return Comment.objects.all().order_by("-submit_date")[:5]
def item_title(self, item):
return item.user_name
def item_description(self, item):
return item.comment
def item_link(self, item):
return reverse('comment', kwargs = {'object_pk':item.pk})
-
In our feed class, title, link, and description attributes correspond to the standard RSS <title>, <link> and <description> elements.
-
The items method, return the elements that should go in the feed as item element. In our case the last five comments.
-
The item_title method, will get what will go as title for our feed item. In our case the title, will be the user name.
-
The item_description method, will get what will go as description for our feed item. In our case the comment itself.
-
The item_link method will build the link to the full item. In our case it will get you to the comment.
既然我们有了提要,让我们在 views.py 中添加一个评论视图以显示我们的评论 -
Now that we have our feed, let’s add a comment view in views.py to display our comment −
from django.contrib.comments import Comment
def comment(request, object_pk):
mycomment = Comment.objects.get(object_pk = object_pk)
text = '<strong>User :</strong> %s <p>'%mycomment.user_name</p>
text += '<strong>Comment :</strong> %s <p>'%mycomment.comment</p>
return HttpResponse(text)
我们还需要在 myapp urls.py 中添加一些 URL 以进行映射 -
We also need some URLs in our myapp urls.py for mapping −
from myapp.feeds import DreamrealCommentsFeed
from django.conf.urls import patterns, url
urlpatterns += patterns('',
url(r'^latest/comments/', DreamrealCommentsFeed()),
url(r'^comment/(?P\w+)/', 'comment', name = 'comment'),
)
访问 /myapp/latest/comments/,您将获得我们的提要 -
When accessing /myapp/latest/comments/ you will get our feed −
然后,单击其中一个用户名将带您访问:/myapp/comment/comment_id (如我们在之前的注释视图中定义的那样),您将获得 -
Then clicking on one of the usernames will get you to: /myapp/comment/comment_id as defined in our comment view before and you will get −
因此,定义 RSS 提要只是子类化 Feed 类并确保定义 URL(一个用于访问提要,一个用于访问提要元素)的问题。就像注释一样,这可以附加到应用程序中的任何模型。
Thus, defining a RSS feed is just a matter of sub-classing the Feed class and making sure the URLs (one for accessing the feed and one for accessing the feed elements) are defined. Just as comment, this can be attached to any model in your app.
Django - Ajax
Ajax 本质上是将技术组合在一起以减少页面加载次数。我们通常使用 Ajax 来方便最终用户体验。在 Django 中使用 Ajax 可以通过直接使用 Ajax 库,如 JQuery 或其他库来实现。假设您想要使用 JQuery,那么您需要下载并通过 Apache 或其他方式在服务器上提供该库。然后在您的模板中使用它,就像您在开发任何基于 Ajax 的应用程序时所做的那样。
Ajax essentially is a combination of technologies that are integrated together to reduce the number of page loads. We generally use Ajax to ease end-user experience. Using Ajax in Django can be done by directly using an Ajax library like JQuery or others. Let’s say you want to use JQuery, then you need to download and serve the library on your server through Apache or others. Then use it in your template, just like you might do while developing any Ajax-based application.
在 Django 中使用 Ajax 的另一种方式是使用 Django Ajax 框架。最常用的是 django-dajax,这是一个功能强大的工具,可以使用 Python 和几乎没有 JavaScript 源代码轻松且快速地开发 Web 应用程序中的异步演示逻辑。它支持四种最流行的 Ajax 框架:Prototype、jQuery、Dojo 和 MooTools。
Another way of using Ajax in Django is to use the Django Ajax framework. The most commonly used is django-dajax which is a powerful tool to easily and super-quickly develop asynchronous presentation logic in web applications, using Python and almost no JavaScript source code. It supports four of the most popular Ajax frameworks: Prototype, jQuery, Dojo and MooTools.
Using Django-dajax
首先要做的是安装 django-dajax。可以使用 easy_install 或 pip 完成此操作 −
First thing to do is to install django-dajax. This can be done using easy_install or pip −
$ pip install django_dajax
$ easy_install django_dajax
这将自动安装 django-dajaxice,这是 django-dajax 所需的。然后我们需要配置 dajax 和 dajaxice。
This will automatically install django-dajaxice, required by django-dajax. We then need to configure both dajax and dajaxice.
在 INSTALLED_APPS 选项中,在项目的 settings.py 中添加 dajax 和 dajaxice −
Add dajax and dajaxice in your project settings.py in INSTALLED_APPS option −
INSTALLED_APPS += (
'dajaxice',
'dajax'
)
确保在相同的 settings.py 文件中,您具有以下内容 −
Make sure in the same settings.py file, you have the following −
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
'django.template.loaders.eggs.Loader',
)
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.core.context_processors.request',
'django.contrib.messages.context_processors.messages'
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'dajaxice.finders.DajaxiceFinder',
)
DAJAXICE_MEDIA_PREFIX = 'dajaxice'
现在转到 myapp/url.py 文件,并确保您具有以下内容来设置 dajax URL 和加载 dajax 静态 js 文件 −
Now go to the myapp/url.py file and make sure you have the following to set dajax URLs and to load dajax statics js files −
from dajaxice.core import dajaxice_autodiscover, dajaxice_config
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf import settings
Then dajax urls:
urlpatterns += patterns('',
url(r'^%s/' % settings.DAJAXICE_MEDIA_PREFIX, include('dajaxice.urls')),)
urlpatterns += staticfiles_urlpatterns()
让我们基于我们的 Dreamreal 模型创建一个简单的表单,使用 Ajax(指无需刷新)来存储它。
Let us create a simple form based on our Dreamreal model to store it, using Ajax (means no refresh).
首先,我们需要在 myapp/form.py 中的 Dreamreal 表单。
At first, we need our Dreamreal form in myapp/form.py.
class DreamrealForm(forms.Form):
website = forms.CharField(max_length = 100)
name = forms.CharField(max_length = 100)
phonenumber = forms.CharField(max_length = 50)
email = forms.CharField(max_length = 100)
然后,我们需要在我们的应用程序中有一个 ajax.py 文件:myapp/ajax.py。这就是我们的逻辑所在,这是我们放置保存我们的表单的函数的位置,然后返回弹出窗口 −
Then we need an ajax.py file in our application: myapp/ajax.py. That’s where is our logic, that’s where we put the function that will be saving our form then return the popup −
from dajaxice.utils import deserialize_form
from myapp.form import DreamrealForm
from dajax.core import Dajax
from myapp.models import Dreamreal
@dajaxice_register
def send_form(request, form):
dajax = Dajax()
form = DreamrealForm(deserialize_form(form))
if form.is_valid():
dajax.remove_css_class('#my_form input', 'error')
dr = Dreamreal()
dr.website = form.cleaned_data.get('website')
dr.name = form.cleaned_data.get('name')
dr.phonenumber = form.cleaned_data.get('phonenumber')
dr.save()
dajax.alert("Dreamreal Entry %s was successfully saved." %
form.cleaned_data.get('name'))
else:
dajax.remove_css_class('#my_form input', 'error')
for error in form.errors:
dajax.add_css_class('#id_%s' % error, 'error')
return dajax.json()
现在让我们创建具有我们表单的 dreamreal.html 模板 −
Now let’s create the dreamreal.html template, which has our form −
<html>
<head></head>
<body>
<form action = "" method = "post" id = "my_form" accept-charset = "utf-8">
{{ form.as_p }}
<p><input type = "button" value = "Send" onclick = "send_form();"></p>
</form>
</body>
</html>
在 myapp/views.py 中添加与模板相对应的视图 −
Add the view that goes with the template in myapp/views.py −
def dreamreal(request):
form = DreamrealForm()
return render(request, 'dreamreal.html', locals())
在 myapp/urls.py 中添加相应的 URL −
Add the corresponding URL in myapp/urls.py −
url(r'^dreamreal/', 'dreamreal', name = 'dreamreal'),
现在让我们在我们的模板中添加 Ajax 工作必需的内容 −
Now let’s add the necessary in our template to make the Ajax work −
在文件的顶部添加 −
At the top of the file add −
{% load static %}
{% load dajaxice_templatetags %}
在 dreamreal.html 模板的 <head> 部分添加 −
And in the <head> section of our dreamreal.html template add −
我们为这个示例使用 JQuery 库,所以添加 −
We are using the JQuery library for this example, so add −
<script src = "{% static '/static/jquery-1.11.3.min.js' %}"
type = "text/javascript" charset = "utf-8"></script>
<script src = "{% static '/static/dajax/jquery.dajax.core.js' %}"></script>
在单击时调用的 Ajax 函数 −
The Ajax function that will be called on click −
<script>
function send_form(){
Dajaxice.myapp.send_form(Dajax.process,{'form':$('#my_form').serialize(true)});
}
</script>
请注意,您需要在静态文件目录中有“jquery-1.11.3.min.js”,还需要 jquery.dajax.core.js。要确保所有 dajax 静态文件都在您的静态目录下提供,请运行 −
Note that you need the “jquery-1.11.3.min.js” in your static files directory, and also the jquery.dajax.core.js. To make sure all dajax static files are served under your static directory, run −
$python manage.py collectstatic
Note − 有时 jquery.dajax.core.js 可能丢失了,如果遇到这种情况,只需下载源代码,并将该文件放入静态文件夹中即可。
Note − Sometimes the jquery.dajax.core.js can be missing, if that happens, just download the source and take that file and put it under your static folder.
访问 /myapp/dreamreal/ 后,您将看到以下屏幕 −
You will get to see the following screen, upon accessing /myapp/dreamreal/ −
提交后,您将会看到以下屏幕 −
On submit, you will get the following screen −