知识点

  1) 数据库的配置

    涉及到INSTALL_APPS的配置等

    初次创建数据的命令

  2) 模型的编写

    模型的创建方式, 写一个类继承自models.Model

    模型的数据类型

    外键

    自动创建ID列

    外键名的设置

    表名会被转化为小写

  3) 模型更改后对数据库生效的命令

    实际操作两条命令就可以完成

    中间可以查看一些信息 

  4) 操作数据的方法

    增删改查

    属性的获取

    __str__()的使用

    双下划线函数的用法(__startswith, __year)

    反向操作(获得related object set) 关联表名_set

    正向操作使用双下划线

    pk

    count()

  5) 后台管理的使用

    创建管理员的命令

    添加应用到后台管理 

1 建立数据库

  Django默认使用的是SQLite这一轻量的数据库

  如果需要配置别的数据库需要修改setting.py文件

  默认配置为

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}

  可以修改为

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}

  其中参数说明为

ENGINE:
'django.db.backends.sqlite3',
'django.db.backends.postgresql',
'django.db.backends.mysql',
'django.db.backends.oracle'
NAME:数据库的名称
如果使用SQLite,数据库将是您计算机上的一个文件, 此时NAME 应该是该文件的完全绝对路径,包括文件名。
默认值,将文件存储在项目目录中。os.path.join(BASE_DIR, 'db.sqlite3')

  除此之外, setting.py还需要配置    

  TIME_ZONE 为当前时区

  INSTALLED_APPS 包含当前需要使用的所有应用程序, 如果新建的应用程序, 应该添加上

    默认的值有

django.contrib.admin - 管理网站
django.contrib.auth - 认证系统
django.contrib.contenttypes - 内容类型的框架
django.contrib.sessions - 会话框架
django.contrib.messages - 消息框架
django.contrib.staticfiles - 一个用于管理静态文件的框架

  执行命令在数据库中创建表

python manage.py migrate

    - 该命令会查看INSTALLED_APPS 的设置

    - 还根据mysite/settings.py中的数据库设置来创建数据库表

2 创建模型

  Django遵循Don’t repeat yourself (DRY)原则, 使得在一个地方定义数据模型, 并自动获取数据

  具体创建如下

  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)

  一个模型就是一个类, 这个类继承自 django.db.models.Model

  每个模型有类变量, 每个类变量相当于一个数据库字段

  这个字段用 Field 类的实例表示

  具体类型有

  AutoField: 是整形类型的数据, 用作ID递增, 具有自增的效果, 默认会自动添加一个该字段

  BigAutoField: 64位整数的自动递增ID, 范围从1到9223372036854775807

  BigIntegerField: 64位整数, 范围-9223372036854775808到 9223372036854775807

  BinaryField: 二进制数据字段, 官方不推荐使用

  BooleanField: 布尔值. 当Field.default 没有定义时默认值为None

    如果需要可以设置为null, 可以使用NullBooleanField

  CharField: 字符串类型

    必须传入max_length设置最大长度

  DateField: 日期类型, 值是datetime.date对象

    auto_now: True/False, 表示每次保存时设置为当前时间, 也就是最后修改时间

    auto_now_add: True/False, 表示首次创建时设置为当前时间, 也就是创建时间

  DateTimeField: 日期类型, 值是datetime.datetime对象

  TimeField:日期类型, 值是datetime.time对象

    DecimalField: 固定精度的十进制数, 值是Decimal值

    必须参数max_digits: 最大位数

    必须参数decimal_places: 小数位数

  DurationField: 时间段, 值是timedelta

  EmailField: 邮箱类型

  FileField: 文件上传字段

    具体属性参见

  FilePathField

  FloatField: 浮点数类型, 值为float类型

  ImageField

  IntegerField: 整数类型, 取值范围为-2147483648到2147483647

  PositiveIntegerField: 正整数类型, 取值范围为0到2147483647

  SmallIntegerField: 较短的整数, 取值范围为0到32767

  PositiveSmallIntegerField: 较短的正整数, 取值范围为-32768到32767

  GenericIPAddressField: IP地址(IPv4和IPv6都可以), 以字符串形式

  TextField: 文本类型

  SlugField: 类似CharField, 常用于URL

  URLField

  UUIDField

  其中ForeignKey表示外键引入    

3 激活模型

  根据已经创建好的模型, 就可以其创建数据库表, 并通过API进行数据操作

  (1) 首先需要修改INSTALLED_APPS

    前面也说过, Django的应用支持即插即用的特性, 因此刚才创建的model所在的应用需要添加到INSTALLED_APPS

    mysite/settings.py

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

  (2) 告诉Django对应用pools做了更改, 进而生成更改信息

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;

    可以看到:

      1) 表名是小写的

      2) 主键ID会自动添加

      3) 外键在表中的名字是 外键字段+"_id"

    此时还可以进行数据库的检查

 python manage.py check

  (3) 创建数据库表

python manage.py migrate

  这条命令会使得makemigrations生成的更改信息生效, 也就是对数据库进行修改或新增表等操作

  总结:

    迁移这条命令功能很强大

    但现目前只需要执行这三条基础操作:配置INSTALLED_APPS, makemigrations和migrate

4 利用接口操作数据库

  进入manage的shell    

python manage.py shell

  具体执行代码

# 导入
>>> from polls.models import Question, Choice # questions的内容信息
>>> Question.objects.all()
<QuerySet []> # 创建一条记录并保存
# 使用timezone.now()代替datetime.datetime.now()
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
>>> q.save() # 查看属性值
>>> q.id
1
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2017, 6, 25, 4, 1, 46, 582600, tzinfo=<UTC>) # 修改属性值并保存
>>> q.question_text = "what is your name?"
>>> q.save() # questions的内容信息
>>> Question.objects.all()
<QuerySet [<Question: Question object>]>

  显然最后我们得到的<QuerySet [<Question: Question object>]>并不友好, 不能看到确切的内容

  因此可以修改一下模型内容为

  polls/models.py

import datetime

from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils import timezone # 如果要使得__str__能够在python2生效就使用该装饰器
@python_2_unicode_compatible
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published') def __str__(self):
return self.question_text def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1) @python_2_unicode_compatible
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

  加入__str__()方法之后, 不仅可以使得在shell中输出会有更加确切的信息, 还会使得在后台管理的时候也会有效果

  同时在太Question中加入一个测试是否是最近一天发布的函数

# 导入
>>> from polls.models import Question, Choice # 查询question, 此时可以看到显示和之前不一样了
>>> Question.objects.all()
<QuerySet [<Question: what is your name?>]> # 使用filter()可以过滤查找id为1的数据
>>> Question.objects.filter(id=1)
<QuerySet [<Question: what is your name?>]>
# 使用__startwith
>>> Question.objects.filter(question_text__startswith = 'what')
<QuerySet [<Question: what is your name?>]> # 判断该question是否是今年发布
# 使用__year
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: what is your name? # 用pk(primary key的缩写)查询主键为1的question
# 相当于 Question.objects.get(id=1)
>>> Question.objects.get(pk=1)
<Question: what is your name?> # 测试一下刚才的函数
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True # 使用 引用该表作为外键的表名_set 来获取对应的外键信息(反向操作)
>>> q = Question.objects.get(pk=1)
>>> q.choice_set.all()
<QuerySet []> # 反向操作创建
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)
>>> c
<Choice: Just hacking again> # 得到的choice可以正向查看question
>>> c.question
<Question: what is your name?> # _set的操作
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3
>>> q.choice_set.filter(choice_text__startswith='Just')
<QuerySet [<Choice: Just hacking again>]> # 正向操作relationship
# 使用双下划线来分割关系, 可以递进多层都没有关系, 只要你想
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]> # 删除一波数据
>>> c = q.choice_set.get(pk=3)
>>> c
<Choice: Just hacking again>
>>> c.delete()
(1, {'TestModel.Choice': 1})
>>> q.choice_set.count()
2

  更多信息:

    相关对象

    双下划线的字段查找

    完整数据库API操作

5 Django后台管理

  1) 创建管理员

python manage.py createsuperuser

  进而输入用户名, 邮箱, 密码(有复杂性要求, 测试的时候贼烦(*`皿´*)ノ)

   2) 启动服务器

python manage.py runserver

  登录后台

http://127.0.0.1:8000/admin

  

  后台系统为

  

  3) 可以看到, 没有我们新建的应用, 此时需要手动将应用添加到系统管理

  polls/admin.py

from django.contrib import admin
from .models import Question admin.site.register(Question)

  

  进而可以对其进行一系列操作了

  

  

  如下是历史记录

  

05 - Django应用第二步的更多相关文章

  1. 05 Django与Ajax

      一.Ajax简介 AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语言与服务器进行异步交互, ...

  2. 05.Django基础五之django模型层(一)单表操作

    一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人 ...

  3. 05 django组件:contenttype

    1.django组件:contenttype 组件的作用:可以通过两个字段让表和N张表创建FK关系 1.专题课,学位课 如何关联 过期时间?? 方法1:分别创建 专题课--过期时间表 .学位课--过期 ...

  4. 05 Django之模型层---单表操作

    一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人 ...

  5. 05.django 搜索与过滤

    django-filter https://github.com/carltongibson/django-filter https://django-filter.readthedocs.io/en ...

  6. 05 Django REST Framework 分页

    01-分页模式 rest framework中提供了三种分页模式: from rest_framework.pagination import PageNumberPagination, LimitO ...

  7. 第六模块:WEB框架开发 第1章·Django框架开发1~50

    01-Django基础介绍 02-Web应用程序1 03-Web应用程序2 04-http请求协议1 05-http请求协议2 06-http协议之响应协议 07-wsgire模块1 08-wsgir ...

  8. Django数据库的查看、删除,创建多张表并建立表之间关系

    配置以下两处,可以方便我们直接右键运行tests.py一个文件,实现对数据库操作语句的调试: settings里面的设置: #可以将Django对数据库的操作语法,能输出对应的的sql语句 LOGGI ...

  9. django uWSGI nginx搭建一个web服务器 确定可用

    网上的找了很多篇 不知道为什么不行,于是自己搭建了一个可用的Web 大家可按步骤尝试 总结下基于uwsgi+Nginx下django项目生产环境的部署 准备条件: .确保有一个能够用runserver ...

随机推荐

  1. 【BZOJ4128】Matrix BSGS+hash

    [BZOJ4128]Matrix Description 给定矩阵A,B和模数p,求最小的x满足 A^x = B (mod p) Input 第一行两个整数n和p,表示矩阵的阶和模数,接下来一个n * ...

  2. 【BZOJ4184】shallot 线段树+vector+线性基

    [BZOJ4184]shallot Description 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏. 每个时刻她会给小葱一颗小葱苗或者是从 ...

  3. This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its 错误解决办法

    This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary log ...

  4. iOS NSError HTTP错误码大全

    NSError codes in the Cocoa error domain. enum { NSFileNoSuchFileError = 4, NSFileLockingError = 255, ...

  5. "ORA-01012: not logged on"以及"Connected to an idle instance."解决思路

    今天测试用的ORACLE服务器出现卡顿情况,于是准备重启一下,在运行shutdown指令关闭数据库的时候意外断开连接,后面想再次进入ORACLE服务器启动时便遇见如下报错: 使用sqlplus /no ...

  6. Delphi窗体研究,留个爪,以后回来研究

    Delphi - 窗体创建过程   来自大富翁. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ...

  7. centos安装 Falcon+

    1:环境 准备 : 安装 go环境 :下载 - Golang中国 参照 :http://www.cnblogs.com/Amos-Turing/p/8494250.html 安装 mysql 安装 r ...

  8. python __nonzero__方法

    类的nonzero方法用于将类转换为布尔值.通常在用类进行判断和将类转换成布尔值时调用.比如语句if A: print 'foo'中就会调用A.nonzero()来判断.下面这个程序应该能帮助你理解n ...

  9. windows中检查端口占用

    在cmd中怎么输入netstat -aon|findstr "9080" 返回: UDP  0.0.0.0:8001   *.* 其中的4220为进城PID

  10. mysql查询当天,本周,本月,上一个月的数据(转)

    今天 select * from 表名 where to_days(时间字段名) = to_days(now()); 昨天 SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ...