Writing your first Django app, part 1
这个tutorial主要是创建一个基本的投票程序,主要由2部分组成:
1、可以让人们查看票数和投票的一个公共页面
2、可以添加、修改、删除投票的管理页面
首先测试下是否已经安装好django,可以通过下面的命令看到结果:
这篇tutorial主要是用Django1.5和Python2.x。
(一)创建一个项目
我们可以自动的生成一个Django的项目,里面包含了一些代码,包括数据库配置信息、Django说明选项、应用的配置等。首先在命令行进入某个目录,然后输入下面的命令:
这将会在当前目录下创建一个叫做mysite的文件夹(tips:项目的名字要避免与Python或者Django内置的名字冲突)
让我们看看startproject创建的项目mysite的目录结构:
包括:
外部的mysite文件夹:包含所有项目文件的根目录
manage.py:一个可以让你通过多种方式与Django项目进行交互的命令行工具
内部的mysite文件夹:你项目实际的Python包所在地
mysite/__init__.py:一个空的文件,告诉Python这个目录应该被当作一个Python 包看待
mysite/settings.py:Django项目的Settings/Configuration信息
mysite/urls.py:Django项目的url声明
mysite/wsgi.py:一个访问WSGI的web服务器的进入点
然后我们可以运行下这个程序,进入mysite目录里,运行下面的命令:
可以看到我们已经启动了一个服务器,一个轻量级的完全由Python编写的,但是不要在实际的运行环境中使用这个服务器,它只是用来开发的服务器。
然后可以打开浏览器,输入http://127.0.0.1:8000/
就会看到一个“It worked!”的页面
改变端口:
默认为8000端口,如果要改变端口,输入以下命令:
python manage.py runserver 8080
端口就会变成8080
数据库的设置
现在需要编辑mysite/settings.py文件,改变DATABASES里面的以下元素,来配置你的数据库设置:
其中:
ENGINE:是'django.db.backends.postgresql_psycopg2', 'django.db.backends.mysql', 'django.db.backends.sqlite3' or'django.db.backends.oracle'.
USER:数据库用户名
PASSWORD:数据库密码
我使用的是mysql数据库,我的配置见下图:
Name对应的是mysql数据库里的一个名为django_db2的数据库,USER和PASSWORD分别为这个数据库的用户名和密码。
同时,在settings.py文件最后的一页有INSTALLED_APP属性,里面包含了在这个Django项目中所有的Django Application的名字。一个App可以用在多个项目中(我的理解,这个app相当于一个模块,譬如日志模块、权限模块),默认的Django包含以下几个模块:
每个app至少对应于数据库的一张表,所以我们需要在数据库里创建表才能使用他们,首先我们先要在mysql创建一个叫做django_db2的数据库():
运行下面的命令:
就会在mysql数据库里创建在INSTALLED_APPS声明的很多表,并且需要用户在权限模块定义一个超级用户。
你可以登录进入mysql数据库,看到里面新创建了很多表
(二)创建模型
每个用Django编写的应用都是由一个Python Package组成,Django可以自动的生成应用的基本目录结构,程序员就可以专心于代码的编写而不是创建目录了。
在这个例子中,我们要创建一个poll的app,它在manage.py的同一级
首先确认你在manage.py文件的同一级,然后输入以下的命令:
系统会创建一个polls目录,结构如下所示:
在我们的polls应用中,我们会创建2个模型:Poll和Choice。Poll有一个question和一个publication date属性。Choice有2个属性:the text of the choice和a vote tally。每个Choice关联到一个Poll。
编辑polls/models.py文件,如下所示:
(三)激活模型
通过上面创建的模型文件,Django可以做到:
1、为这个app创建数据库的表
2、为访问这些模型提供python 的api
但是首先我们需要告诉我们的项目,polls的应用已经被安装。。。
编辑settings.py文件,修改INSTALLED_APP,添加polls,如下所示:
现在Django项目包含了polls应用,现在运行如下命令:
python manage.py sql polls
会看到如下输出:
这些是即将运行在数据库中的sql语句,会在数据库中创建表。
现在运行syncdb,在数据库中创建这些模型:
(四)访问api
现在我们可以通过python shell访问这些模型,运行
python manage.py shell
然后运行以下命令,可以看到相应的输出:
可以看到,当最后输入objects.all(),返回的信息没有指明详细的对象,现在我们修改下模型的定义,对Poll和Choice添加一个__unicode__()方法:
以上都是python内置的方法,下面我们加入一个用户定义的方法,用来演示:
我们在Poll类中定义了一个新的检查某个Poll是不是最近发布的方法。保存后运行下面的命令:
>>> from polls.models import Poll, Choice # Make sure our __unicode__() addition worked. >>> Poll.objects.all() [<Poll: What's up?>] # Django provides a rich database lookup API that's entirely driven by # keyword arguments. >>> Poll.objects.filter(id=1) [<Poll: What's up?>] >>> Poll.objects.filter(question__startswith='What') [<Poll: What's up?>] # Get the poll that was published this year. >>> from django.utils import timezone >>> current_year = timezone.now().year >>> Poll.objects.get(pub_date__year=current_year) <Poll: What's up?> # Request an ID that doesn't exist, this will raise an exception. >>> Poll.objects.get(id=2) Traceback (most recent call last): ... DoesNotExist: Poll matching query does not exist. Lookup parameters were {'id': 2} # Lookup by a primary key is the most common case, so Django provides a # shortcut for primary-key exact lookups. # The following is identical to Poll.objects.get(id=1). >>> Poll.objects.get(pk=1) <Poll: What's up?> # Make sure our custom method worked. >>> p = Poll.objects.get(pk=1) >>> p.was_published_recently() True # Give the Poll a couple of Choices. The create call constructs a new # Choice object, does the INSERT statement, adds the choice to the set # of available choices and returns the new Choice object. Django creates # a set to hold the "other side" of a ForeignKey relation # (e.g. a poll's choices) which can be accessed via the API. >>> p = Poll.objects.get(pk=1) # Display any choices from the related object set -- none so far. >>> p.choice_set.all() [] # Create three choices. >>> p.choice_set.create(choice_text='Not much', votes=0) <Choice: Not much> >>> p.choice_set.create(choice_text='The sky', votes=0) <Choice: The sky> >>> c = p.choice_set.create(choice_text='Just hacking again', votes=0) # Choice objects have API access to their related Poll objects. >>> c.poll <Poll: What's up?> # And vice versa: Poll objects get access to Choice objects. >>> p.choice_set.all() [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>] >>> p.choice_set.count() 3 # The API automatically follows relationships as far as you need. # Use double underscores to separate relationships. # This works as many levels deep as you want; there's no limit. # Find all Choices for any poll whose pub_date is in this year # (reusing the 'current_year' variable we created above). >>> Choice.objects.filter(poll__pub_date__year=current_year) [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>] # Let's delete one of the choices. Use delete() for that. >>> c = p.choice_set.filter(choice_text__startswith='Just hacking') >>> c.delete()