目录

Django - 快速指南

Django - Basics

Django是一个高级Python Web框架,鼓励快速开发和干净,实用的设计。 Django可以更轻松地使用更少的代码快速构建更好的Web应用程序。

Note - Django是Django Software Foundation的注册商标,并根据BSD许可进行许可。

Django的历史

  • 2003 - 由Adrian Holovaty和Simon Willison在Lawrence Journal-World报纸上担任内部项目。

  • 2005 - 2005年7月发布,并以爵士吉他手Django Reinhardt命名为Django。

  • 2005 - 足够成熟,可以处理几个高流量的网站。

  • Current - Django现在是一个开源项目,在世界各地都有贡献者。

Django - 设计哲学

Django具有以下设计理念 -

  • Loosely Coupled - Django旨在使其堆栈中的每个元素独立于其他元素。

  • Less Coding - 更少的代码,所以反过来快速开发。

  • Don't Repeat Yourself (DRY) - 一切都应该只在一个地方开发,而不是一次又一次地重复。

  • Fast Development - Django的理念是尽一切可能促进超快速开发。

  • Clean Design - Django在其自己的代码中严格保持干净的设计,并且可以轻松地遵循最佳的Web开发实践。

Django的优点

以下是使用Django的一些优点,可以在这里列出 -

  • Object-Relational Mapping (ORM) Support - Django提供了数据模型和数据库引擎之间的桥梁,并支持大量数据库系统,包括MySQL,Oracle,Postgres等.Django还通过Django-nonrel fork支持NoSQL数据库。 目前,唯一支持的NoSQL数据库是MongoDB和谷歌应用引擎。

  • Multilingual Support - Django通过其内置的国际化系统支持多语言网站。 因此,您可以开发支持多种语言的网站。

  • Framework Support - Django内置了对Ajax,RSS,缓存和各种其他框架的支持。

  • Administration GUI - Django为管理活动提供了一个很好的即用型用户界面。

  • Development Environment - Django附带了一个轻量级的Web服务器,以促进端到端的应用程序开发和测试。

Django - Overview

如您所知,Django是一个Python Web框架。 和大多数现代框架一样,Django支持MVC模式。 首先让我们看看什么是模型 - 视图 - 控制器(MVC)模式,然后我们将看看Django对模型 - 视图 - 模板(MVT)模式的特殊性。

MVC模式

在谈论提供UI(Web或桌面)的应用程序时,我们通常会讨论MVC架构。 顾名思义,MVC模式基于三个组件:模型,视图和控制器。 在这里查看我们的MVC教程以了解更多信息。

DJANGO MVC - MVT模式

模型 - 视图 - 模板(MVT)与MVC略有不同。 事实上,这两种模式之间的主要区别在于Django本身负责控制器部分(控制模型和视图之间交互的软件代码),让我们留下模板。 该模板是与Django模板语言(DTL)混合的HTML文件。

下图说明了MVT模式的每个组件如何相互交互以满足用户请求 -

DJANGO MVC  -  MVT模式

开发人员提供模型,视图和模板,然后将其映射到URL,Django可以为用户提供服务。

Django - Environment

Django开发环境包括安装和设置Python,Django和数据库系统。 由于Django处理Web应用程序,因此值得一提的是您还需要Web服务器设置。

第1步 - 安装Python

Django是用100%纯Python代码编写的,因此您需要在系统上安装Python。 最新的Django版本需要2.6.x分支的Python 2.6.5或更高版本或2.7.x分支的2.7.3或更高版本。

如果您使用的是最新的Linux或Mac OS X发行版之一,则可能已经安装了Python。 您可以通过在命令提示符下键入python命令来验证它。 如果你看到这样的东西,那么就安装了Python。

$ 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。

第2步 - 安装Django

安装Django非常简单,但安装所需的步骤取决于您的操作系统。 由于Python是一种独立于平台的语言,因此Django有一个适用于任何地方的软件包,无论您的操作系统如何。

您可以从http://www.djangoproject.com/download链接下载最新版本的Django。

UNIX/Linux和Mac OS X安装

如果您运行Linux或Mac OS系统,有两种方法可以安装Django -

  • 您可以使用操作系统的软件包管理器,也可以使用easy_install或pip(如果已安装)。

  • 使用您之前下载的官方存档手动安装。

我们将介绍第二个选项,因为第一个选项取决于您的操作系统分发。 如果您决定遵循第一个选项,请注意您正在安装的Django版本。

假设您从上面的链接获得了存档,它应该像Django-x.xx.tar.gz:

提取并安装。

$ tar xzvf Django-x.xx.tar.gz
$ cd Django-x.xx
$ sudo python setup.py install

您可以通过运行此命令来测试您的安装 -

$ django-admin.py --version

如果您在屏幕上看到当前版本的Django,那么一切都已设置完毕。

Note - 对于某些版本的Django,它将是django-admin,“。py”被删除。

Windows安装 (Windows Installation)

我们假设您的计算机上安装了Django存档和python。

首先,PATH验证。

在某些版本的Windows(Windows 7)上,您可能需要确保Path系统变量的路径如下C:\Python27\;C:\Python27\Lib\site-packages\django\bin\ in当然取决于您的Python版本。

然后,解压缩并安装Django。

c:\>cd c:\Django-x.xx

接下来,通过运行以下命令安装Django,在Windows shell“cmd”中需要管理权限 -

c:\Django-x.xx>python setup.py install

要测试安装,请打开命令提示符并键入以下命令 -

c:\>django-admin.py --version

如果您在屏幕上看到当前版本的Django,那么一切都已设置完毕。

OR

启动“cmd”提示符然后键入python -

c:\> python
>>> import django
>>> print django.get_version()

第3步 - 数据库设置

Django支持几个主要的数据库引擎,你可以根据自己的舒适度设置它们。

您可以参考相应的文档来安装和配置您选择的数据库。

Note - 数字5和6是NoSQL数据库。

第4步 - Web服务器

Django附带了一个轻量级Web服务器,用于开发和测试应用程序。 此服务器已预先配置为与Django一起使用,更重要的是,只要您修改代码,它就会重新启动。

但是,Django确实支持Apache和其他流行的Web服务器,如Lighttpd。 在使用不同的示例时,我们将讨论后续章节中的两种方法。

Django - Creating a Project

现在我们已经安装了Django,让我们开始使用它。 在Django中,您要创建的每个Web应用程序都称为项目; 一个项目是一个应用程序的总和。 应用程序是依赖于MVT模式的一组代码文件。 例如,假设我们要建立一个网站,网站是我们的项目,论坛,新闻,联系引擎都是应用程序。 由于每个应用程序都是独立的,因此这种结构可以更轻松地在项目之间移动应

创建一个项目 (Create a Project)

无论您是在Windows还是Linux上,只需获取终端或cmd提示并导航到您希望创建项目的位置,然后使用此代码 -

$ django-admin startproject myproject

这将创建一个具有以下结构的“myproject”文件夹 -

myproject/
   manage.py
   myproject/
      __init__.py
      settings.py
      urls.py
      wsgi.py

项目结构

“myproject”文件夹只是你的项目容器,它实际上包含两个元素 -

  • manage.py - 这个文件是你的项目本地django-admin,用于通过命令行与你的项目进行交互(启动开发服务器,同步数据库......)。 要获取可通过manage.py访问的完整命令列表,您可以使用代码 -

$ python manage.py help
  • The “myproject” subfolder - 此文件夹是项目的实际python包。 它包含四个文件 -

    • __init__.py - 只为python,将此文件夹视为包。

    • settings.py - 如名称所示,您的项目设置。

    • urls.py - 项目的所有链接和要调用的函数。 一种你项目的ToC。

    • wsgi.py - 如果需要通过WSGI部署项目。

设置项目

您的项目已在子文件夹myproject/settings.py中设置。 以下是您可能需要设置的一些重要选项 -

DEBUG = True

此选项允许您设置项目是否处于调试模式。 调试模式可让您获得有关项目错误的更多信息。 永远不要为实时项目将其设置为“True”。 但是,如果您希望Django light服务器提供静态文件,则必须将其设置为“True”。 仅在开发模式下执行。

DATABASES = {
   'default': {
      'ENGINE': 'django.db.backends.sqlite3',
      'NAME': 'database.sql',
      'USER': '',
      'PASSWORD': '',
      'HOST': '',
      'PORT': '',
   }
}

数据库在“数据库”字典中设置。 上面的例子是针对SQLite引擎的。 如前所述,Django也支持 -

  • MySQL(django.db.backends.mysql)
  • PostGreSQL(django.db.backends.postgresql_psycopg2)
  • Oracle(django.db.backends.oracle)和NoSQL DB
  • MongoDB(django_mongodb_engine)

在设置任何新引擎之前,请确保已安装正确的数据库驱动程序。

您还可以设置其他选项,如:TIME_ZONE,LANGUAGE_CODE,TEMPLATE ...

现在您的项目已创建并配置,确保它正常工作 -

$ python manage.py runserver

在运行上述代码时,您将获得以下内容 -

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

项目是许多应用程序的总和。 每个应用程序都有一个目标,可以重复使用到另一个项目中,比如网站上的联系表单可以是一个应用程序,并且可以重用给其他人。 将其视为项目的一个模块。

创建一个应用程序

我们假设您在项目文件夹中。 在我们的主“myproject”文件夹中,相同的文件夹然后manage.py -

$ python manage.py startapp myapp

你刚刚创建了myapp应用程序和项目,Django创建了一个带有应用程序结构的“myapp”文件夹 -

myapp/
   __init__.py
   admin.py
   models.py
   tests.py
   views.py
  • __init__.py - 只是为了确保python将此文件夹作为包处理。

  • admin.py - 此文件可帮助您在管理界面中修改应用程序。

  • models.py - 这是存储所有应用程序模型的地方。

  • tests.py - 这是您的单元测试的地方。

  • views.py - 这是您的应用程序视图的位置。

让项目了解您的应用程序

在这个阶段,我们有“myapp”应用程序,现在我们需要在我们的Django项目“myproject”中注册它。 为此,请在项目的settings.py文件中更新INSTALLED_APPS元组(添加您的应用程序名称) -

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根据您的项目模型自动生成管理UI。

启动管理界面

Admin界面依赖于django.countrib模块。 要使其正常工作,您需要确保在myproject/settings.py文件的INSTALLED_APPS和MIDDLEWARE_CLASSES元组中导入一些模块。

对于INSTALLED_APPS,请确保您有 -

INSTALLED_APPS = (
   'django.contrib.admin',
   'django.contrib.auth',
   'django.contrib.contenttypes',
   'django.contrib.sessions',
   'django.contrib.messages',
   'django.contrib.staticfiles',
   'myapp',
)

对于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',
)

在启动服务器之前,要访问管理界面,您需要启动数据库 -

$ python manage.py migrate

syncdb将根据您的数据库类型创建必要的表或集合,这是管理界面运行所必需的。 即使您没有超级用户,也会提示您创建一个超级用户。

如果您已经有超级用户或忘记了它,您可以使用以下代码创建一个 -

$ python manage.py createsuperuser

现在要启动管理界面,我们需要确保为管理界面配置了一个URL。 打开myproject/url.py你应该有类似的东西 -

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)),
)

现在只需运行服务器。

$ python manage.py runserver

您可以通过以下网址访问您的管理界面:http://127.0.0.1:8000/admin/

管理界面

与超级用户帐户连接后,您将看到以下屏幕 -

超级用户帐户

该界面将允许您管理Django组和用户,以及您应用中的所有注册模型。 该界面使您能够在模型上至少执行“CRUD”(创建,读取,更新,删除)操作。

Django - Creating Views

视图函数或简称“视图”只是一个Python函数,它接受Web请求并返回Web响应。 此响应可以是网页的HTML内容,重定向,404错误,XML文档或图像等。示例:您使用视图创建网页,请注意您需要关联视图到URL以将其视为网页。

在Django中,必须在app views.py文件中创建视图。

简单的看法

我们将在myapp中创建一个简单的视图,说“欢迎来到我的应用程序!”

请参阅以下视图 -

from django.http import HttpResponse
def hello(request):
   text = """<h1>welcome to my app !</h1>"""
   return HttpResponse(text)

在这个视图中,我们使用HttpResponse来呈现HTML(因为您可能已经注意到我们在视图中对HTML进行了硬编码)。 要将此视图视为页面,我们只需将其映射到URL(这将在下一章中讨论)。

我们之前使用HttpResponse在视图中呈现HTML。 这不是呈现页面的最佳方式。 Django支持MVT模式以便制作先例视图,Django-MVT就像我们需要的那样 -

模板:myapp/templates/hello.html

现在我们的观点看起来像 -

from django.shortcuts import render
def hello(request):
   return render(request, "myapp/template/hello.html", {})

视图也可以接受参数 -

from django.http import HttpResponse
def hello(request, number):
   text = "<h1>welcome to my app number %s!</h1>"% number
   return HttpResponse(text)

链接到URL时,页面将显示作为参数传递的数字。 请注意,参数将通过URL传递(在下一章中讨论)。

Django - URL Mapping

现在我们已经有了前面章节中解释的工作视图。 我们想通过URL访问该视图。 Django有自己的URL映射方式,它是通过编辑项目url.py文件(myproject/url.py) 。 url.py文件看起来像 -

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模式中的元组,如 -

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 pattern - 匹配您要解析的URL和映射的正则表达式。 可以使用python're'模块的所有内容都符合该模式(当您想通过url传递参数时非常有用)。

  • The python path to the view - 与导入模块时相同。

  • The name - 为了执行URL反转,您需要使用命名URL模式,如上面的示例所示。 完成后,只需启动服务器即可访问您的视图:http://127.0.0.1/hello

整理您的网址

到目前为止,我们已经在“myprojects/url.py”文件中创建了URL,但是如前所述,关于Django和创建应用程序,最好的一点是能够在不同的项目中重用应用程序。 如果要将所有URL保存在“projecturl.py”文件中,则可以轻松查看问题所在。 因此,最佳做法是为每个应用程序创建一个“url.py”,并将其包含在我们的主项目url.py文件中(我们之前包含管理界面的管理URL)。

整理网址

怎么做的?

我们需要使用以下代码在myapp中创建url.py文件 -

from django.conf.urls import patterns, include, url
urlpatterns = patterns('', url(r'^hello/', 'myapp.views.hello', name = 'hello'),)

然后myproject/url.py将更改为以下内容 -

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应用程序结构。

我的项目

现在让我们假设我们在myapp“morning”中有另一个视图,我们想在myapp/url.py中映射它,然后我们将myapp/url.py更改为 -

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'),
)

这可以重新考虑到 -

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元组的第一个元素。 当您想要更改应用名称时,此功能非常有用。

网址格式

将参数发送到视图

我们现在知道如何映射URL,如何组织它们,现在让我们看看如何将参数发送到视图。 一个经典示例是文章示例(您想通过“/ articles/article_id”访问文章)。

传递参数是通过使用URL模式中的正则regexp捕获它们来完成的。 如果我们在“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”中的以下内容 -

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视图,在浏览器中你应该得到以下结果 -

将参数传递给viewArticle

请注意,参数的顺序在这里很重要。 假设我们想要一年中一个月的文章列表,让我们添加一个viewArticles视图。 我们的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)
def viewArticles(request, month, year):
   text = "Displaying articles of : %s/%s"%(year, month)
   return HttpResponse(text)

相应的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'),
   url(r'^articles/(\d{2})/(\d{4})', 'viewArticles', name = 'articles'),)

现在,当你去“/ myapp/articles/12/2006 /”时,你会得到'显示文章:2006/12',但如果你反转参数,你将得不到相同的结果。

显示文章

为避免这种情况,可以将URL参数链接到view参数。 为此,我们的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'),
   url(r'^articles/(?P\d{2})/(?P\d{4})', 'viewArticles', name = 'articles'),)

Django - Template System

Django可以分离python和HTML,python进入视图,HTML进入模板。 为了链接这两者,Django依赖于渲染功能和Django模板语言。

渲染功能

这个功能有三个参数 -

  • Request - 初始请求。

  • The path to the template的路径 - 这是相对于项目settings.py变量中的TEMPLATE_DIRS选项的路径。

  • Dictionary of parameters字典 - 包含模板中所需的所有变量的字典。 可以创建此变量,也可以使用locals()传递视图中声明的所有局部变量。

Django Template Language (DTL)

Django的模板引擎提供了一种迷你语言来定义应用程序的面向用户的层。

显示变量

变量如下所示:{{variable}}。 模板通过render函数的第三个参数中的视图发送的变量替换变量。 让我们改变我们的hello.html来显示今天的日期 -

hello.html

<html>
   <body>
      Hello World!!!<p>Today is {{today}}</p>
   </body>
</html>

那么我们的观点将改为 -

def hello(request):
   today = datetime.datetime.now().date()
   return render(request, "hello.html", {"today" : today})

现在,我们将在访问URL/myapp/hello后得到以下输出 -

Hello World!!!
Today is Sept. 11, 2015

您可能已经注意到,如果变量不是字符串,Django将使用__str__方法来显示它; 并且使用相同的原则,您可以像在Python中一样访问对象属性。 例如:如果我们想显示日期年份,我的变量将是:{{today.year}}。

过滤器 (Filters)

它们可以帮助您在显示时修改变量。 过滤器结构如下所示:{{var | filters}}。

Some examples -

  • {{string|truncatewords:80}} - 此过滤器将截断字符串,因此您只能看到前80个单词。

  • {{string|lower}} - 将字符串转换为小写。

  • {{string|escape|linebreaks}} - 转义字符串内容,然后将换行符转换为标签。

您还可以设置变量的默认值。

Tags

使用标签可以执行以下操作:if条件,for循环,模板继承等。

Tag if

就像在Python中一样,你可以在你的模板中使用if,else和elif -

<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>

在此新模板中,根据当天的日期,模板将呈现特定值。

标记为

就像'if'一样,我们有'for'标签,就像在Python中一样。 让我们更改我们的hello视图以将列表传输到我们的模板 -

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}}显示该列表的模板 -

<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>

我们应该得到类似的东西 -

Hello World!!!
Today is Sept. 11, 2015
We are I don't know.
Mon
Tue
Wed
Thu
Fri
Sat
Sun

阻止和扩展标签

没有模板继承,模板系统就无法完成。 在设计模板时的意思是,您应该有一个带有孔的主模板,孩子的模板将根据自己的需要填充,例如页面可能需要为所选选项卡提供特殊的CSS。

让我们将hello.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

{% 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来重构我们的代码 -

在main_template.html中,我们使用标记块定义块。 标题栏将包含页面标题,内容块将包含页面主要内容。 在home.html中,我们使用extends从main_template.html继承,然后我们填充上面的块定义(内容和标题)。

评论标签

注释标记有助于将注释定义到模板中,而不是HTML注释,它们不会出现在HTML页面中。 它可用于文档或只是注释一行代码。

Django - Models

模型是表示数据库中的表或集合的类,其中类的每个属性都是表或集合的字段。 模型在app/models.py中定义(在我们的示例中:myapp/models.py)

创建模型

以下是作为示例创建的Dreamreal模型 -

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。

我们的类有4个属性(3个CharField和1个Integer),它们将是表字段。

具有db_table属性的Meta类允许我们定义实际的表或集合名称。 Django自动命名表或集合:myapp_modelName。 此类将允许您将表的名称强制为您喜欢的。

django.db.models中有更多字段类型,您可以在https://docs.djangoproject.com/en/1.5/ref/models/fields/#field-types上了解更多相关信息。

创建模型后,您将需要Django来生成实际的数据库 -

$python manage.py syncdb

Manipulating Data (CRUD)

让我们创建一个“crudops”视图,看看我们如何在模型上进行CRUD操作。 我们的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)

其他数据操作

让我们探讨一下我们可以对模型做的其他操作。 请注意,CRUD操作是在我们模型的实例上完成的,现在我们将直接使用代表我们模型的类。

让我们在myapp/views.py创建一个'datamanipulation'视图

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)

链接模型

Django ORM提供3种链接模型的方法 -

我们将在这里看到的第一个案例之一是一对多关系。 正如您在上面的示例中所看到的,Dreamreal公司可以拥有多个在线网站。 通过使用django.db.models.ForeignKey来定义该关系 -

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中看到的,我们添加了在线模型并将其链接到我们的Dreamreal模型。

让我们通过manage.py shell检查所有这些是如何工作的 -

首先让我们创建一些公司(Dreamreal条目)在我们的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()

现在一些托管域名 -

>>> 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条目)很简单 -

>>> on1.company.name

如果我们想知道Dreamreal公司托管的所有在线域名,我们将使用该代码 -

>>> dr1.online_set.all()

要获取QuerySet,请注意我们之前看到的所有操作方法(filter,all,exclude,order_by ....)

您还可以访问链接模型属性以进行过滤操作,假设您想要获取Dreamreal名称包含“公司”的所有在线域名 -

>>> Online.objects.filter(company__name__contains = 'company'

Note - SQL DB只支持这种查询。 它不适用于不存在连接且存在两个“_”的非关系数据库。

但这不是链接模型的唯一方法,您还有OneToOneField,这是一个保证两个对象之间的关系是唯一的链接。 如果我们在上面的示例中使用了OneToOneField,那么对于每个Dreamreal条目来说,只有一个在线条目是可能的,而在另一个方面。

最后一个,表之间的(nn)关系的ManyToManyField。 注意,这些与基于SQL的DB相关。

Django - Page Redirection

Web应用程序中出于多种原因需要页面重定向。 您可能希望在发生特定操作时将用户重定向到另一个页面,或者基本上是出现错误。 例如,当用户登录您的网站时,他经常被重定向到主要主页或他的个人仪表板。 在Django中,使用“重定向”方法完成重定向。

'redirect'方法作为参数:您要重定向到的URL作为字符串A视图的名称。

到目前为止myapp/views看起来如下 -

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将更改为 -

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导入重定向,并且为了重定向到Django官方网站,我们只是将完整的URL作为字符串传递给'redirect'方法,对于第二个例子(viewArticle视图),'redirect' method将视图名称及其参数作为参数。

访问/ myapp/hello,将为您提供以下屏幕 -

Django页面重定向Example1

并访问/ myapp/article/42,将为您提供以下屏幕 -

Django页面重定向Example2

通过添加permanent = True参数,还可以指定“重定向”是临时的还是永久的。 用户将看不到任何差异,但这些是搜索引擎在您的网站排名时考虑的详细信息。

还要记住我们在url.py中定义的'name'参数,同时映射URL -

url(r'^articles/(?P\d{2})/(?P\d{4})/', 'viewArticles', name = 'articles'),

该名称(此处文章)可以用作'重定向'方法的参数,然后我们的viewArticle重定向可以从 - 更改 -

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")

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")

Note - 还有一个生成URL的功能; 它的使用方式与重定向相同; '反向'方法(django.core.urlresolvers.reverse)。 此函数不返回HttpResponseRedirect对象,而只返回包含使用任何传递参数编译的视图的URL的字符串。

Django - Sending E-mails

Django带有一个易于使用的简易光引擎来发送电子邮件。 与Python类似,您只需要导入smtplib。 在Django中,您只需要导入django.core.mail。 要开始发送电子邮件,请编辑项目settings.py文件并设置以下选项 -

  • EMAIL_HOST - smtp服务器。

  • EMAIL_HOST_USER - smtp服务器的登录凭据。

  • EMAIL_HOST_PASSWORD - smtp服务器的密码凭据。

  • EMAIL_PORT - smtp服务器端口。

  • EMAIL_USE_TLS or _SSL - 如果安全连接, EMAIL_USE_TLS or _SSL True。

发送简单的电子邮件

让我们创建一个“sendSimpleEmail”视图来发送一个简单的电子邮件。

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参数的详细信息 -

  • subject - 电子邮件主题。

  • message - 电子邮件正文。

  • from_email - 来自的电子邮件。

  • recipient_list - 接收者的电子邮件地址列表。

  • fail_silently - Bool,如果false send_mail将在出错时引发异常。

  • auth_user - 如果未在settings.py中设置, auth_user用户登录。

  • auth_password - 如果未在settings.py中设置, auth_password用户密码。

  • connection - 电子邮件后端。

  • html_message - (Django 1.7中的新功能)如果存在,电子邮件将是多部分/替代。

让我们创建一个URL来访问我们的视图 -

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时,您将看到以下页面 -

发送简单的电子邮件

使用send_mass_mail发送多个邮件

该方法返回成功传递的消息数。 这与send_mail相同,但需要额外的参数; datatuple,我们的sendMassEmail视图将是 -

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('%<b class="notranslate">s</b>'%res)

让我们创建一个URL来访问我们的视图 -

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/时,我们得到 -

发送多个邮件

send_mass_mail参数详情是 -

  • datatuples - 每个元素类似的元组(subject,message,from_email,recipient_list)。

  • fail_silently - Bool,如果false send_mail将在出错时引发异常。

  • auth_user - 如果未在settings.py中设置, auth_user用户登录。

  • auth_password - 如果未在settings.py中设置, auth_password用户密码。

  • connection - 电子邮件后端。

如上图所示,成功发送了两条消息。

Note - 在本例中,我们使用的是Python smtp debuggingserver,您可以使用 -

$python -m smtpd -n -c DebuggingServer localhost:1025

这意味着您发送的所有电子邮件都将打印在stdout上,虚拟服务器正在localhost:1025上运行。

Sending e-mails to admins and managers using mail_admins and mail_managers methods

这些方法按照settings.py文件的ADMINS选项中的定义向站点管理员发送电子邮件,并按settings.py文件的MANAGERS选项中的定义向站点管理员发送电子邮件。 让我们假设我们的ADMINS和MANAGERS选项看起来像 -

ADMINS =(('polo','polo@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('<b class="notranslate">%s</b>'%res)

上面的代码将向ADMINS部分中定义的每个管理员发送一封电子邮件。

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('<b class="notranslate">%s</b>'%res)

上面的代码将向MANAGERS部分中定义的每个经理发送一封电子邮件。

参数详情 -

  • Subject - 电子邮件主题。

  • message - 电子邮件正文。

  • fail_silently - Bool,如果false send_mail将在出错时引发异常。

  • connection - 电子邮件后端。

  • html_message - (Django 1.7中的新功能)如果存在,电子邮件将是多部分/替代。

发送HTML电子邮件

在Django> = 1.7中发送HTML消息就像 -

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=")

这将产生一个多部分/替代电子邮件。

但是对于Django <1.7,发送HTML消息是通过django.core.mail.EmailMessage类完成的,然后在对象上调用'send' -

让我们创建一个“sendHTMLEmail”视图来发送HTML电子邮件。

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('<b class="notranslate">%s</b>'%res)

EmailMessage类创建的参数详细信息 -

  • Subject - 电子邮件主题。

  • message - HTML中的电子邮件正文。

  • from_email - 来自的电子邮件。

  • to - 接收者的电子邮件地址列表。

  • 密送 - “密件抄送”收件人的电子邮件地址列表。

  • connection - 电子邮件后端。

让我们创建一个URL来访问我们的视图 -

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时,我们得到 -

发送HTML电子邮件

发送带附件的电子邮件

这是通过在EmailMessage对象上使用'attach'方法完成的。

发送带附件的电子邮件的视图将是 -

from django.core.mail import EmailMessage
from django.http import HttpResponse
def sendEmailWithAttach(request, emailto):
   html_content = "<b class="notranslate">Comment tu vas?</b>"
   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('<b class="notranslate">%s</b>'%res)

附加参数的详细信息 -

  • filename - 要附加的文件的名称。

  • content - 要附加的文件的内容。

  • mimetype - 附件的内容mime类型。

Django - Generic Views

在某些情况下,正如我们之前看到的那样,写视图非常重要。 想象一下,您需要一个静态页面或列表页面。 Django提供了一种简单的方法来设置那些称为通用视图的简单视图。

与经典视图不同,通用视图是类而不是函数。 Django在django.views.generic中为泛型视图提供了一组类,每个泛型视图都是其中一个类或从其中一个继承的类。

有10多个通用类 -

>>> 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']

这可以用于您的通用视图。 让我们看一些例子,看看它是如何工作的。

静态页面

让我们从“static.html”模板发布一个静态页面。

我们的static.html -

<html>
   <body> 
      This is a static page!!! 
   </body>
</html>

如果我们按照以前的方式做到这一点,我们必须将myapp/views.py更改为 -

from django.shortcuts import render
def static(request):
   return render(request, 'static.html', {})

myapp/urls.py是 -

from django.conf.urls import patterns, url
urlpatterns = patterns("myapp.views", url(r'^static/', 'static', name = 'static'),)

最好的方法是使用通用视图。 为此,我们的myapp/views.py将成为 -

from django.views.generic import TemplateView
class StaticView(TemplateView):
   template_name = "static.html"

我们的myapp/urls.py我们将 -

from myapp.views import StaticView
from django.conf.urls import patterns
urlpatterns = patterns("myapp.views", (r'^static/$', StaticView.as_view()),)

访问/ myapp/static时,你会得到 -

静态页面

为了同样的结果,我们也可以,做以下 -

  • views.py中没有变化
  • 将url.py文件更改为 -
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文件。

从DB列出和显示数据

我们将列出Dreamreal模型中的所有条目。 通过使用ListView通用视图类,可以轻松完成此操作。 编辑url.py文件并将其更新为 -

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将成为 -

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” ,)

相关的模板将是 -

{% extends "main_template.html" %}
{% block content %}
Dreamreals:<p>
{% for dr in object_list %}
{{dr.name}}</p>
{% endfor %}
{% endblock %}

访问/ myapp/dreamreals /将生成以下页面 -

从DB列出和显示数据

Django - Form Processing

在Django中创建表单与创建模型非常相似。 在这里,我们只需要继承Django类,类属性将是表单字段。 让我们在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())

如上所示,字段类型可以采用html渲染的“widget”参数; 在我们的例子中,我们希望隐藏密码,而不是显示密码。 Django中存在许多其他小部件:日期的DateInputCheckboxInput等。

在视图中使用表单

有两种HTTP请求,GET和POST。 在Django中,作为参数传递给视图的请求对象有一个名为“method”的属性,其中设置了请求的类型,并且可以通过request.POST字典访问通过POST传递的所有数据。

让我们在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。

<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)攻击。

{% csrf_token %}

获得登录模板后,我们需要在表单处理后呈现的loggedin.html模板。

<html>
   <body>
      You are : <strong>{{username}}</strong>
   </body>
</html>

现在,我们只需要开始使用这对URL: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”时,我们将获得以下login.html模板 -

登录HTML模板

在表单帖子上,表单有效。 在我们的情况下,确保填写这两个字段,你会得到 -

表格验证

如果您的用户名是polo,并且您忘记了密码。 您将收到以下消息 -

表格无效的讯息

使用我们自己的表格验证

在上面的例子中,验证表格时 -

MyLoginForm.is_valid()

我们只使用Django自我形式验证引擎,在我们的例子中只是确保字段是必需的。 现在让我们尝试确保尝试登录的用户作为Dreamreal条目出现在我们的数据库中。 为此,请将myapp/forms.py更改为 -

#-*- 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

现在,在调用“is_valid”方法之后,只有当用户在我们的数据库中时,我们才会得到正确的输出。 如果要检查表单的字段,只需添加一个以“clean_”开头的方法,然后将您的字段名称添加到表单类中。 提升forms.ValidationError非常重要。

Django - File Uploading

通常,网络应用程序能够上传文件(个人资料图片,歌曲,PDF格式,单词.....)非常有用。 我们将在本章讨论如何上传文件。

上传图片

在开始播放图像之前,请确保已安装Python Image Library(PIL)。 现在为了说明上传图片,让我们在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将确保上传的文件是图像。 如果没有,表单验证将失败。

现在让我们创建一个“配置文件”模型来保存我们上传的个人资料。 这是在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选项中。

现在我们有了Form和Model,让我们在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 。 如果未通过,则表单验证将失败,并显示一条消息,指出图片为空。

现在,我们只需要saved.html模板和profile.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 -

<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

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模板 -

正在上传图片

在表单帖子上,将呈现保存的模板 -

表格帖子模板

我们有一个图像样本,但是如果你想上传另一种类型的文件,而不仅仅是图像,只需用ImageField替换Model和Form中的FileField

Django - Apache Setup

到目前为止,在我们的示例中,我们使用了Django开发Web服务器。 但是这个服务器只是用于测试,不适合生产环境。 一旦投入生产,你需要一个像Apache,Nginx等真正的服务器。让我们在本章讨论Apache。

通过Apache提供Django应用程序是通过使用mod_wsgi完成的。 所以首先要确保安装了Apache和mod_wsgi。 请记住,当我们创建项目并查看项目结构时,它看起来像 -

myproject/
   manage.py
   myproject/
      __init__.py
      settings.py
      urls.py
      wsgi.py

wsgi.py文件是处理Django和Apache之间链接的文件。

假设我们想与Apache共享我们的项目(myproject)。 我们只需要设置Apache来访问我们的文件夹。 假设我们将myproject文件夹放在默认的“/ var/www/html”中。 在此阶段,将通过127.0.0.1/myproject访问项目。 这将导致Apache只列出该文件夹,如下面的快照所示。

Django Apache安装程序

如图所示,Apache没有处理Django的东西。 为了解决这个问题,我们需要在httpd.conf中配置Apache。 所以打开httpd.conf并添加以下行 -

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,您将看到以下页面 -

登录页面

Django - Cookies Handling

有时,您可能希望根据Web应用程序的要求在每个站点访问者的基础上存储一些数据。 请记住,cookie是保存在客户端的,并且根据您的客户端浏览器安全级别,设置cookie有时可能会工作,有时可能不会。

为了说明Django中的cookie处理,让我们使用之前创建的登录系统创建一个系统。 系统将让您保持登录X分钟的时间,超过该时间,您将退出应用程序。

为此,您需要设置两个cookie,last_connection和username。

首先,让我们更改我们的登录视图以存储我们的用户名和last_connection cookie -

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值都以字符串形式返回。

现在让我们为登录表单创建一个formView,如果设置了cookie并且不超过10秒,我们将不会显示表单 -

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中看到的,访问您设置的cookie,是通过请求的COOKIES属性(dict)完成的。

现在让我们更改url.py文件以更改URL,使其与我们的新视图配对 -

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时,您将看到以下页面 -

Django Cookies处理

并且您将在提交时重定向到以下屏幕 -

Cookie处理重定向页面

现在,如果您尝试在10秒范围内再次访问/ myapp/connection,您将直接重定向到第二个屏幕。 如果您再次访问此范围内的/ myapp/connection,您将获得登录表单(屏幕1)。

Django - Sessions

如前所述,我们可以使用客户端cookie为Web应用程序存储大量有用的数据。 我们之前已经看到,我们可以使用客户端cookie来存储对我们的Web应用程序有用的各种数据。 这会导致许多安全漏洞,具体取决于您要保存的数据的重要性。

出于安全原因,Django有一个用于cookie处理的会话框架。 会话用于抽象cookie的接收和发送,数据保存在服务器端(如数据库中),客户端cookie只有一个会话ID用于标识。 会话对于避免用户浏览器设置为“不接受”cookie的情况也很有用。

设置会话

在Django中,通过向MIDDLEWARE_CLASSESINSTALLED_APPS选项添加一些行,在项目settings.py完成启用会话。 这应该在创建项目时完成,但总是很好知道,所以MIDDLEWARE_CLASSES应该 -

'django.contrib.sessions.middleware.SessionMiddleware'

并且INSTALLED_APPS应该 -

'django.contrib.sessions'

默认情况下,Django将会话信息保存在数据库(django_session表或集合)中,但您可以使用其他方式配置引擎以存储信息,例如:在file或在cache

启用会话时,每个请求(Django中任何视图的第一个参数)都具有会话(dict)属性。

让我们创建一个简单的示例来了解如何创建和保存会话。 我们之前已经构建了一个简单的登录系统(参见Django表格处理章节和Django Cookies处理章节)。 让我们将用户名保存在cookie中,这样如果没有注销,当访问我们的登录页面时,您将看不到登录表单。 基本上,让我们通过保存cookie服务器端使我们在Django Cookies中使用的登录系统更安全。

为此,首先让我们更改我们的登录视图以保存我们的用户名cookie服务器端 -

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,我们将不会显示表单 -

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文件以更改网址,以便与我们的新视图配对 -

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时,您将看到以下页面 -

设置会话

您将被重定向到以下页面 -

会话重定向页面

现在,如果您再次尝试访问/ myapp/connection,您将直接重定向到第二个屏幕。

让我们创建一个简单的注销视图来删除我们的cookie。

def logout(request):
   try:
      del request.session['username']
   except:
      pass
   return HttpResponse("<strong>You are logged out.</strong>")

并将其与myapp/url.py中的注销URL配对

url(r'^logout/', 'logout', name = 'logout'),

现在,如果您访问/ myapp/logout,您将看到以下页面 -

登出页面

如果再次访问/ myapp/connection,您将获得登录表单(屏幕1)。

使用会话的一些更可能的操作

我们已经了解了如何存储和访问会话,但最好知道请求的会话属性还有一些其他有用的操作,如 -

  • set_expiry ( value ) - 设置会话的到期时间。

  • get_expiry_age() - 返回此会话到期之前的秒数。

  • get_expiry_date() - 返回此会话将过期的日期。

  • clear_expired() - 从会话存储中删除过期的会话。

  • get_expire_at_browser_close() - 返回True或False,具体取决于用户的Web浏览器关闭时用户的会话cookie是否已过期。

Django - Caching

缓存某些内容是为了保存昂贵计算的结果,以便下次需要时不执行它。 以下是一个伪代码,解释了缓存的工作原理 -

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 Cache框架的优点是你可以缓存 -

  • 特定视图的输出。
  • 模板的一部分。
  • 你的整个网站。

要在Django中使用缓存,首先要做的是设置缓存将保留的位置。 缓存框架提供了不同的可能性 - 缓存可以保存在数据库,文件系统或直接存储在内存中。 设置在项目的settings.py文件中完成。

在数据库中设置缓存

只需在项目settings.py文件中添加以下内容 -

CACHES = {
   'default': {
      'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
      'LOCATION': 'my_table_name',
   }
}

为了使其工作并完成设置,我们需要创建缓存表'my_table_name'。 为此,您需要执行以下操作 -

python manage.py createcachetable

在文件系统中设置缓存

只需在项目settings.py文件中添加以下内容 -

CACHES = {
   'default': {
      'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
      'LOCATION': '/var/tmp/django_cache',
   }
}

在内存中设置缓存

这是最有效的缓存方式,使用它您可以使用以下选项之一,具体取决于您为内存缓存选择的Python绑定库 -

CACHES = {
   'default': {
      'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
      'LOCATION': '127.0.0.1:11211',
   }
}

Or

CACHES = {
   'default': {
      'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
      'LOCATION': 'unix:/tmp/memcached.sock',
   }
}

缓存整个站点

在Django中使用缓存的最简单方法是缓存整个站点。 这是通过编辑项目settings.py中的MIDDLEWARE_CLASSES选项来完成的。 以下需要添加到选项中 -

MIDDLEWARE_CLASSES += (
   'django.middleware.cache.UpdateCacheMiddleware',
   'django.middleware.common.CommonMiddleware',
   'django.middleware.cache.FetchFromCacheMiddleware',
)

请注意,顺序在这里很重要,更新应该在Fetch中间件之前。

然后在同一个文件中,你需要设置 -

CACHE_MIDDLEWARE_ALIAS – The cache alias to use for storage.
CACHE_MIDDLEWARE_SECONDS – The number of seconds each page should be cached.

缓存视图

如果您不想缓存整个站点,则可以缓存特定视图。 这是通过使用Django附带的cache_page装饰器完成的。 让我们说我们要缓存viewArticles视图的结果 -

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分钟。

Note - 正如我们之前看到的,上面的视图是映射到 -

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。

缓存视图也可以直接在url.py文件中完成。 然后以下具有与上述相同的结果。 只需编辑myapp/url.py文件并将相关的映射URL(上图)更改为 -

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中不再需要它。

缓存模板片段

您还可以缓存模板的某些部分,这可以通过使用cache标记来完成。 我们来看看我们的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 %}

要缓存内容块,我们的模板将成为 -

{% 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 %}

如上所示,缓存标记将采用2个参数 - 您希望缓存块的时间(以秒为单位)以及要为缓存片段指定的名称。

Django - Comments

在开始之前,请注意,自1.5版本以来,不推荐使用Django Comments框架。 现在您可以使用外部功能,但如果您仍想使用它,它仍然包含在1.6和1.7版本中。 从版本1.8开始它没有,但您仍然可以在不同的GitHub帐户上获取代码。

评论框架可以轻松地将评论附加到您应用中的任何模型。

开始使用Django评论框架 -

编辑项目settings.py文件并将'django.contrib.sites''django.contrib.comments'添加到INSTALLED_APPS选项 -

INSTALLED_APPS += ('django.contrib.sites', 'django.contrib.comments',)

获取网站ID -

>>> from django.contrib.sites.models import Site
>>> Site().save()
>>> Site.objects.all()[0].id
u'56194498e13823167dd43c64'

设置您在settings.py文件中获得的ID -

SITE_ID = u'56194498e13823167dd43c64'

同步数据库,以创建所有注释表或集合 -

python manage.py syncdb

将评论应用的网址添加到项目的urls.py中 -

from django.conf.urls import include
url(r'^comments/', include('django.contrib.comments.urls')),

现在我们已经安装了框架,让我们更改我们的hello模板来跟踪Dreamreal模型上的注释。 我们将列出,保存特定Dreamreal条目的注释,该条目的名称将作为参数传递给/ myapp/hello URL。

梦幻模型

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"

你好

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 %}

最后是我们的hello视图的映射URL -

url(r'^hello/(?P<Name>\w+)/', 'hello', name = 'hello'),

现在,

  • 在我们的模板(hello.html)中,使用 - {%load comments%}加载评论框架

  • 我们通过视图获取Dreamreal对象的注释数量 - {%get_comment_count for dreamreal as comment_count%}

  • 我们得到了对象的评论列表 - {%render_comment_list for dreamreal%}

  • 我们显示默认评论表单 - {%render_comment_form for dreamreal%}

访问/ myapp/hello/steve时,您将获得名为Steve的Dreamreal条目的评论信息。 访问该URL将获得 -

Django评论示例

发布评论后,您将被重定向到以下页面 -

评论重定向页面

如果再次访问/ myapp/hello/steve,您将看到以下页面 -

评论数量

如您所见,评论数量现在为1,您在评论列表下面有评论。

Django - RSS

Django附带了一个联合供稿生成框架。 有了它,您可以通过django.contrib.syndication.views.Feed class来创建RSS或Atom提要。

让我们为应用程序上的最新评论创建一个feed(另请参阅Django - Comments Framework章节)。 为此,让我们创建一个myapp/feeds.py并定义我们的feed(您可以将您的feed类放在代码结构中的任何位置)。

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})
  • 在我们的feed类中, titlelinkdescription属性对应于标准RSS 《title》《link》《description》元素。

  • items方法,返回应作为item元素放在feed中的元素。 在我们的案例中,最后五条评论。

  • item_title方法将获取我们的Feed项的标题。 在我们的例子中,标题将是用户名。

  • item_description方法将获得我们的Feed项目的描述。 在我们的案例中评论本身。

  • item_link方法将构建指向完整项目的链接。 在我们的案例中,它会让你发表评论。

现在我们有了feed,让我们在views.py中添加一个评论视图来显示我们的评论 -

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进行映射 -

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 /时,您将获得我们的Feed -

Django RSS示例

然后单击其中一个用户名将转到:/ myapp/comment/comment_id,如我们的评论视图中所定义,您将获得 -

Django RSS重定向页面

因此,定义RSS提要只是对Feed类进行子类化并确保定义URL(一个用于访问feed和一个用于访问feed元素)。 就像评论一样,这可以附加到您应用中的任何模型。

Django - Ajax

Ajax本质上是集成在一起的技术组合,以减少页面加载的数量。 我们通常使用Ajax来简化最终用户体验。 在Django中使用Ajax可以通过直接使用Ajax库(如JQuery或其他)来完成。 假设您想使用JQuery,那么您需要通过Apache或其他人下载并在您的服务器上提供库。 然后在模板中使用它,就像在开发任何基于Ajax的应用程序时一样。

在Django中使用Ajax的另一种方法是使用Django Ajax框架。 最常用的是django-dajax,它是一个功能强大的工具,可以使用Python和几乎没有JavaScript源代码轻松快速地在Web应用程序中开发异步表示逻辑。 它支持四种最流行的Ajax框架:Prototype,jQuery,Dojo和MooTools。

Using Django-dajax

首先要做的是安装django-dajax。 这可以使用easy_install或pip完成 -

$ pip install django_dajax
$ easy_install django_dajax

这将自动安装django-dajax所需的django-dajaxice。 然后我们需要配置dajax和dajaxice。

在INSTALLED_APPS选项中的项目settings.py中添加dajax和dajaxice -

INSTALLED_APPS += (
   'dajaxice',
   'dajax'
)

确保在相同的settings.py文件中,您有以下内容 -

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 statics js文件 -

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()

让我们使用Ajax创建一个基于Dreamreal模型的简单表单来存储它(意味着不刷新)。

首先,我们需要myapp/form.py中的Dreamreal表单。

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。 这就是我们的逻辑,那就是我们放置将保存表单的函数然后返回弹出窗口 -

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模板,它有我们的形式 -

<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中添加模板附带的视图 -

def dreamreal(request):
   form = DreamrealForm()
   return render(request, 'dreamreal.html', locals())

在myapp/urls.py中添加相应的网址 -

url(r'^dreamreal/', 'dreamreal', name = 'dreamreal'),

现在让我们在模板中添加必要的东西来使Ajax工作 -

在文件顶部添加 -

{% load static %}
{% load dajaxice_templatetags %}

在我们的dreamreal.html模板的部分添加 -

我们在这个例子中使用了JQuery库,所以添加 -

<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函数 -

<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静态文件,请运行 -

$python manage.py collectstatic

Note - 有时可能会丢失jquery.dajax.core.js,如果发生这种情况,只需下载源并获取该文件并将其放在静态文件夹下。

访问/ myapp/dreamreal /后,您将看到以下屏幕 -

使用Django-dajax

提交后,您将看到以下屏幕 -

使用Django-dajax响应
<上一篇.Django - AJAX
↑回到顶部↑
WIKI教程 @2018