从零搭建一个Django项目(二): 模型的使用

462 阅读2分钟

这里接着上一篇内容继续 从零搭建一个Django项目(一)

数据库配置

Django支持以下数据库:

'django.db.backends.sqlite3','django.db.backends.postgresql','django.db.backends.mysql',或 'django.db.backends.oracle'。

这里以mysql为例,修改settings配置如下(修改配置为你要连接的数据库配置即可),并安装mysqlclient库

...
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
         # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'NAME': 'demo001',
        'USER': 'root',
        'PASSWORD': 'pwd',
        'HOST': '127.0.0.1',
        'PORT': 3306
    }
}
...

修改完成后启动服务,如果启动成功,说明配置ok

创建模型

模型的定义即通过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.CharField(max_length=200)
    votes = models.IntegerField(default=0)

每个字段都是 Field 类的实例 - 比如,字符字段被表示为 CharField ,日期时间字段被表示为 DateTimeField 。这将告诉 Django 每个字段要处理的数据类型。

每个 Field 类实例变量的名字(例如 question_text 或 pub_date )也是字段名,所以最好使用对机器友好的格式。你将会在 Python 代码里使用它们,而数据库会将它们作为列名。

*主键(IDs)会被自动创建。(当然,你也可以自定义。)

应用模型

Step 1

首先将应用包含在这个项目中,在settings中设置如下

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls',
]

Step 2

第二步,将模型生成用于操作数据库的python代码

$ python manage.py makemigrations polls

输出如下


Migrations for 'polls':
  polls/migrations/0001_initial.py:
    - Create model Choice
    - Create model Question
    - Add field question to choice

可以使用以下命令查看将要执行的sql语句

$ python manage.py sqlmigrate polls 0001

输出结果如下

BEGIN;
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "choice_text" varchar(200) NOT NULL,
    "votes" integer NOT NULL
);
--
-- Create model Question
--
CREATE TABLE "polls_question" (
    "id" serial NOT NULL PRIMARY KEY,
    "question_text" varchar(200) NOT NULL,
    "pub_date" timestamp with time zone NOT NULL
);
--
-- Add field question to choice
--
ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
ALTER TABLE "polls_choice"
  ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
    FOREIGN KEY ("question_id")
    REFERENCES "polls_question" ("id")
    DEFERRABLE INITIALLY DEFERRED;

COMMIT;

Step 3

将模型真正应用到数据库

$ python manage.py migrate

这个 migrate 命令选中所有还没有执行过的迁移(Django 通过在数据库中创建一个特殊的表 django_migrations 来跟踪执行过哪些迁移)并应用在数据库上 - 也就是将你对模型的更改同步到数据库结构上。

总结

  • 编辑 models.py 文件,改变模型。
  • 运行 python manage.py makemigrations 为模型的改变生成迁移文件。
  • 运行 python manage.py migrate 来应用数据库迁移。

Django Shell

可以通过以下方式进入Django的交互命令行模式,需要这么做是因为 manage.py 会设置DJANGO_SETTINGS_MODULE 环境变量,这个变量会让 Django 根据 mysite/settings.py 文件来设置 Python 包的导入路径。

$ python manage.py shell

进入交互命令行之后

>>> from polls.models import Choice, Question  # Import the model

# 查询所有数据
>>> Question.objects.all()
<QuerySet []>

# 创建数据
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
>>> q.save()

# 查看当前数据(自增id只有在save之后才会生成)
>>> q.id
1

>>> q.question_text
"What's new?"

>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

# 修改数据并再次保存
>>> q.question_text = "What's up?"
>>> q.save()

# 再次查询所有数据
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>

查看数据

但是发现上面的查询有一个问题,就是<Question: Question object (1)> 对于我们并没有什么意义,想要看到具体的数据,可以在model中给 Question 和 Choice 增加 str() 方法。

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    def __str__(self):
        return str(self.id) + ':' +self.question_text


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    def __str__(self):
        return self.choice_text

再次进入Django Shell查看数据

>>> from polls.models import Choice,Question

>>> Question.objects.all()
<QuerySet [<Question: 1:test ques001>]>

*更多查询api操作参考Django 官方文档

Django Admin

创建管理账号

$ python manage.py createsuperuser #交互式输入对应信息

$ python manage.py runserver #启动服务

打开"http://127.0.0.1:8000/admin/" 登入admin管理界面

将应用添加到管理台

打开 polls/admin.py 文件,添加如下代码

from django.contrib import admin

from .models import Question

admin.site.register(Question)

重启服务,管理台页面如下

*更多查admin操作参考Django 官方文档