writing_first_django_app_part1
Creating a project
查看django版本:
$ python -c "import django; print(django.get_version())"
创建工程,进入需要放置工程的目录:
$ django-admin.py startproject mysite
会创建以下文件:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
manage.py用来与工程进行命令行交互 settings.py里面是项目的配置 urls.py是项目的一些URL声明 wsgi.py是wsgi网站服务器支持工程的入口
默认使用SQLite数据库
INSTALLED_APPS: 在settings.py中,默认有以下几个可以使用:
- django.contrib.admin: 管理者站点
- django.contrib.auth: authentication system
- django.contrib.contenttypes
- django.contrib.sessions
- django.contrib.messages
- django.contrib.staticfiles
因为一些应用使用了至少一个数据库表格,所以我们需要在使用之前在数据库创建这些表格,运行:
$ python manage.py migrate
这个命令查看INSTALLED_APPS中激活的应用,然后根据settings.py文件来创建需要的数据库.可以通过命令查看已经创建的表格,如SQLite中.schema可以查看 具体可以在数据库文件的目录下先通过终端打开数据库命令行交互界面:
$ sqlite3 db.sqlite3
然后在交互界面中输入.schema即可查看 ad 接下来就可以尝试运行服务器了:
$ python manage.py runserver
# python manage.py runserver 0.0.0.0:8080 可以指定ip,端口
一般情况下修改代码之后不需要重新运行server,我们发出请求时修改的代码会自动生效,除非是增加文件等操作才需要重启服务器
Creating models 创建一个app:
python manage.py startapp polls
修改polls/models.py:
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
每个变量值都属于一个Field类,ForeignKey表示一种多对一的关系,django支持数据库常用的几种关系:多对一,多对多,一对一.
Activating models
有了上面model的代码之后可以给django提供很多信息,可以为这个app创建数据库表格,创建python的数据库接口给Question和Choice,不过首先要告诉工程polls这个app 在settings.py中的INSTALLED_APPS中添加一项'polls',然后命令行:
$ python manage.py makemigrations polls
migrations是django用来记录models的改变的文件
还有一种可以查看数据库需要改变的地方:
$ python manage.py sqlmigrate polls 0001
这里并不是真正执行migrate,只是输出django认为需要的SQL语句,可以用来预先检查
还有一种检查方式:
$ python manage.py check
会告诉我们有多少个问题
现在可以真正执行migrate操作去创建model表格在数据库中:
$ python manage.py migrate
migrate这种机制对于我们开发是非常有用的,我们在开发中有新的内容不再需要删除掉数据库而重新创建一个,可以直接用migrate来更新数据库.
现在总结导致model发生改变的三个步骤:
- models的修改(models.py)
- 运行
makemigrations
创建这些改变的migrations - 运行
migrate
应用这些改变
Playing with the API
$ python manage.py shell
进入命令行界面后:
>>> from polls.models import Question, Choice
>>> Question.objects.all()
[]
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
>>> q.save()
>>> q.id
1
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
>>> q.question_text = "What's up?"
>>> q.save()
>>> Question.objects.all()
[<Question: Question object>]
最后显示object.all()的时候仅仅是对象的简单描述,不方便查看,这里可以重写polls/models.py中Question的 __str__()函数(在python2中是__unicode__())
class Question(models.Model):
...
def __str__(self):
return self.question_text
class Choice(models.Model):
# ...
def __str__(self): # __unicode__
增加一个查看是否是最近发布的函数:
class Question(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
再次使用命令行交互:
>>> from polls.models import Question, Choice
>>> Question.objects.all()
[<Question: What's up?>]
>>> Question.objects.filter(id=1)
[<Question: What's up?>]
>>> Question.objects.filter(question_text__startswith='What')
[<Question: What's up?>]
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>
>>> Question.objects.get(pk=1)
<Question: What's up?>
# Make sure our custom method worked.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True
# Create three choices.
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)
>>> c.question
<Question: What's up?>
# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
>>> q.choice_set.count()
3
>>> Choice.objects.filter(question__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 = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()