课前补充: 1. 虚拟环境的账号不要用 root 账号链接虚拟机
1. 数据库的连接配置
django 连接 MySQL 的配置流程:
- 进入虚拟环境, 安装 MySQL
pymysql pip install pymysql
- 创建数据库用户
有创建数据库权限的用户
例如: 创建一个管理员用户 crm 账号, 密码为 crm@python
CREATE USER 'crm'@'%'IDENTIFIED BY 'crm@python';
给这个用户授予所有远程访问, 这个用户主要用于管理整个数据库, 备份, 还原等操作.
GRANT ALL ON *.* TO 'crm'@'%';
使授权立即生效:
FLUSH PRIVILEGES;
- 创建数据库 crm
create database crm;
- 修改配置
- settings.py(我连接使用的是 root 用户, 用什么用户能连接上就行)
- DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.mysql', #引擎
- 'NAME': 'crm',
- 'USER': 'root',
- 'PASSWORD': 'qwe123',
- 'HOST': '127.0.0.1',
- 'PORT': '3306',
- }
- }
- 修改项目文件夹 (和 settings.py 文件所在的目录) 下
__init__.py 文件(如果导入不行, 先退出 pycharm 项目, 重新进入)
- import pymysql
- pymysql.install_as_MySQLdb()
settings.py 设置时区
TIME_ZONE = 'Asia/Shanghai' # 北京时间
2.django 的 ORM 系统
- 对象关系映射(Object Relational Mapping, 简称 ORM)!
简单的说就是用面向对象的方式, 描述数据库, 操作数据库,
达到不用编写 SQL 语句就能对数据库进行增删改查.
3. 模型的创建与激活
创建模型
Student 的模型, 代表学生
- from django.db import models
- # Create your models here.
- class Student(models.Model): #继承自 Modle 模型会自动创建主键
- name = models.CharField(max_length=20) #姓名 字符字段(CharField) 必须参数 max_length
- age = models.SmallIntegerField(default=0) #年龄 SmallInterField default(默认值)
- sex = models.SmallIntegerField(default=1) #性别
- qq = models.CharField(max_length=20,unique=True,null=True)
- phone = models.CharField(max_length=20,unique=True,null=True)
- #删除年级的时候不必把学生都删除, 必须可以设置年级字段为 null,on_delete=models.SET_NULL,null=True
- grade = models.ForeignKey('Grade',on_delete=models.SET_NULL,null=True)
- c_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True) #时间日期型, verbose_name 提示信息, 如果有这个参数必须写在第一个参数位置
- e_time = models.DateTimeField(verbose_name='编辑时间',auto_now=True) #auto_now_add 创建对象额时候讲当前时间记录到数据库 auto_now 每次更新都会将时间更新
- is_deleted = models.BooleanField(default=False)
- def __str__(self): #输出友好, 重写__str__方法, 添加这一段对数据库不造成任何影响, 不用做数据库迁移
- return '%s-%s-%s' %(self.id,self.name,self.age)
总结:
1. 每一个模型都是 django.db.models.Model 的子类
2. 类变量 表示模型中的数据库字段
3. 每一个字段由一个字段类的实例表示
激活模型
1. 在项目中注册 App, 在 settings.py
- INSTALLED_APPS = [
- 'teacher', #添加项目名称到 INSTALLED_APPS 中
- 'django.contrib.admin',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.messages',
- 'django.contrib.staticfiles',
- ]
2. 运行数据库迁移命令(一定要在项目根目录下)
python mange.py makemigrations teacher #可以不加 teacher, 如果不加会把 INSTALLED_APPS 中所有的 App 都做更改
告诉 django, 我们做了哪些数据库的更改
sqlmigrate 从迁移获取 sql 语句, 生成的数据库迁移文件
- python manage.py sqlmigrate teacher 000(模糊匹配)
- -- Create model Student #(与上面的定义略有不同, 只为展示上面命令的结果)
- --
- CREATE TABLE `teacher_student` (
- `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
- `name` varchar(20) NOT NULL,
- `age` smallint NOT NULL,
- `sex` smallint NOT NULL,
- `qq` varchar(20) NOT NULL,
- `phone` varchar(20) NOT NULL,
- `c_time` datetime(6) NOT NULL);
- COMMIT;
- # 表名 appname_模型 name.lower
3. 运行 migrate 命令, 使迁移生效
python manage.py migrate #(执行后, 在数据库里能够查到表)
# 对于数据库模型中的修改都要先运行数据库迁移命令 python mange.py makemigrations, 并且使迁移生效 python manage.py migrate
4. 数据的增删改查
- 工具 djang shell 调试工具
需要安装 ipython
pip install ipython
进入调试工具, 如下
- pyvip@Vip:~$ workon django
- (django) pyvip@Vip:~$ cd crm/
- (django) pyvip@Vip:~/crm$ ls
- crm db.sqlite3 demo.py manage.py static student teacher templates upload
- (django) pyvip@Vip:~/crm$ python manage.py shell
- Python 3.5.2 (default, Nov 23 2017, 16:37:01)
- Type 'copyright', 'credits' or 'license' for more information
- IPython 7.3.0 -- An enhanced Interactive Python. Type '?' for help.
- In [1]:
数据增加, 查询
- In [1]: from teacher.models import Student #从模型中导入数据库
- In [2]: Student.objects #objects 是 Student 模型类的管理器
- Out[2]: <django.db.models.manager.Manager at 0xb47e7c4c>
- In [3]: Student.objects.all()
- Out[3]: <QuerySet []> #返回查询集 QuerySet
- 增
4 种方法
1. 实例化一个对象
- In [7]: s1 = Student(name = 'aaa',age=19,qq='1234')
- In [8]: s.save() #只有调用 save()方法后才能保存到数据库
- In [10]: Student.objects.all()
- Out[10]: <QuerySet [<Student: Student object (1)>]>
2. 创建一个空的实例对象, 再通过添加对象属性
- In [11]: s2= Student()
- In [12]: s2.name ='xinlan'
- In [13]: s2.age = 18
- In [14]: s2.qq = '12312'
- In [15]: s2.save() #只有调用 save()方法后才能保存到数据库
3. 一步创建数据, 直接操作数据
- In [11]: Student.objects.create(name='xiaopo',age=16)
- Out[11]: <Student: xiaopo-16>
4. 通过 get_or_create 方法创建对象(先查, 如果没有再创建)
False 代表是查来的, True 是创建来的
- In [14]: Student.objects.get_or_create(name='xiaopo',age=16)
- Out[14]: (<Student: xiaopo-16>, False) #返回一个元组, 第一个值是一个模型对象
- In [15]: s=Student.objects.get_or_create(name='shiwei',age=16)
- In [16]: s
- Out [16]:(<Student: shiwei-16>, True)
- In [17]:s[0].name
- Out [17]:'shiwei'
- In [18]:s[0].age
- Out [18]:'16'
- 查询
- In [2]: from teacher.models import Student
- # 查询所有
- In [3]: Student.objects.all() #返回的查询集可以 for 循环, 可以迭代, 可以切片
- Out[3]: <QuerySet [<Student: aaa-19>, <Student: xinlan-18>]>
- # 查询一条
- # 使用 get 不能查询出多条, 会报错, 最好使用 (id) 主键
- In [4]: s = Student.objects.get(id=1) #返回的是对象, 不是查询集
- # 表里面的主键不一定会取名加 id, 最好写成 pk, 不管主键是什么, 都可以查到
- In [4]: s = Student.objects.get(pk=1)
- In [5]: s
- Out[5]: <Student: aaa-19>
- #filter 过滤
- In [23]: res = Student.objects.filter(sex=1)
- In [24]: print(res.query) #打印 SQL 如下
- SELECT `teacher_student`.`id`, `teacher_student`.`name`, `teacher_student`.`age`, `teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`, `teacher_student`.`c_time` FROM `teacher_student` WHERE `teacher_student`.`sex` = 1
- In [25]: res
- Out[25]: <QuerySet [<Student: aaa-19>, <Student: xinlan-18>, <Student: xiaopo-16>, <Student: shiwei-16>]>
- 2.
- In [18]: res=Student.objects.all()
- In [19]: print(res.query)
- SELECT `teacher_student`.`id`, `teacher_student`.`name`, `teacher_student`.`age`, `teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`, `teacher_student`.`c_time` FROM `teacher_student`
可以迭代, 切片
- In [21]: print(res[1:3].query)
- SELECT `teacher_student`.`id`, `teacher_student`.`name`, `teacher_student`.`age`, `teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`, `teacher_student`.`c_time` FROM `teacher_student` LIMIT 2 OFFSET 1
3. 修改, 通过对对象数据进行赋值, 修改属性
- In [27]: s2 = Student.objects.get(id=4)
- In [30]: s2.age
- Out[30]: 16
- In [31]: s2.age=22
- In [32]: s2.save()
- In [34]: Student.objects.get(name='shiwei').age
- Out[34]: 22
通过 update 修改
- In [35]: Student.objects.filter(name='shiwei').update(age=18) #匹配出来的数据全部改成 18
- Out[35]: 1
- In [37]: Student.objects.get(name='shiwei').age
- Out[37]: 18
4. 删除
- 1.
- In [38]: s= Student.objects.get(name='shiwei')
- In [39]: s.delete()
- Out[39]: (1, {
- 'teacher.Student': 1
- })
- 2.
- In [41]: Student.objects.filter(sex=1).delete()
- Out[41]: (3, {
- 'teacher.Student': 3
- })
- In [43]: Student.objects.all()
- Out[43]: <QuerySet []>
通过在创建数据库 Students 模块
- from teacher.models import Student,Grade,StudentDetail,Course,Enroll
- def index(request):
- students = Student.objects.all()
- format_str = '%Y-%m-%d %H:%M:%S'
- return render(request,'teacher/index.html',context={
- 'student':students,
- 'format_str':format_str
- })
08 django 模型系统(一)
来源: http://www.bubuko.com/infodetail-2982283.html