由于Django在一个快节奏的新闻工作室环境中开发,使得他被设计成让通用的Web开发任务快速而简单。这边先给出一个非正式的概览来展示如何用Django开发一个数据库驱动的Web应用。
这篇文档的目的是给你充分的技术细节来理解Django是怎么工作的,但是这并不是一份教程或者参考手册 - 但是这两个我们都有! 当你准备好开启一个项目的时候,有可以从我们的教程入手或者直接深入我们具体的文档。
尽管你可以在Django中不适用数据库, 但是Django自带了一个对象-关系映射器(ORM Object-relational mapping)用来用Python的代码描述数据库的表结构。
数据模型的语法提供了丰富的方法来描述你的模型 - 到目前位置, 这种方式正在解决多年来数据库模式的问题。这边是个简单例子:
mysite/news/models.py
from djanog.db import models
class Reporter(models.Model):
full_name = models.CharField(max_length=70)
def __str__(self): # __unicode__ on Python 2
return self.full_name
class Article(modes.Model):
pub_date = models.DateField()
headline = models.CharField(max_length=200)
content = models.TextField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
def __str__(self): # __unicode__ on Python 2
return self.headline
接着运行Django的命令行安装程序来自动创建数据库表格:
$ python manage.py migrate
migrate这个命令会自动的查找你现有代码里面的有效模型类, 然后创建那些还不存在的表格, 并且提供了可选的更丰富的模式控制。
有了他们, 你将获得自由和丰富的Python API来访问你的数据。这些API会自动获得,而不需要任何的代码生成:
# Import the models we created from our "news" app
>>> from news.models import Reporter, Article
# No reporters are in the system yet.
>>> Reporters.objects.all()
# Create a new Reporter.
>>> r = Reporter(full_name='John Smith')
# Save the object into the database. You have to call save() explicitly.
>>> r.save()
# Not it has an ID.
>>> r.id
1
# Now the new reporter is in the database.
>>> Reporter.objects.all()
]>
# Fields are represented as attributes on the Python object.
>>> r.full_name
'John Smith'
# Django provides a rich database lookup API.
>>> Reporter.objects.get(id=1)
>>> Reporter.objects.get(full_name__startswith='John')
>>> Reporter.objects.get(full_name__contains='mith')
>>> Reporter.objects.get(id=2):
Traceback (most recent call last):
...
DoesNotExist: Reporter matching query does not exist.
# Create an article.
>>> from datetime import date
>>> a = Article(pub_date=date.today(), headline='Django is cool', content='Yeah.', reporter=r)
>>> a.save()
# Now the article is in the database.
>>> Article.objects.all()
]>
# Article objects get API access to related Reporter objects.
>>> r = a.reporter
>>> r.full_name
'John Smith'
# And vice versa: Reporter objects get API access to Article objects.
>>> r.article_set.all()
]>
# 这边API通过你需要的关系,使用有效的JOIN语句来完成你需要的数据访问
# 下面这个会找到reporter名字以"John"开头人的所有article
>>> Article.objects.filter(reporter__full_name__startswith='John')
]>
# 修改对象的值,然后调用save()来保存
>>> r.full_name = 'Billy Goat'
>>> r.save()
# 使用delete()来删除数据
>>> r.delete()
一旦你的模型定义完成, Django就可以自动创建专业的,生产环境可以的管理接口 - 一个是的认证用户可以增加,修改和删除数据的网站。你可以很容易注册你的模型到管理网站上。
mysite/news/models.py
from django.db import models
class Article(models.Model):
pub_date = models.DateField()
headline = models.CharField(max_length=200)
content = models.TextField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
mysite/news/admin.py
from django.contrib import admin
from . import models
admin.site.register(models.Article)
这边的原则是你的网站可能是你的员工,客户或者只是你来就修改维护内容 - 而你又不想处理这些后来维护内容的工作。
一个典型的创建Django应用的开发流程是创建模型并且使得管理网站尽快上线运行,你的员工或者客户就可以往里面塞数据了。然后开发人员就开发展示数据的方式。
一个简单优雅的URL和一个高质量的网站内容同样重要。Django鼓励使用漂亮的URL设计,而不是放入那些令人讨厌的后缀到URL里面去,比如.php和.asp。
要给应用设计URL, 你需要创建一个叫URLconf的模块。你的应用的目录结构,包含了一个从URL样式到Python回调函数的映射。URLconfs就是用来将Python代码和URL解耦的。
这边是一个用于上面的Reporter/Article的URL例子:
mysite/news/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^aritcles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article-detail),
]
上面代码使用了简单的正则表达式来映射地址到Python的回调函数(”试图“)。正则表达式使用小括号来抓取URL里面的参数。当用户请求页面的时候, Django就会按顺序比较这些正则表达式, 当他发现匹配的URL就会停止查找。(如果没有任何匹配, Django就会调用一个特殊的404视图。)这个过程会很快,应该Django会在启动时候就对正则表达式进行编译。
一旦一个正则表达式匹配上了, Django就会引入和调用指定的试图, 其实就是一个Python的函数。每个试图会得到一个传入的request对象 - 包含了请求的元数据 - 以及从正则表达式中抓取的参数。
比如, 如果用户请求的URL是”/articles/2005/05/39323/”, Django就会调用函数news.vies.article_detail(request, ‘2005’, ‘05’, ‘39323’)。
每个视图都负责做两件事中的一个:返回一个HttpResponse对象,包含被请求页面的内容,或者抛出一个比如Http404的异常。剩下的就全部取决于你。
通常来说, 一个视图会更根据传入的参数来获取数据, 然后调用一个模板,用已有的数据来渲染模板。这边有个用于上面year_archive的视图:
mysite/news/views.py
from django.shortcuts import render
from .models import Article
def year_archive(request, year):
a_list = Article.objects.filter(pub_date__year=year)
context = {'year': year, 'article_list': a_list}
return render(request, 'news/year_archive.html', context)
这个例子使用了Django的模板系统,带有强大的功能,并且努力使他足够简单以适用于非编码人员。
上面的例子会调用news/year_archive.html模板。
Django默认有个模板搜索路径, 是的你尽量减少重复的模板。在Django设置中, 有需要制定一个目录列表来用于查找模板。如果模板不存在与第一个目录, 那么他就会查找第二个,然后第三,第四……
比如说news/year_archive.html模板被找到了。下面将会是他看上去的样子:
mysite/news/templates/news/year_archive.html
{% extends "base.html" %}
{% block title %}Articles for {{ year }}{% endblock %}
{% block content %}
Articles for {{ year }}
{% for article in article_list %}
{{ article.headline }}
By {{ article.reporter.full_name }}
Published {{ article.pub_date|date:"F j, Y" }}
{% endfor %}
{% endblock %}
双大括号里面的变量 {{ article.headline }}表示用这个article.headline的值作为输出跳入大括号所在的位置。这边的原点不但可以用于Python里面的属性查找,也可以用于Python里面字典key的查找,index查找和函数调用。
请注意{{ article.pub_date|date:”F j, Y” }}使用了类似于Unix里面的管道(”|“字符)。这个叫做模板过滤器, 用于过滤一个变量的值。在这个例子里面, 日期过滤器用来将一个Python datetime对象用给定的格式输出(就好像PHP里面的date函数)。
你可以把任意个过滤器级联起来。你也可以自己定制模板过滤器。你还可以自己编写自定义的模板标签,可以使用自己的Python代码来实现。
最后, Django使用了模板继承的概念。就是这里的{% extends “base.html” %}。base.html定义了一堆模块, 在这里就会先导入这些模块, 然后再接下俩的模块里面就能使用这些模块。简单的说, 你可以使用这种方法大量减少冗余的代码: 每个模板只要定义它和其他模板不同的地方。
以下是”base.html”模板, 包括使用静态文件:
mysite/templates/base.html
{% load static %}
{% block title %}{% endblock %}
{% block content %}{% endblock %}
很简单,这边只是定义网站的框子(带有网站的Logo), 并且提供了子模版可以填入的空。这就是的网站的重新设计可以很简单,只要修改一个基本模板就可以了。
同时也可以让你创建网站的多个版本, 只要使用不同的基本模板, 并重用相同的子模板。Django的创建者使用这个技术创建了多个用于移动端的网站版本 - 其实就是简单的替换基本模板。
这边要提到的是如果你喜欢其他模板系统的话,你可以不适用Django提供的模板系统。尽管Django的模板系统和Django的模型层集成的很好, 但没有强制你使用这套模板系统。说到这点, 你同样不需要使用Django的数据库API。 又可以使用其他的数据库抽象层, 你可以使用XML文件, 你也可以直接读取文件或者使用其他方式。Django的每个部件 - 模型, 视图, 模板 - 都是互相解耦的。
这只是Django功能的一个快速概览。 下面是更多的一些有用功能:
下一步你需要下载Django, 阅读手册和加入社区。 谢谢。