Python:Django入门——建立项目 & 创建应用程序

来源:《Python编程:从入门到实践》

文章目录

  • 1 建立项目
    • 1.1 制定规范
    • 1.2 建立虚拟环境
    • 1.3 安装virtualenv
    • 1.4 激活虚拟环境
    • 1.5 安装Django
    • 1.6 在Django中创建项目
    • 1.7 创建数据库
    • 1.8 查看项目
  • 2 创建应用程序
    • 2.1 定义模型
    • 2.2 激活模型
    • 2.3 Django管理网站
      • 1.创建超级用户
      • 2.向管理网站注册模型
      • 3.添加主题
    • 2.4 定义模型Entry
    • 2.5 迁移模型Entry
    • 2.6 向管理网站注册Entry
    • 2.7 Django shell

  • 本章学习如何使用Django(http://djangoproject.com)开发一个“学习笔记”(Learning Log)的项目,这是一个在线日志系统,能够记录所学习的有关特定主题的知识
  • 将为这个项目制定规范,然后为应用程序使用的数据定义模型
  • 将使用Django的管理系统来输入一些初始数据,再学习编写视图和模板,让Django能够为我们的网站创建网页
  • Django是一个Web框架——一套用于帮助开发交互式网站的工具
  • Django能够响应网页请求,还能让你更轻松地读写数据库、管理用户等

1 建立项目

  • 建立项目时,首先需要以规范的方式对项目进行描述,再建立虚拟环境,以便在其中创建项目

1.1 制定规范

  • 完整的规范详细说明了项目的目标,阐述了项目的功能,并讨论了项目的外观和用户界面
  • 规范应突出重点,帮助避免项目轨道
  • 这里不会制定完整的项目规划,而只列出一些明确的目标,以突出开发的重点:

我们要编写一个名为“学习笔记”的Web应用程序,让用户能够记录感兴趣的主题,并在学习每个主题的过程中添加日志条目。“学习笔记”的主页对这个网站进行描述,并邀请用户注册或登录。用户登录后,就可创建新主题、添加新条目以及阅读既有的条目。

1.2 建立虚拟环境

  • 要使用Django,首先需要建立一个虚拟工作环境
  • 虚拟环境 是系统的一个位置,你可以在其中安装包,并将其与其他Python包隔离
  • 将项目的库与其他项目分离是有益的,且为了在后面的章节将“学习笔记”部署到服务器,这也是必须的
  • 为项目新建一个目录,将其命名为learning_log,再在终端中切换到这个目录,并创建一个虚拟环境
  • 如果使用的是Python 3,使用如下命令创建虚拟环境:
python -m venv ll_env
  • 这里运行了模块venv,并使用它来创建一个名为ll_env的虚拟环境。
  • 如果这样做OK,请跳到后面的1.4节;如果不行,请看下面一节

1.3 安装virtualenv

  • 如果使用的是较早的Python版本,或者系统没有正确地配置,不能使用模块venv,可安装virtualenv包:
pip install --user virtualenv

注意:如果你使用的是Linux系统,且上面的做法不管用,可使用系统的包管理器来安装virtualenv。例如,要在Ubuntu系统中安装virtualenv,可使用命令sudo apt-get install python-virtualenv

  • 在终端中切换到目录learning_log,并像下面这样创建一个虚拟环境:
virtualenv ll_env

注意:如果你的系统安装了多个Python版本,需要指定virtualenv使用的版本。例如,命令virtualenv ll_env --python=python3创建一个使用python3的虚拟环境

1.4 激活虚拟环境

  • 建立虚拟环境后,需要下面的命令激活它:
ll_env\Scripts\activate

Python:Django入门——建立项目 & 创建应用程序_第1张图片

  • 要停止使用虚拟环境,可执行命令deactivate
  • 如果关闭运行虚拟环境的终端,虚拟环境也将不再处于活动状态

1.5 安装Django

  • 创建并激活虚拟环境后,就可安装Django了(这里使用1.11版):
pip install Django==1.11

Python:Django入门——建立项目 & 创建应用程序_第2张图片

1.6 在Django中创建项目

  • 在依然处于活动的虚拟环境的情况下(ll_env包含在括号内),执行如下命令来新建一个项目:
django-admin.py startproject learning_log .
dir
dir learning_log

Python:Django入门——建立项目 & 创建应用程序_第3张图片

  • django-admin.py startproject learning_log .让Django新建一个名为learning_log的项目。这个命令末尾的句点让新项目使用合适的目录结构,这样开发完成后可轻松地将应用程序部署到服务器

注意 : 千万别忘了这个句点,否则部署应用程序时将遭遇一些配置问题。如果忘记了这个句点,就将创建的文件和文件夹删除(ll_env除外),再重新运行这个命令

  • 第二行的命令dir,结果表明Django新建了一个名为learning_log的目录。
  • 它还创建了一个名为manage.py的文件,这是一个简单的程序,它接受命令将其交给Django的相关部分去运行
  • 我们将使用这些命令来管理诸如使用数据库和运行服务器等任务
  • 目录learning_log包含4个文件,其中最重要的是settings.py、urls.py和wsgi.py
    1. settings.py指定Django如何与你的系统交互以及如何管理项目。在开发项目的过程中,将修改其中一些设置,并添加一些设置
    2. urls.py 告诉Django应创建哪些网页来响应浏览器请求
    3. wsgi.py 帮助Django提供它创建的文件,这个文件名是web server gateway interface(Web服务器网关接口)的首字母缩写

1.7 创建数据库

  • Django将大部分与项目相关的信息都存储在数据库中,因此我们需要创建一个供Django使用的数据库
  • 为给项目“学习笔记”创建数据库,请在处于活动虚拟环境中的情况虚执行下面的命令:
(ll_env) F:\python_work\learning_log>python manage.py migrate

Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "F:\python_work\learning_log\ll_env\lib\site-packages\django\core\management\__init__.py", line 363, in execute_from_command_line
    utility.execute()
  File "F:\python_work\learning_log\ll_env\lib\site-packages\django\core\management\__init__.py", line 337, in execute
    django.setup()
  File "F:\python_work\learning_log\ll_env\lib\site-packages\django\__init__.py", line 27, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "F:\python_work\learning_log\ll_env\lib\site-packages\django\apps\registry.py", line 85, in populate
    app_config = AppConfig.create(entry)
  File "F:\python_work\learning_log\ll_env\lib\site-packages\django\apps\config.py", line 94, in create
    module = import_module(entry)
  File "C:\Users\M S I\AppData\Local\Programs\Python\Python37\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "", line 1006, in _gcd_import
  File "", line 983, in _find_and_load
  File "", line 967, in _find_and_load_unlocked
  File "", line 677, in _load_unlocked
  File "", line 728, in exec_module
  File "", line 219, in _call_with_frames_removed
  File "F:\python_work\learning_log\ll_env\lib\site-packages\django\contrib\admin\__init__.py", line 4, in <module>
    from django.contrib.admin.filters import (
  File "F:\python_work\learning_log\ll_env\lib\site-packages\django\contrib\admin\filters.py", line 10, in <module>
    from django.contrib.admin.options import IncorrectLookupParameters
  File "F:\python_work\learning_log\ll_env\lib\site-packages\django\contrib\admin\options.py", line 12, in <module>
    from django.contrib.admin import helpers, widgets
  File "F:\python_work\learning_log\ll_env\lib\site-packages\django\contrib\admin\widgets.py", line 151
    '%s=%s' % (k, v) for k, v in params.items(),
    ^
SyntaxError: Generator expression must be parenthesized
  • 这里出现了问题,由于django 1.11版本和python3.7版本不兼容, 2.0版本以后的Django修复了这个问题
  • 这篇文章对这个问题讲的比较详细:https://blog.csdn.net/qq_28194001/article/details/86709006
  • 再次执行命令,ok!
    Python:Django入门——建立项目 & 创建应用程序_第4张图片
  • 我们将修改数据库称为 迁移数据库
  • 首次执行命令migrate时,将让Django确保数据库与下面的当前状态匹配
  • 在使用SQLite的新项目中首次执行这个命令时,Django将新建一个数据库
  • python manage.py migrate Django指出它将创建必要的数据库表,用于存储我们将在这个项目(Synchronize unmigrated apps,同步未迁移的应用程序)中使用的信息,再确保数据库结构与当前代码(Apply all migrations,应用所有的迁移)匹配

1.8 查看项目

  • 下面来核实Django是否正确地创建了项目。为此,可执行命令runserver:
python manage.py runserver

Python:Django入门——建立项目 & 创建应用程序_第5张图片

  • Django启动一个服务器,让你能够查看系统中的项目,了解它们的工作情况
  • 当你在浏览器中输入URL以请求网页时,该Django服务器将进行响应:生成合适的网页,并将其发送给浏览器
  • 终端打印了一些信息,它指出了项目的URL。URL http://127.0.0.1:8000/表明项目将在你的计算机(即localhost)的端口8000上侦听请求
  • local是一种只处理当前系统发出的请求,而不允许其他任何人查看你正在开发的网页的服务器
  • 现在打开一款Web浏览器,输入URL:http://localhost:8000/;如果不管用就输入:http://127.0.0.1:8000/
  • 下面这个页面是Django创建的,让你知道到目前为止一切正常
    Python:Django入门——建立项目 & 创建应用程序_第6张图片

2 创建应用程序

  • Django项目 由一系列应用程序组成,它们协同工作,让项目成为一个整体
  • 我们暂时只创建一个应用程序,它将完成项目的大部分工作(下一章将再添加一个管理用户账户的应用程序)
  • 当前,在前面打开的终端窗口中应该还运行着runserver
  • 再打开一个终端窗口(或标签页),并切换到manage.py所在的目录
  • 激活该虚拟环境,再执行命令startapp:
ll_env\Scripts\activate
python manage.py startapp learning_logs
  • 命令startapp appname让Django建立创建应用程序所需的基础设施
  • 现在查看项目目录,看到新增了一个文件夹learning_logs
  • 打开这个文件夹,看看Django创建了什么
    Python:Django入门——建立项目 & 创建应用程序_第7张图片
  • 其中重要的文件是models.py、admin.py和views.py
  • 将使用models.py来定义要在应用程序中管理的数据
  • 剩下两个稍后了解

2.1 定义模型

  • 现在想一下涉及的数据
    • 每位用户都需要在学习笔记中创建很多主题
    • 用户输入的每个条目都与特定主题相关联,这些条目将以文本的方式显示
    • 还需要存储每个条目的时间戳,以便能够告诉用户各个条目都是什么时候创建的
  • 打开文件models.py,看看它当前包含哪些内容:

models.py

from django.db import models

# Create your models here.
  • 这为我们导入了模块models,还让我们创建自己的模型
  • 模型告诉Django如何处理应用程序中存储的数据
  • 在代码层面,模型就是一个类,包含属性和方法
  • 下面是表示用户将要存储的主题 的模型
from django.db import models

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和date_added
    • 属性text是一个CharField——由字符或文本组成的数据
    • 需要存储少量的文本,如名称、标题或城市时,可使用CharField
    • 定义CharField属性时,必须告诉Django该在数据库中预留多少空间
    • 这里将max_length设置为200(200个字符),这对存储大多数主题名来说足够了
    • 属性date_added是一个DateTimeField——记录日期和时间的数据
    • 实参auto_now_add=True,每当用户创建新主题时,都让Django将这个属性自动设置成当前日期和时间

注意 要获悉可在模型中使用的各种字段,参阅Django Model Field Reference(Django模型字段参考),网址为https://docs.djangoproject.com/en/1.8/ref/models/fields/

  • 我们需要告诉Django,默认应使用哪个属性来显示有关主题的信息
  • Django调用方法__str__()来显示模型的简单表示
  • 这里,它返回存储在属性text中的字符串

2.2 激活模型

  • 要使用模型,必须让Django将应用程序包含到项目中
  • 打开settings.py(位于目录learning_log/learning_log中),你将看到一个这样的片段,即告诉Django哪些应用程序安装在项目中

settings.py

--snip--
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
--snip--
  • 它告诉Django项目是由哪些应用程序组成的
  • 现在修改INSTALLED_APPS,将前面的应用程序添加到这个元组中
--snip--
INSTALLED_APPS = [
    --snip--
    'django.contrib.staticfiles',
    
    # My apps
    'learning_logs',
]
--snip--
  • 通过将应用程序编组,在项目不断增大,包含更多的应用程序时,有助于对应用程序进行跟踪
  • 接下来,让Django修改数据库,使其能够存储与模型Topic相关的信息
  • 为此,在终端窗口执行下面命令:
(ll_env) learning_log>python manage.py makemigrations learning_logs

Python:Django入门——建立项目 & 创建应用程序_第8张图片

  • 命令makemigrations让Django确定该如何修改数据库,使其能够存储与我们定义的新模型相关联的数据
  • 输出表明Django创建了一个名为0001_initial.py的迁移文件,这个文件将在数据库中为模型Topic创建一个表
  • 下面来应用这种迁移,让Django替我们修改数据库
(ll_env) learning_log>python manage.py migrate

Python:Django入门——建立项目 & 创建应用程序_第9张图片

  • 这个命令的大部分输出都与我们首次执行命令migrate的输出相同
  • Applying learning_logs.0001_initial... OK这里Django确认为learning_logs应用迁移时一切正常(OK)
  • 每当需要修改“学习笔记”管理的数据时,都采取如下三个步骤:
    1. 修改models.py
    2. 对learning_logs调用makemigrations
    3. 让Django迁移项目

2.3 Django管理网站

  • 为应用程序定义模型时,Django提供的管理网站(admin site)让你能够轻松地处理模型
  • 网站的管理员可使用管理网站,但普通用户不能使用
  • 在本节中,我们将建立管理网站,并通过它使用模型Topic来添加一些主题

1.创建超级用户

  • Django允许创建具备所有权限的用户——超级用户
  • 权限决定了用户可执行的操作
  • 最严格的权限设置只允许用户阅读网站的公开信息
  • 注册了的用户通常可阅读自己的私有数据,还可查看一些只有会员才能查看的信息
  • 为有效地管理Web应用程序,网站所有者通常需要访问网站存储的所有信息
  • 优秀的管理员会小心对待用户的敏感信息,因为用户对其访问的应用程序有极大的信任
  • 下面执行命令并根据提示做,在Django中创建超级用户:
(ll_env) learning_log>python manage.py createsuperuser
Username (leave blank to use 'msi'): ll_admin
Email address:
Password:
Password (again):
Superuser created successfully.

2.向管理网站注册模型

  • Django自动在管理网站中添加了一些模型,如User和Group
  • 但对于我们创建的模型,必须手工进行注册
  • 创建应用程序learning_logs时,Django在models.py所在的目录中创建了一个名为admin.py的文件

admin.py

from django.contrib import admin

# Register your models here.
  • 向管理网站注册Topic:
from django.contrib import admin

from learning_logs.models import Topic

admin.site.register(Topic)
  • 代码导入要注册的模型Topic,再使用admin.site.register()让Django通过管理网站管理我们的模型
  • 现在使用超级用户账户访问管理网站:访问http://localhost:8000/admin/
  • 输入刚创建的超级用户用户名和密码:
  • 这个网页让你能够添加和修改用户和用户组,还可以管理与刚才定义的模型Topic相关的数据

Python:Django入门——建立项目 & 创建应用程序_第10张图片

3.添加主题

  • 向管理网站注册Topic后,我们来添加第一个主题
  • 为此,单机Topics进入主题网页
  • 单击Add,将看到一个用于添加新主题的表单
  • 在第一个方框输入Chess,再单击Save,这将返回到主题管理页面,其中包含刚创建的主题
  • 下面再创建一个主题Rock Climbing

2.4 定义模型Entry

  • 要记录学到的国际象棋和攀爬知识,需要为用户可在学习笔记中添加的条目定义模型
  • 每个条目都与特定主题相关联,这种关系被称为 多对一关系 ,即多个条目可关联到同一个主题
  • 下面是模型Entry的代码:

models.py

from django.db import models

class Topic(models.Model):
    --snip--
    
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实例
    • 这种字段不需要长度限制,因为我们不想限制条目的长度
    • 属性date_added让我们能够按创建顺序呈现条目,并在每个条目旁边放置时间戳
  • Entry类中嵌套了Meta类
    • Meta存储用于管理模型的额外信息,这里,它让我们能够设置一个特殊属性,让Django在需要时使用Entries来表示多个条目
    • 如果没有这个类,Django将使用Entrys来表示多个条目
  • 方法__str__()告诉Django,呈现条目时应显示哪些信息
    • 由于条目包含的文本可能很长,我们让Django只显示text的前50个字符

2.5 迁移模型Entry

  • 由于刚添加了一个新模型,因此需要再次迁移数据库
  • 你将慢慢地对这个过程了如指掌:
    1. 修改models.py
    2. 对learning_logs调用makemigrations
    3. 让Django迁移项目
  • 下面来迁移数据库并查看输出:
(ll_env) learning_log>python manage.py makemigrations learning_logs
Migrations for 'learning_logs':
  learning_logs\migrations\0002_entry.py
    - Create model Entry

(ll_env) learning_log>python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, learning_logs, sessions
Running migrations:
  Applying learning_logs.0002_entry... OK
  • 生成了一个新的迁移文件——0002_entry.py,它告诉Django如何修改数据库,使其能够存储与模型Entry相关的信息
  • 执行命令migrate,发现Django应用了这种迁移且一切顺利

2.6 向管理网站注册Entry

  • 还需要注册模型Entry
  • 修改admin.py

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
  • 将看到一个下拉列表,让你能够选择要为哪个主题创建条目,还有一个用于输入条目的文本框
  • 从下拉列表中选择Chess,并添加一个条目
  • 下面是我添加的第一个条目:
	The opening is the first part of the game, roughly the first ten moves or so. In the opening,
it's a good idea to do three things--bring out your bishops and knights, try to control the center of the board,
and castle your king.
	Of course, these are just guidelines. It will be important to learn when to follow these guidelines and 
when to disregard these suggestions.
  • 单击Save,将返回到主条目管理页面
  • 在这里,你将发现使用text[:50]作为条目的字符串表示的好处:管理界面中,只显示了条目的开头部分而不是其所有文本,这使得管理多个条目容易得都
  • 下面再提供一些初始数据:
  • 再创建一个国际象棋条目:
	In the opening phase of the game, it's important to bring out your bishops and knights. These pieces
are powerful and maneuverable enough to play a significant role in the beginning moves of a game.
  • 创建一个攀岩条目:
	One of the most important concepts in climbing is to keep your weight on your feet as much as possible. 
There's a myth that climbers can hang all day on their arms.
  • 继续往下开发“学习笔记”时,这三个条目可为我们提供使用的数据

2.7 Django shell

  • 输入一些数据后,就可通过交互式终端会话以编程方式查看这些数据了
  • 这种交互式环境称为Django shell,是测试项目和排除其故障的理想之地
  • 下面是一个交互式shell会话示例:
(ll_env) learning_log>python manage.py shell
>>> from learning_logs.models import Topic
>>> Topic.objects.all()
<QuerySet [<Topic: Chess>, <Topic: Rock Climbing>]>
  • 在活动的虚拟环境中执行时,命令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)
...
1 Chess
2 Rock Climbing
  • 从输出可知,主题Chess的ID为1,而Rock Climbing的ID为2
  • 知道对象的ID后,就可获取该对象并查看其任何属性
  • 下面看看主题Chess的属性text和date_added的值:
>>> t = Topic.objects.get(id=1)
>>> t.text
'Chess'
>>> t.date_added
datetime.datetime(2019, 9, 3, 3, 17, 23, 266910, tzinfo=<UTC>)
  • 我们还可查看与主题相关联的条目
  • 前面给模型Entry定义了属性topic,这是一个ForeignKey,将条目与主题关联起来
  • 利用这种关联,Django能够获取与特定主题相关联的所有条目:
>>> t.entry_set.all()
<QuerySet [<Entry: The opening is the first part of the game, roughly...>, <Entry: In the opening phase of the game, it's important t...>]>
  • 为通过外键关系获取数据,可使用相关模型的小写名称、下划线和单词set
  • 编写用户可请求的网页时,我们将使用这种语法
  • 确认代码能获取所需的数据时,shell很有帮助
  • 如果代码在shell中的行为符合预期,那么它们在项目文件中也能正确地工作
  • 如果代码引发了错误或获取地数据不符合预期,那么在简单的shell环境中排除故障要比在生成网页的文件中排除故障容易得多
  • 我们不会太多地使用shell,但应继续使用它来熟悉对存储在项目中的数据进行访问的Django语法

注意: 每次修改模型后,都需要重启shell,这样才能看到修改的效果。要退出shell会话,可按CTRL+D;如果是Windows系统,按CTRL+Z,再看回车键。

你可能感兴趣的:(Python学习)