[part 2] 第一个 Django 应用
内容
- 配置数据库,模型创建,表结构迁移
- 生成后台站点,管理帐号创建,界面预览,汉化时区配置
数据
mysite/settings.py
Django
配置文件,默认使用python
内置的SQLite
- 数据库配置
DATABASES 'default'
配置数据库连接ENGINE
数据库引擎'django.db.backends.sqlite3', 'django.db.backends.postgresql'
'django.db.backends.mysql', or 'django.db.backends.oracle'
非sqlite数据库,在创建表之前,通常需要先创建配置的数据库,其他配置项诸如时区视情况而定
INSTALLED_APPS
配置django.contrib
空间下的admin,auth,contenttypes,sessions,messages,staticfiles
,认证,类型,session,消息及管理静态文件的框架或系统由Djiang
提供
建表
- 创建表 生成
apps
默认表python manage.py migrate
创建模型
- 添加一些元数据,调整数据库字段布局。模型包含一些必要字段和基于模型数据的方法
- Django通过回滚或修改数据表结构,达到匹配当前模型
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, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
- 每个模型都是
django.db.models.Model
的子类,其内定义了若干类变量,代表数据库中相应字段 - 每个字段都是
Field
类的实例, 每一个字段实例名(如question_text
)都是数据库的表结构列名 - 字段类的初始化第一个可选参数如('date published'), 对人友好可读性,通常被作文档,在
Django
中作内省值 - 外键则指示了关联关系,框架支持 一对一,一对多,多对多关联
激活模型
- 增加项目配置
INSTALLED_APPS
PollsConfig
是在polls/apps.py
文件中, 对应命名空间polls.apps.PollsConfig
INSTALLED_APPS = [
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
makemigrations
执行迁移,生成自定义模型表sqlmigrate
命令获取迁移名称并返回其SQL
python manage.py makemigrations polls
python manage.py sqlmigrate polls 0001
-
注意事项
- 表名是组合应用程序名称(自动生成polls)和模型的小写名字
question
和choice
- 外键关系通过 约束显式化
- 具体的数据类型,自动处理特定于数据库的字段类型
- 该
sqlmigrate
命令实际上并不在数据库上运行迁移 - 它只是将其打印到屏幕上
- 表名是组合应用程序名称(自动生成polls)和模型的小写名字
-
执行迁移
python manage.py migrate
-
修改流程
- 更改模型(
in models.py
) - 运行以创建这些更改的迁移
python manage.py makemigrations
- 运行以将这些更改应用于数据库
python manage.py migrate
- 更改模型(
简述 定义数据模型 --> 创建迁移文件 --> 执行迁移入库
使用Shell
- 命令
python manage.py shell
进入django shell
,与数据库交互
In [1]: from polls.models import Choice, Question
In [2]: Question.objects.all()
Out[2]: <QuerySet []>
In [3]: from django.utils import timezone
In [4]: q = Question(question_text="What's new?", pub_date=timezone.now())
In [5]: q.save()
In [6]: q.id
Out[6]: 1
In [7]: q.question_text
Out[7]: "What's new?"
In [8]: q.pub_date
Out[8]: datetime.datetime(2019, 7, 12, 8, 38, 18, 439683, tzinfo=<UTC>)
In [9]: q.question_text = "What's up?"
In [10]: q.save()
In [11]: Question.objects.all()
Out[11]: <QuerySet [<Question: Question object (1)>]>
In [12]: exit
<Question: Question object (1)>
默认输出不直观,重写__str__
方法修复此问题
polls/models.py
from django.db import models
class Question(models.Model):
# ...
def __str__(self):
return self.question_text
class Choice(models.Model):
# ...
def __str__(self):
return self.choice_text
- 再次运行
python manage.py shell
,对模型的增改查
In [1]: from polls.models import Choice, Question
In [2]: Question.objects.all()
Out[2]: <QuerySet [<Question: What's up?>]>
In [3]: Question.objects.filter(id=1)
Out[3]: <QuerySet [<Question: What's up?>]>
In [4]: Question.objects.filter(question_text__startswith='What')
Out[4]: <QuerySet [<Question: What's up?>]>
In [5]: from django.utils import timezone
In [6]: current_year = timezone.now().year
In [7]: Question.objects.get(pub_date__year=current_year)
Out[7]: <Question: What's up?>
In [8]: Question.objects.get(id=2)
DoesNotExist: Question matching query does not exist.
In [9]: Question.objects.get(pk=1)
Out[9]: <Question: What's up?>
In [10]: q = Question.objects.get(pk=1)
In [11]: q.was_published_recently()
Out[11]: True
In [12]: q = Question.objects.get(pk=1)
In [13]: q.choice_set.all()
Out[13]: <QuerySet []>
In [14]: q.choice_set.create(choice_text='Not much', votes=0)
Out[14]: <Choice: Not much>
In [15]: q.choice_set.create(choice_text='The sky', votes=0)
Out[15]: <Choice: The sky>
In [16]: c = q.choice_set.create(choice_text='Just hacking again', votes=0)
In [17]: c.question
Out[17]: <Question: What's up?>
In [18]: q.choice_set.all()
Out[18]: <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
In [19]: q.choice_set.count()
Out[19]: 3
In [20]: Choice.objects.filter(question__pub_date__year=current_year)
Out[20]: <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
In [21]: c = q.choice_set.filter(choice_text__startswith='Just hacking')
In [22]: c.delete()
Out[22]: (1, {'polls.Choice': 1})
后台 Admin
- 创建后台用户
py manage.py createsuperuser
Username (leave blank to use 'administrator'): admin
Email address: admin@pardon110.com
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
- 修改项目目录
mysite
下的settings
配置,汉化及时区
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
- 启动后台服务
py manage.py runserver
- 访问http://localhost:8000/admin/
, 用上述创建的帐号密码登录 - 将
poll
应用模型注册到后台
# polls/admin.py
from django.contrib import admin
from .models import Question
admin.site.register(Question)
- 刷新页面,点击“Questions” --> "What’s up?" 可看到如下页面
源码
本作品采用《CC 协议》,转载必须注明作者和本文链接