在Django中,项目(Project)是一个网站的总的合集,应用(APP)是单个的功能模块。比如淘宝网是一个项目,其中的用户管理、订单管理、商品管理、电商直播等等功能模块是一个个的应用。虽然可以把所有功能写在一个应用里,但是强烈不建议这么做,把项目拆合理地拆分成应用是更加正确的做法。

用Pycharm打开我们之前创建的项目:File-Open,选中my_blog文件夹,单击OK按钮。

打开cmd,进入my_blog目录,然后开启虚拟环境。由于Scripts文件夹在上一层目录中,这里用..表示上一层目录。

C:\Users\glp\blog\env\my_blog>..\Scripts\activate
(env) C:\Users\glp\blog\env\my_blog>

创建名为“article”的APP。

(env) C:\Users\glp\blog\env\my_blog>python manage.py startapp article

此时,我们的项目结构是这样的:

my_blog
│  db.sqlite3
│  manage.py
│
├─article
│  │  admin.py
│  │  apps.py
│  │  models.py
│  │  tests.py
│  │  views.py
│  │  __init__.py
│  │
│  └─migrations
│        └─ __init__.py
│
└─my_blog
    │  settings.py
    │  urls.py
    │  wsgi.py
    └─ __init__.py

根目录my_blog是我们的项目名称。db.sqlite3是数据库文件,用来存储数据的。manage.py是执行命令用的工具,后面会经常用到。article是我们刚刚创建的APP。最下面的my_blog是创建项目时自动生成的APP,其中的settings.py是配置文件,urls.py是根路由文件。

我们刚刚创建了一个APP,需要在配置文件settings.py中进行注册,把APP名字添加到INSTALLED_APPS中。后面每次创建APP都要记得在settings.py中注册,否则会报错。

my_blog/settings.py

INSTALLED_APPS = [
    # 其他代码
    ...

    # 注册article应用
    'article',
]

访问路径url也要在urls.py中配置。

my_blog/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    # 其他代码
    ...

    # 配置article应用的url
    path('article/', include('article.urls', namespace='article')),
]

article/是项目给article应用分配的访问路径。article.urls是article应用的路由文件,这个文件没有自动生成,后面需要手动创建。namespace相当于给article应用的路径起了个外号,后面编码会用到。如果这里有疑惑,接着看下去,后面有总结。

在article文件夹中创建文件urls.py,然后输入下面的内容。

article/urls.py

from django.urls import path

app_name = 'article'
urlpatterns = [
]

我们在编写Django项目的时候,主要在三个地方写代码:模型(model),视图(view),模板(template)。模型和数据库打交道,负责规定数据库存储什么样的数据,比如文章名、作者、文章内容。视图从模型中取出数据,进行逻辑处理之后,把数据传给模板。模板接收到数据之后,展示到网页上。这里的描述不是十分精确,了解大概意思就行,后面会逐步加深对这三者的理解。

打开article目录下的models.py文件,输入下面的代码。

article/models.py

from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone


class ArticlePost(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    body = models.TextField()
    created = models.DateTimeField(default=timezone.now)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ('-created',)

    def __str__(self):
        return self.title

这里要说一下自学编程的学习方法。如果在学习中遇到了不懂的地方,所看的教程又没有解释,那么一定要学会使用搜索引擎,推荐使用谷歌、多吉。在搜索的过程中,提升自己从问题中提炼关键词的能力。比如这里的on_delete,完全就可以通过搜索引擎明白这是什么。

这个model定义了一篇文章的属性。作者和文章有一对一(一个作者只写了一篇文章)和一对多(一个作者写了多篇文章)两种关系,author使用外键ForeignKey关联到了User。类比:如果我们定义一个学生的模型,那么应该这么写:

class 学生(models.Model):
    班级 = models.ForeignKey(班级类)

前面的班级是学生的一个属性,后面的班级类是一个类。

created和updated分别会在文章被创建和被修改的时候自动生成当时的时间,不用手动填写。

Meta是一个内部类,用来定义字段以外的属性(字段的意思是模型里面的属性,如author、title、body都是一个个字段),ordering表明了文章的排序方式,按照创建时间的倒序排列,也就是新创建的文章排在最前面。__str__方法向外展示了该数据显示的名称,在Django后台管理部分我们会看到它的效果。

我们写好模型文件之后,需要执行数据迁移,把models.py中规定的字段添加到db.sqlite3文件中。我们每一次对modles.py进行修改,都要执行一次迁移,否则不会生效。

使用cmd进入虚拟环境,使用python manage.py makemigrations生成迁移文件,再使用python manage.py migrate执行迁移。

C:\Users\glp>cd blog\env\my_blog
C:\Users\glp>cd blog\env\my_blog>..\Scripts\activate
(env) C:\Users\glp\blog\env\my_blog>python manage.py makemigrations
(env) C:\Users\glp\blog\env\my_blog>python manage.py migrate

到这里为止,我们就把模型写好了,它定义了数据库存储的数据应该是什么样的。下面开始写视图,再提醒一下,视图用来从模型中获取数据并进行逻辑处理。