Django 开发Tutorial part_2

本文参考:https://docs.djangoproject.com/en/1.9/intro/tutorial02/

设置数据库:

  在mysite/setting.py里设置数据库类型,默认如下:

1 DATABASES = {
2     'default': {
3         'ENGINE': 'django.db.backends.sqlite3',
4         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
5     }
6 }

  其中EGINE可以替换为其他数据库。

1 'django.db.backends.sqlite3',
2 'django.db.backends.postgresql',
3 'django.db.backends.mysql',
4 'django.db.backends.oracle'

  python默认内置了sqlite,Django同样可以使用。

  然后运行 python manage.py migrate ,会根据setting.py里的 INSTALLED_APPS 设置数据库表。


 

接下来设置模版:

  编辑polls/model.py

 1 from django.db import models
 2 
 3 
 4 class Question(models.Model):
 5     question_text = models.CharField(max_length=200)
 6     pub_date = models.DateTimeField('date published')
 7 
 8 
 9 class Choice(models.Model):
10     question = models.ForeignKey(Question, on_delete=models.CASCADE)
11     choice_text = models.CharField(max_length=200)
12     votes = models.IntegerField(default=0)

  每个类都是 dango.db.models.Model 的子类,每个类具有许多类变量,每个都是模版数据库的字段。每个字段由 Field 字段的实例表示,如 CharField , DateTimeField ,分别表示字符字段和日期时间字段。

  字段的实例(如 question_text 和 pub_date ),是对机器友好的格式,可以在Python代码中使用,也可以在数据库的列名中使用。

  一些字段类需要参数,以 CharField 为例,需要 max_length 参数,它不仅仅用在数据库模式 ,验证也会用到(保留疑问,原文说稍后提及)。一些字段也有可选参数,在这种情况下,我们设置 default 为0.

  它们的关系是由 ForeignKey 建立的,这告诉Django每个 Choice 都会联系到一个 Question 上,Django支持很多常见的数据库关系:多对一,多对多,一对一。


 

激活模版:

  首先需要告诉项目polls app已经安装了

  再次编辑mysite/setting.py

1 INSTALLED_APPS = [
2     'polls.apps.PollsConfig',    #加入这行,告诉Django已经加入了polls App    
3     'django.contrib.admin',
4     'django.contrib.auth',
5     'django.contrib.contenttypes',
6     'django.contrib.sessions',
7     'django.contrib.messages',
8     'django.contrib.staticfiles',
9 ]

  接下来运行 python manage.py makemigration polls .

  虽然只有一行代码,却做了很多事情:

    1:为这个APP创建数据库架构(CREATE TABLE语句)

    2:为了访问Question 和 Choice 创建了一套python的连接数据库的API

  然后出现了如下文字

1 Migrations for 'polls':
2   0001_initial.py:
3     - Create model Choice
4     - Create model Question
5     - Add field question to choice

  makemigration  实际是告诉Django,模版已经做了改变(在这里是增加了创建了新的模版),需要将该改变的部分 migrate 。

 Migration是Django存储模版的方式,它仅仅是硬盘上的文件,你可以读取它。就像polls/migration/0001_initial.py一样。你可以读取它,并且它是可以修改的,以方便必要的时候手动修改。文件如下:

 1 # -*- coding: utf-8 -*-
 2 # Generated by Django 1.9.4 on 2016-03-14 04:46
 3 from __future__ import unicode_literals
 4 
 5 from django.db import migrations, models
 6 import django.db.models.deletion
 7 
 8 
 9 class Migration(migrations.Migration):
10 
11     initial = True
12 
13     dependencies = [
14     ]
15 
16     operations = [
17         migrations.CreateModel(
18             name='Choice',
19             fields=[
20                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21                 ('choice_text', models.CharField(max_length=200)),
22                 ('votes', models.IntegerField(default=0)),
23             ],
24         ),
25         migrations.CreateModel(
26             name='Question',
27             fields=[
28                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
29                 ('question_text', models.CharField(max_length=200)),
30                 ('pub_date', models.DateTimeField(verbose_name='date published')),
31             ],
32         ),
33         migrations.AddField(
34             model_name='choice',
35             name='question',
36             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='polls.Question'),
37         ),
38     ]

 

  也就是说,这些代码是 makemigration 生成用于 migrate 的。

 

  接下来运行 python manage.py sqlmigrate polls 0001 

  运行结果如下

 1 BEGIN;
 2 --
 3 -- Create model Choice
 4 --
 5 CREATE TABLE "polls_choice" (
 6     "id" serial NOT NULL PRIMARY KEY,
 7     "choice_text" varchar(200) NOT NULL,
 8     "votes" integer NOT NULL
 9 );
10 --
11 -- Create model Question
12 --
13 CREATE TABLE "polls_question" (
14     "id" serial NOT NULL PRIMARY KEY,
15     "question_text" varchar(200) NOT NULL,
16     "pub_date" timestamp with time zone NOT NULL
17 );
18 --
19 -- Add field question to choice
20 --
21 ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
22 ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
23 CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
24 ALTER TABLE "polls_choice"
25   ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
26     FOREIGN KEY ("question_id")
27     REFERENCES "polls_question" ("id")
28     DEFERRABLE INITIALLY DEFERRED;
29 
30 COMMIT;

不同的数据库会产生不同的结果,这是PostgreSQL的结果。

其中创建的表名是根据APP的名字(polls)和模版名的小写(questionh和choice)(可以重写),主键是自动生成的(可以重写),为了方便起见, 外键被加上了_id后缀(也可以重写),外键关系由 FOREIGN KEY 明确做出了约束。

  sqlmigrate 并不会真正对数据库执行 migration ,它只是把SQL Django认为需要执行的命令打印出来,以方便数据库管理员做SQL脚本上的修改。

  你还可以执行 python manage.py check ,检查是否做了 migrations 或者有没有使用数据库。

  现在执行 python manage.py migrate ,应用 migration 。

  

  现在来总结一下:

  1:首先编辑models.py

  2:运行 python manage.py makemigrations  ,创建 migrations 

  3:运行 python manage.py migrate ,应用 migrations 

 

  为什么要将第二步和第三步拆开呢?这样会使开发变得简单,有效率。


 

试试API吧!

  执行 python manage.py shell 这条指令代替 python 直接打开python环境,是为了设置 DJANGO_SETTINGS_MODULE 环境变量,这个环境变量是告诉Django你所使用的setting。

  在现在这个环境中,你可以试试数据库的API了。

>>> from polls.models import Question, Choice  
# Import the model classes we just wrote. # 这个系统里还没有提问. >>> Question.objects.all() [] # 创建一个新的提问. # 为默认设置的时区提供支持, Django可以用tzinfo为pub_date提供时间,使用 # timezone.now()来代替datetime.datetime.now() >>> from django.utils import timezone >>> q = Question(question_text="What's new?", pub_date=timezone.now()) # 把对象存入数据库 >>> q.save() # 现在它有id了 >>> q.id 1 # 可以通过python的属性来访问模版字段值. >>> q.question_text "What's new?" >>> q.pub_date datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=) # 通过改变属性,调用save来更改值 >>> q.question_text = "What's up?" >>> q.save() # objects.all() 显示数据库中所有的提问. >>> Question.objects.all() []

但是 [] 这样的信息对我们毫无帮助,现在让我们为 Question 和 Chocie 类来添加 __str__ 方法

1 class Question(models.Model):
2     # ...
3     def __str__(self):
4         return self.question_text
5 
6 class Choice(models.Model):
7     # ...
8     def __str__(self):
9         return self.choice_text

这样不仅方便自己查看,更重要的是在整个Django的自动生成过程都会出现。

__str__是普通的类方法,放我们来加一个自定义的类方法修饰一下。

 1 import datetime
 2 
 3 from django.db import models
 4 from django.utils import timezone
 5 
 6 
 7 class Question(models.Model):
 8     # ...
 9     def was_published_recently(self):
10         return self.pub_date >= timezone.now()

在这里我们加入了 datetime 和 timezone 模块,前者是python标准库的内置模块,后者是Django内置模块

重新打开环境,测试

 1 >>> from polls.models import Question, Choice
 2 
 3 # 测试 __str__() 是否工作
 4 >>> Question.objects.all()
 5 ['s up?>]
 6 
 7 # Django可以使用关键字参数使用很多查看数据库的API
 8 >>> Question.objects.filter(id=1)
 9 ['s up?>]
10 >>> Question.objects.filter(question_text__startswith='What')
11 ['s up?>]
12 
13 # 获取一个今年提出的问题
14 >>> from django.utils import timezone
15 >>> current_year = timezone.now().year
16 >>> Question.objects.get(pub_date__year=current_year)
17 's up?>
18 
19 # 查看的id不存在,抛出异常
20 >>> Question.objects.get(id=2)
21 Traceback (most recent call last):
22     ...
23 DoesNotExist: Question matching query does not exist.
24 
25 #通过主键查找是最常见的情况,所以Django提供了一套和主键看起来一样#的shortcut(不知道这个单单词该如何准确的翻译,是捷径的意思)
26 #下面的语句和Question.objects.get(id=1)意思一样
27 >>> Question.objects.get(pk=1)
28 's up?>
29 
30 # 确保自定义类方法可以工作
31 >>> q = Question.objects.get(pk=1)
32 >>> q.was_published_recently()
33 True
34 
35 # 给Question类一对Choices类. 这叫创建新Choice的对象, 相当于执行 #INSERT语句, 增加选项到集合并返回一个新的Choice对象 
36 # Django创建了一个集合来保存这些“外部”的主键关系
37 # (例如 一个提问的选项) 可以通过API连接.
38 >>> q = Question.objects.get(pk=1)
39 
40 # 打印选项的集合
41 >>> q.choice_set.all()
42 []
43 
44 # 增加三个选项.
45 >>> q.choice_set.create(choice_text='Not much', votes=0)
46 
47 >>> q.choice_set.create(choice_text='The sky', votes=0)
48 
49 >>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)
50 
51 # Choice对象和Question对象通过API联系
52 >>> c.question
53 's up?>
54 
55 # 反之亦然
56 >>> q.choice_set.all()
57 [, , ]
58 >>> q.choice_set.count()
59 3
60 
61 # 这些API会自动跟随你需要的数据关系
62 # 用双下划线来分隔这些关系
63 # 你可以建立很多层的关系,这是没有限制的
64 # 查找所有pub_date在今年的的Choices
65 # (重用我们分刚刚创建的 'current_year' 变量).
66 >>> Choice.objects.filter(question__pub_date__year=current_year)
67 [, , ]
68 
69 # 删除一个选项
70 >>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
71 >>> c.delete()

 


 

Django管理员
  创建管理员 python manage.py createsuperuser 
  按照指示输入用户名,邮箱,密码。
  然后运行server  python manage.py runserver 
  打开网站 http://127.0.0.1/8000/admin 各种玩去吧!

  如果是英文界面的话,设置setting.py 里的 LANGUAGE_CODE = 'zh-CN' ,就变成中文了。

转载于:https://www.cnblogs.com/fudianheg/p/5276944.html

你可能感兴趣的:(数据库,python,shell)