编写你的第一个django应用程序2
从1停止的地方开始,我们将设置数据库,创建您的第一个模型,并快速介绍django自动生成的管理站点
数据库设置
现在,打开mysite/settings.py。这是一个普通的python模块,其中模块级变量代表django设置
默认情况下,配置使用sqlite。如果只是想尝试django,这是最简单的选择。sqlite包含在python中,因此你无需安装任何其他东西来支持你的数据库。但是,在启动第一个真正的项目时,您可能希望使用像PostgreSQL这样的更具伸缩性的数据库,以避免数据库切换问题
如果要使用其他数据库,请安装相应的数据库绑定并更改项中的以下键以匹配数据库连接设置
databases'default'
ENGINE
-要么'django.db.backends.sqlite3'
,'django.db.backends.postgresql'
,'django.db.backends.mysql'
,或'django.db.backends.oracle'
。其他后端也可用。NAME
- 数据库的名称。如果您使用的是SQLite,则数据库将是您计算机上的文件; 在这种情况下,NAME
应该是该文件的完整绝对路径,包括文件名。默认值,, 将文件存储在项目目录中。os.path.join(BASE_DIR,'db.sqlite3')
如果你不使用sqlite作为数据库,额外的设置,例如user,password和host必须加入
对于sqlite以外的数据库
如果您使用的是除sqlite之外的数据库,请确保此时已创建数据库。在数据库的交互式提示中使用‘’执行此操作。create database database_name;
还要确保提供的数据库用户mysite/settings.py具有‘create database’特权。这允许自动创建测试数据库,这将在以后的教程中使用
如果您使用的是sqlite,则无需事先创建任何内容-数据库文件将在需要时自动创建
在编辑时mysite/settings.py,请设置TIME_ZONE为您的时区
另外,请注意INSTALLED_APPS文件顶部的设置。它包含在这个django实例中激活的所有django应用程序的名称。应用程序可以在多个项目中使用,您可以打包和分发它们以供项目中的其他人使用
默认情况下,INSTALLED_APPS包含以下应用程序,所有这些应用程序都随django一起提供
django.contrib.admin管理站点,你很快就会用到它
django.contrib.auth认证系统
django.contrib.contenttypes内容类型的框架
django.contrib.sessions会话框架
django.contrib.messages消息传递框架
django.contrib.staticfiles用于管理静态文件的框架
默认情况下包含这些应用程序,以方便常见情况
其中一些应用程序至少使用了一个数据库表,因此我们需要在使用它们之前在数据库中创建表。为此,请运行以下命令
python manage.py migrate
该migrate命令查看INSTALLED_APPS设置并根据mysite/settings.py文件中的数据库设置和应用程序附带的数据库迁移创建任何必要的数据库表。您将看到适用于每次迁移的消息。如果您有兴趣,请运行数据库的命令行客户端并键入\dt(PostgreSQL),(MySQL),(SQLite)或(Oracle)以显示django创建的表
show tables;schemaSELECT TABLE_NAME FROM USER_TABLES;
对于极简主义者
就像我们上面所说的那样,默认应用程序包含在常见情况中,但不是每个人都需要它们。如果您不需要其中任何一个或全部,请INSTALLED_APPS在运行前随意注释或删除相应的行migrate。该migrate命令仅运行应用程序的迁移INSTALLED_APPS
创建模型
现在我们将定义您的模型-本质上是您的数据库布局,以及其他元数据
哲学
模型是关于数据的单一,明确的真实来源。它包含您要存储的数据的基本字段和行为。django遵循dry原则。目标是在一个地方定义您的数据模型,并自动从中获取数据
这包括迁移-与Ruby on Rails不同,例如,迁移完全来自您的模型文件,并且基本上只是django可以通过更新数据库模式以匹配您当前模型的历史记录
在我们简单的民意调查应用程序中,我们将创建两个模型:questio和choice。A question有问题和出版日期。A choice有两个字段:选择的文本和投票记录。每个choice都与一个question
这些概念由简单的python类表示,编辑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.CharFied(max_legth=200)
votes=models.IntegerField(default=0)
代码很简单,每个模型由一个子类表示django.db.models.Model。每个模型都有许多类变量,每个变量代表模型中的数据库字段
每个字段由Field类的实例表示,例如,CharField用于字符字段和DateTimeField日期时间。这告诉django每个字段包含哪种类型的数据
每个Field实例的名称(例如question_text或pub_date)是字段名称,采用机器友好格式。您将在python代码中使用此值,并且您的数据库将使用它作为列名
您可以使用可选的第一个位置参数Field来指定一个人类可读的名称。这在django的几个内省部分中使用,并且它兼做文档。如果未提供此字段,django将使用机器可读的名称。在这个例子中,我们只定义了一个人类可读的名称Question.pub_date。对于此模型中的所有其他字段,字段的机器可读名称就足以作为其可读的名称
有些Field类需要参数。CharField例如,要求你给它一个max_length。这不仅在数据库模式中使用,而且在验证中使用,我们很快就会看到
A Field也可以有各种可选参数,在这种情况下,我们将default值设置votes为0
最后,请注意使用的定义关系ForeignKey。这告诉django每个Choice都与单个相关Question。django支持所有常见的数据库关系:多对一,多对多和一对一
激活模型
这一小部分模型代码为django提供了大量信息。有了它,django能够:
为此应用程序创建数据库模式(语句)。create table
创建用于访问Question和choice对象的python数据库访问API
首先我们要告诉我们的项目polls应用程序已安装
哲学
django应用程序是可插拔的:您可以在多个项目中使用应用程序,并且可以分发应用程序,因为它们不必绑定到给定的django安装
要在我们的项目中包含应用程序,我们需要在设置中添加对其配置类的引用INSTALLED_APPS。该PollsConfig 是在polls/apps.py文件中,所以它的虚线路径‘polls.apps.Pollsconfig’。编辑mysite/settings.py文件并将该虚线路径添加到INSTALLED_APPS设置中
INSTALLED_APPS=[ 'polls.apps.PollsConfig' , 'django.contrib.admin' , 'django.contrib.auth' , 'django.contrib.contenttypes' , 'django.contrib.sessions' , 'django.contrib.messages' , 'django.contrib.staticfiles' , ]
现在django知道要包含该polls应用程序,让我们运行另一个命令
python manage.py makemigrations polls
看到类似以下内容
Migrations for 'polls': polls/migrations/0001_initial.py: - Create model Choice - Create model Question - Add field question to choice
通过运行makemigrations,您告诉django您已对模型进行了一些更改(在这种情况下,您已经创建了新模型),并且您希望将更改存储为迁移
迁移是django如何存储对模型(以及数据库模式)的更改-它们只是磁盘上的文件。如果您愿意,可以阅读新模型的迁移,这是文件polls/migrations/0001_initial.py
不要担心,每次django制作时都不会读它们,但是如果你想手动调整django如何改变它们,它们的设计是人为可编辑的
有一个命令可以为您运行迁移并自动管理您的数据库模式-这是被调用的migrate,我们马上就会看到它-但首先,让我们看看迁移将运行的SQL。该sqlmigrate命令获取迁移名称并返回其SQL
python manage.py sqlmigrate polls 0001
您应该看到类似于以下内容的东西(为了方便阅读,我们重新格式化了它)
BEGIN; -- -- Create model Choice -- CREATE TABLE "fuck_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL); -- -- Create model Question -- CREATE TABLE "fuck_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL, "pub_date" datetime NOT NULL); -- -- Add field question to choice -- ALTER TABLE "fuck_choice" RENAME TO "fuck_choice__old"; CREATE TABLE "fuck_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL, "question_id" integer NOT NULL REFERENCES "fuck_question" ( "id")); INSERT INTO "fuck_choice" ("id", "choice_text", "votes", "question_id") SELECT "id", "choice_text", "votes", NULL FROM "fuck_choice__old"; DROP TABLE "fuck_choice__old"; CREATE INDEX "fuck_choice_question_id_c65e29f8" ON "fuck_choice" ("question_id"); COMMIT;
确切的输出将根据您使用的数据库而有所不同
表名是通过组合应用程序的名称(自动生成polls)和模型的小写名字question和choice(您可以覆盖此行为)
主键(ID)会自动添加(你也可以覆盖它)
django附加‘_id’到外键字段名称(是的,你可以覆盖它)
外键关系通过约束显式化。不要担心零件,foreign keydeferrable
它是根据您正在使用的数据库量身定制的,因此可以自动为您处理特定于数据库的字段类型,如auto_increment(mysql)。引用字段名称也是如此-例如,使用双引号或单引号。integer primary key autoincrement
该sqlmigrate命令实际上并不在您的数据库上运行迁移,它只是将其打印到屏幕上,以便您可以看到sql django认为需要什么。它对于检查django将要执行的操作或者是否有需要sql脚本进行更改的数据库管理员非常有用
如果你有兴趣,你也可以跑,这将检查项目中的任何问题,而无需进行迁移或触摸数据库 python manage.py check
再次运行下面的命令在数据库创建这些模型表
python manage.py migrate
该migrate命令将执行所有尚未应用的迁移(django跟踪使用数据库中的特殊表来应用哪些迁移django_migrations)并针对您的数据库运行它们-实际上,您将对模型所做的更改与模型中的模式同步数据库
迁移功能非常强大,您可以在开发项目时随时更改模型,而无需删除数据库或表并创建新数据库-它专门用于实时升级数据库,而不会丢失数据。
模型更改的三步指南
更改模型
运行以创建这些更改的迁移python manage.py makemigrations
运行以将这些更改应用于数据库python manage.py migrate
之所以有单独的命令来制作和应用迁移是因为您将提交迁移到您的版本控制系统并将其与您的应用程序一起发送,它们不仅使您的开发更容易,而且还可以被其他开发人员和生产中使用
现在,让我们进入交互式python shell并使用django为您提供的免费API。使用以下命令
python manage.py shell
我们使用它而不是简单地输入‘python’,因为manage.py设置了django_settings_module环境变量,这为django提供了mysite/settings.py文件的python导入路径
绕过manage.py
如果你不想使用manage.py,没问题。只需设置django_settings_module环境变量to mysite.settings,启动一个普通的python shell,并设置django
import django django.setup()
如果这引发了AttributeError,你可能正在使用与本教程版本不匹配的django版本。您将要切换到较旧的教程或较新的django版本
您必须python从同一目录运行manage.py,或确保该目录位于python路径上,这样才有效。import mysite
进入shell后,浏览数据库API
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 q.question_text q.pub_date q.question_text="what's up" q.save() Question.objects.all()
完全是对这个对象的无益表现。让我们来解决这个问题通过编辑模型(在文件),并加入到两个方法和:
<Question: Question object>
Question
polls/models.py
__str__()
Question
Choice
from django.db import models from django.utils.encoding import python_2_unicode_compatible @python_2_unicode_compatible class Question(models.Model): def __str__(self): return self.question_text @python_2_unicode_compatible def __str__(self): return self.choice_text
__str__()向模型添加方法非常重要,不仅是为了您在处理交互式提示时的方便,还因为在django自动生成的管理中使用了对象的表示
这些是普通的python方法。让我们添加一个自定义方法
import datetime from django.db import models from django.utils import timezone class Question(models.Model): def was_published_recently(self): return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
请注意添加和分别引用python的标准模块和django的时区相关实用程序。如果您不熟悉python中的时区处理,可以在时区支持文档中了解更多信息
保存这些更改并通过再次运行启动新的python交互式shell:python manage.py shell
from polls.models import Question,Choice Question.objects.all() Question.objects.filter(id=1) Question.objects.filter(question_text__startswith='what') from django.utils import timezone current_year=timezone.now().year Question.objects.get(pub_date__year=current_year) Question.objects.get(id=2) Question.objects.get(pk=1) q=Question.objects.get(pk=1) q.was_published_recently() q=Question.objects.get(pk=1) q.choice_set.all() q.choice_set.create(choice_text='not much',vote=0) q.choice_set.create(choice_text='The sky',vote=0) c=q.choice_set.create(choice_text='just hacking again',vote=0) c.question q.choice_set.all() q.choice_set.count() Choice.objects.filter(question__pub_date__year=current_year) c=q.choice_set.filter(choice_text__startswith='just hacking') c.delete()
介绍django管理员
哲学
为您的员工或客户生成管理网站以添加,更改和删除内容是繁琐的工作,不需要太多的创造力,出于这个原因,django完全自动化为模型创建管理界面
django是在新闻编辑室环境中编写的,‘内容发布者’和‘公共’网站之间有明显的分离。站点管理员使用该系统添加新闻报道,事件,体育比分等,并且该内容显示在公共站点上。django解决了为站点管理员创建统一界面以编辑内容的问题。
管理员不打算由网站访问者使用,它适用于网站管理员
创建管理员用户
首先,我们需要创建一个可以登录管理站点的用户,运行以下命令
python manage.py createsuperuser
输入所需的用户名,然后按enter键
Username:admin
然后,系统将提示您输入所需的电子邮件地址
admin@example.com
最后一步是输入密码。系统会要求您输入两次密码,第二次输入密码作为第一次确认
superuser created successfully
启动开发服务器
django管理站点默认激活,让我们启动开发服务器并进行探索
如果服务器没有运行,请启动它
python manage.py runserver
现在,打开web浏览器并转到本地域的‘/admin/’-例如http://127.0.0.1:8000/admin/。您应该看到管理员的登录屏幕
进入管理站点
尝试使用您在上一步中创建的超级用户账户登录,你应该看到django管理员的索引界面
您应该看到几种类型的可编辑内容:组和用户。django.contrib.auth由django提供的身份验证框架提供
在管理员中修改民意调查应用程序
我们需要告诉管理员Question对象有一个管理界面。为此,请打开该polls/admin.py文件,然后如下
from django.contrib import admin from .models import Question admin.site.register(Question)
探索免费的管理功能
现在我们已经注册了Question,django知道它应该显示在管理员索引界面上
单击‘问题’,您将进入‘更改列表’页面以查询问题。此页面显示数据库中的所有问题,您可以选择一个更改它。我们之前创建了‘什么事’这个问题
点击‘怎么了’问题进行编辑
这里要注意的事项:
表单是从Question模型自动生成的
不同的模型字段类型(datetimefield,charfield)对应于相应的HTML输入窗口小部件。每种类型的字段都知道如何在django管理员中显示自己
每个都datetimefield获得免费的javascript快捷方式。日期获得‘今日’快捷方式和日历弹出窗口,时间获得‘现在’快捷方式和方便的弹出窗口,列出常用的输入时间
页面底部为您提供了几个选项:
保存-保存更改并返回此类对象的更改列表页面
保存并继续编辑-保存更改并重新加载此对象的管理页面
保存并添加另一个-保存更改并为此类对象加载新的空白表单
删除-显示删除确认页面
如果‘发布日期’的值与您在创建问题的时间不匹配,则可能意味着您忘记为该time_zone设置正确的值。更改它,重新加载页面并检查是否显示正确的值
单击‘今天’和‘立即’快捷方式更改‘发布日期’,然后单击‘保存并继续编辑’。然后单击右上角的‘历史记录’。您将看到一个页面,其中列出了通过django管理员对此对象所做的所有更改,以及进行更改的人员的时间戳和用户名
如果您对模型API感到满意并熟悉管理网站,请阅读本教程的第3部分,了解如何向民意调查应用添加更多视图。
https://docs.djangoproject.com/en/1.11/intro/tutorial02/