前言
从上篇文章开始给大家介绍Django的入门,一套用于帮助开发交互式网站的工具。Django能够响应网站请求,还能让你更轻松地读写数据库、管理用户等。主要包括制定规范、建立虚拟环境、安装virtualenv、激活虚拟环境、安装Django以及在Django中创建项目、创建数据库以及最后查看项目。本文给大家介绍创建应用程序的相关内容。
创建应用程序
Django项目是由一系列应用程序组成,它们协同工作,让项目成为一个整体。我们暂时只创建一个应用程序,它将完成项目的大部分工作。
当前,在前面打开的终端窗口中应该还运行着runserver
。请再打开一个终端窗口(或标签页),并切换到manage.py
所在目录。激活该虚拟环境,在执行命令startapp
,具体执行情况如下:
source ll_env/bin/activate
python manage.py startapp learning_logs
dir
dir learning_logs/
具体执行的结果如下:
命令startapp.appname
让Django建立创建应用程序所需的基础设施。如果现在查看项目目录,将看到其中新增一个文件夹learning_logs
。打开这个文件夹,看看Django都创建了什么。具体内容如下:
其中最重要的文件是models.py
、admin.py
和views.py
。我们将使用models.py
来定义我们要在应用程序中管理的数据。其中的admin.py
和views.py
将在稍后介绍。
一、定义模型
我们来想想涉及的数据。每位用户都需要在学习笔记中创建很多主题。用户输入的每个条目都与特定主题相关联,这些条目将以文本的方式显示。我们还需要存储每个条目的时间戳,以便能够告诉用户各个条目都是什么时候创建的。
我们打开文件models.py
,看看它当前包含哪些内容:
from django.db import models
# 在这里创建模型
这为我们导入了模块models,还让我们创建自己的模型。模型告诉Django如何处理应用程序中存储的数据。在代码
层面,模型就是一个类,就像前面讨论的每个类一样,包含属性和方法。下面是表示用户将要存储的主题模型:
class Topic(models.Model):
"""用户学习的主题"""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
"""返回模型的字符串表示"""
return self.text
我们创建了一个名为Topic
的类,它继承了Model
——Django中一个定义了模型基本功能的类。Topic类只有两个属性:text
和data_added
。属性text
是一个CharField
——由于字符和文本组成的数据。需要存储少量的文本,如名称、标题或城市时,可使用CharField
。定义CharField
属性时,必须告诉Django该在数据库中预留多少空间。在这里,我们将max_length
设置成了200(即200个字符),对这存储大多数主题的名来说足够了。
属性date_added
是一个DateTimeField
——记录日期和时间的数据。我们传递了实参——auto_now_add=True
,每当用户创建新主题时,这都让Django将这个属性自动设置成当前日期和时间。
我们需要告诉Django,默认应使用哪个属性来显示有关主题的信息。Django调用方法__str()__
来显示模型的简单表示。在这里,我们呢编写了方法__str__()
,它返回存储在属性text中的字符串。
二、激活模型
要使用模型,必须让Django将应用程序包含到项目中。为此,打开settings.py
(它位于目录learning_log/learning_log
中),我们将看到一个这样的片段,即告诉Django哪些应用程序安装在项目中,具体setting的位置如下图所示:
具体settings.py
中的内容如下:
"""
Django settings for learning_log project.
Generated by 'django-admin startproject' using Django 1.11.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'klx8i)7p@fa&jc=(wtc^0l^08p*jfuygqg_+d58h%#4k+e$juh'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'learning_log.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'learning_log.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL = '/static/'
这是一个数组,告诉Django项目是由哪些应用程序组成的。请将INSTALLED_APPS
修改成下面这样,将前面的应用程序添加到这个元组中:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 添加我们自己的应用
'learning_logs',
]
具体的书写位置如下图所示:
通过将应用程序编组,在项目不断增大,包含更多的应用程序时,有助于对应用程序进行跟踪。这里新建了一个名为My apps
的片段,当前它只包含应用程序learning_logs
。接下来,需要让Django
修改数据库,使其能够存储与模型topic相关信息。为此,在终端窗口中执行下面的命令:
python manage.py makemigrations learning_logs
命令makemigrations
让Django确定该如何修改数据库,使其能够存储与我们定义的新模型相关联的数据。输出表明Django创建了一个名为0001_initial.py
的迁移文件,这个文件将在数据库中为模型topic创建一个表。具体如下:
下面来应用迁移,让Django替我们修改数据库:
python manage.py migrate
这个命令的大部分输出都与我们首次执行命令migrate
的输出相同。我们需要检查的是相应的输出行,在这里,Django确认为learning_logs
应用迁移时一切OK。具体运行情况如下:
每当需要修改“学习笔记”管理的数据时,都采取如下三步骤:修改models.py
;对learning_logs
调用makemigrations
;让Django迁移项目。
三、Django管理网站
为应用程序定义模型时,Django提供的管理网站让我们能够轻松地处理模型。网站的管理员可使用管理网站,但普通用户不能使用。接下来,我们将建立管理网站,并通过它使用模型topic来添加一些主题。
1、创建超级用户
Django允许我们创建具备所有权限用户——超级用户。权限决定了用户可执行操作。最严格的权限设置只允许用户阅读网站的公开信息;注册了的用户通常可阅读自己的私有数据,还可以查看一些只有会员才能看的信息。为了有效地管理web应用程序,网站所有者通常需要访问网站存储的所有信息。优秀的管理员会小心对待用户的敏感信息,因为用户对其访问的应用程序有极大的信任。
为在Django中创建用户,请执行下面的命令并按提示做:
python manage.py createsuperuser
ll_admin
当我们执行命令createsuperuser
时,Django提示我们输入超级用户的用户名。这里我们输入的是ll_admin
,但我们可以输入任何用户名,比如电子邮件地址,也可让这个字段为空。我们需要输入密码两次,具体内容如下:
具体体现在网站如下,我们这个网站出来后会让输入用户名和密码:
2、向管理网站注册模型
Django自动在管理网站中添加了一些模型,如user
和group
,但对于我们创建的模型,必须手工进行注册。我们是创建应用程序learning_logs
时,Django在models.py
所在目录中创建了一个名为admin.py
的文件,具体如下:
from django.contrib import admin
# 在这里注册你的模板
为向管理网站注册Topic
,请输入以下的代码:
from django.contrib import admin
from learning_logs.models import Topic, Entry
admin.site.register(Topic)
这些代码导入我们注册的模型Topic
,再使用admin.site.register()
让Django通过管理网站管理我们的模型。
现在,可使用超级用户账户访问管理网站,并输入我们刚创建的超级用户的用户名和密码,我们将看到类似于如下所示的屏幕。这个网站让我们能够添加修改用户和用户组,还可以管理与刚才定义的模型topic相关的数据。具体如下:
3、添加主题
向管理网站注册Topic
后,我们来添加第一个主题。为此,单击Topic
进入主题网页,它几乎是空的,这是因为我们还没有添加任何主题。单击Add,你将看到一个用于添加新主题的表单。在第一个方框中输入Chess
,再单击save,这将返回到主题管理页面,其中包含刚新建的主题。
下满再创建一个主题,以便有更多的数据可供使用。再次单击Add
,并在创建另一个主题Python
。当我们单击save时,将重新回到主题管理页面,其中包含主题java和chess。
四、定义模型Entry
要记录学到的Python知识,需要为用户可在学习笔记中添加的条目定义模型。每个条目都与特定主题相关联,这种关系被称为多对一关系,即多个条目可关联到同一个主题。下面是模型Entry
的代码:
class Entry(models.Model):
"""学到的有关某个主题的具体知识"""
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'entries'
def __str__(self):
"""返回模型的字符串表示"""
return self.text[:50] + "..."
像Topic
一样,Entry
也继承了Django基类Model
。第一个属性Topic
是一个ForeignKey
实例。外键是一个数据库术语,它引用了数据库中额另一条记录;这些代码将每个条目关联到特定的主题。每个主题创建时,都给它分配了一个键(或ID)。需要在两项数据之间建立联系时,Django使用与每项信息相关联的键。稍后我们将根据这些联系获取特定的主题相关联的所有条目。
接下来属性text
,它是一个TextField
实例。这种字段不需要长度限制,因为我们不想限制条目的长度。属性data_added
让我们能够按创建顺序来呈现条目,并在每个条目旁边放置。
最后,我们在Entry
中嵌入了Meta
类。Meta
存储用于管理模型的额外信息,在这里,它让我们能够设置一个特殊属性,让Django
在需要时使用Entries
来表示多个条目。如果没有这个类,Django将使用entrys来表示这个多个条目。最后,方法__str__()
告诉Django,呈现条目时应显示哪些信息。由于条目包含的文本可能很长,我们让Django只显示text的前50个字符。我们还添加了一个省略号,指出显示的并非整个条目。
五、迁移模型Entry
由于我们添加了一个新模型,因此需要再次迁移数据库。我们将慢慢地对这个过程了如指掌:修改models.py
,执行命令python manage.py makemigrations app_name
,再执行命令python manage.py migrate
。下面来迁移数据库并查出输出:
python manage.py makemigrations learning_logs
python manage.py migrate
生成了一个新的迁移文件——0002_entry.py
,它告诉Django如何修改数据库,使其能够存储与模型entry相关信息。执行命令migrate,我们发下Django应用了这种迁移且一切顺利。具体如下:
六、向管理网站注册Entry
我们还需要注册模型Entry
,为此,需要将admin.py修成类似于下面这样:
from django.contrib import admin
from learning_logs.models import Topic, Entry
admin.site.register(Topic)
admin.site.register(Entry)
返回到http://localhost:8000/admin
,你将看到learning_logs
下列出了Entries
。单击Entries
的Add链接,或者单击Entries
再选择Add entry
。具体如下:
我们将看到一个下拉列表,让你能够选择要为哪个主题创建条目,还有一个用于输入条目的文本框。从下拉列表中选择Python
,并添加一个条目。下面是我们添加的第一条条目:
当我们单击save的时候,将返回的主条目管理页面。在这里,我们将使用text[:50]
作为条目的字符串表示的好处;管理界面中,只显示了条目的开发部分而不是所有文本,这使得管理多个条目容易的多。具体过程如下:
创建好的效果如下:
再来创建两条Python的相关内容,具体内容如下:
创建好的这三条数据效果如下:
我们继续接着往下开发“学习笔记”时,这三个条目可为我们提供使用的数据。
七、Django shell
输入一些数据后,就可以通过交互式终端会话以编程方式查看这些数据了。这种交互式环境称为Django shell,是测试项目和排除其故障的理想之地。下面是一个交互式shell会话示例:
python manage.py shell
from learning_logs.models import Topic
Topic.objects.all()
在活动的虚拟环境中执行时,命令python manage.py shell
启动一个Python解释器,可使用它来探索存储在项目数据库中的数据。在这里,我们导入了模块learning_logs.models
中的模型Topic
,然后使用方法Topic.objects.all()
来获取模型Topic
的所有实例;它返回的是一个列表,称为查询接。具体过程如下:
我们可以像遍历列表一样遍历查询集。下面演示了如何查看分配给每个主题对象的ID:
topics = Topic.objects.all()
for topic in topics:
print(topic.id, topic)
我们将返回的查询集存储在topics中,然后打印每个主题的id属性和字符串表示。从输出可知,主题Python的ID为3,具体如下:
知道对象的ID后,就可获得该对象并查看其任何属性。下面来看看主题Python的属性text
和date_add
的值,具体如下:
t = Topic.objects.get(id = 1)
t.text
t.date_added
具体的结果如下:
我们还可以查看与主题相关联的条目。前面我们给模型Entry
定义属性topic,这是一个ForeignKey
,将条目与主题关联起来,Django能够获取与特定主题相关联的所有条目,具体如下:
t.entry_set.all()
具体结果如下:
为通过外键关系获取数据,可使用相关模型的小写名称、下划线和单词set。例如,假设你有模型Pizza和Topping,而Topping通过一个外键关联到Pizza;如果我们有一个my_pizza的对象,表示一张比萨,就可使用代码my_pizza.topping_set.all()
来获取这张比萨的所有配料。
在编写用户可请求的网页时,我们将使用这种语法。确认代码能获取所需的数据时,shell很有帮助。如果代码在shell中的行为符合预期,那么它们在项目文件中也能正确地工作。如果代码引发了错误或获取的数据不符合预期,那么在简单的shell环境中排除故障要比在生成网页的文件中排除故障容易的多。我们不会太多地使用shell,但应继续使用它阿里熟悉对存储在项目中的数据进行访问Django语法。
总结
从上篇文章开始给大家介绍Django的入门,一套用于帮助开发交互式网站的工具。Django能够响应网站请求,还能让你更轻松地读写数据库、管理用户等。主要包括制定规范、建立虚拟环境、安装virtualenv、激活虚拟环境、安装Django以及在Django中创建项目、创建数据库以及最后查看项目。本文给大家介绍创建应用程序的相关内容,主要包括定义、激活模型、Django管理网站以及定义和迁移模型entry和最后的Django shell的简单使用。Python是一门注重实际操作的语言,它是众多编程语言中最简单,也是最好入门的。当你把这门语言学会了,再去学习java、go以及C语言就比较简单了。当然,Python也是一门热门语言,对于人工智能的实现有着很大的帮助,因此,值得大家花时间去学习。生命不息,奋斗不止,我们每天努力,好好学习,不断提高自己的能力,相信自己一定会学有所获。加油!!!