ORM + Mysql配置
学习博客:http://www.cnblogs.com/yuanchenqi/articles/7552333.html#_label2
http://www.cnblogs.com/yuanchenqi/articles/7629939.html#_label2
Terminal中创建app
命令 python manage.py startapp app02 (然后setting中配置)---数据库
1、cmd 创建数据库
mysql -uroot -p create database ***
2、diango settints.py 配置数据库相关
DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), # } 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'day', 'USER':'root', 'PASSWORD':'123456', 'HOST':'127.0.0.1', 'PORT':3306, } }
3、项目下 __init__ 告诉项目使用的数据库 (只有一个app 也可以写在app下__init__)
import pymysql pymysql.install_as_MySQLdb()
4、models.py 创建表
from django.db import models # 利用一个中间模块 帮助我们连接数据库,写SQL语句,执行SQL语句,拿到结果 # 出版社表 class Publisher(models.Model): id = models.IntegerField(primary_key=True) name = models.CharField(max_length=32) address = models.CharField(max_length=32,null=True) # default="北京"
5、神奇的命令:(注意顺序) models.py
python manage.py makemigrations
python manage.py migrate
4 、models.py
4.1 字符串类(以下都是在数据库中本质都是字符串数据类型,此类字段只是在Django自带的admin中生效)
name=models.CharField(max_length=32)
EmailField(CharField):
IPAddressField(Field)
URLField(CharField)
SlugField(CharField)
UUIDField(Field)
FilePathField(Field)
FileField(Field)
ImageField(FileField)
CommaSeparatedIntegerField(CharField)
models.CharField 对应的是MySQL的varchar数据类型
char 和 varchar的区别 :
char和varchar的共同点是存储数据的长度,不能 超过max_length限制,
不同点是varchar根据数据实际长度存储,char按指定max_length()存储数据;所有前者更节省硬盘空间;
4.2、时间字段
models.DateTimeField(null=True)
date=models.DateField()
4.3、数字字段 (max_digits=30,decimal_places=10)总长度30小数位 10位
num = models.IntegerField() num = models.FloatField() 浮点 price=models.DecimalField(max_digits=8,decimal_places=3) 精确浮点
4.4、枚举字段
choice=( (1,'男人'), (2,'女人'), (3,'其他') ) lover=models.IntegerField(choices=choice) #枚举类型
4.5、其他字段
db_index = True 表示设置索引 unique(唯一的意思) = True 设置唯一索引 联合唯一索引 class Meta: unique_together = ( ('email','ctime'), ) 联合索引(不做限制) index_together = ( ('email','ctime'), ) ManyToManyField(RelatedField) #多对多操作
ORM操作 (http://www.cnblogs.com/liwenzhou/p/8660826.html#top)
1. 增加
Student.objects.create(name="www",age=21) # 创建了一个Student对象 insert into student(name) values("www") # 如果是数据是字典,使用**打散字典再传入。
2. 删除
obj.delete()
3. 改 (一定要赋值给obj,图片写法错误)
obj.name = "新的值" obj.save() 提交到数据库
4. 查 (可以使用python console 进行测试,from app.models import * )
4.0 简单API
<1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个, 如果符合筛选条件的对象超过一个或者没有都会抛出错误。 <5> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 <4> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列 <9> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 <6> order_by(*field): 对查询结果排序 <7> reverse(): 对查询结果反向排序 <8> distinct(): 从返回结果中剔除重复纪录 <10> count(): 返回数据库中匹配查询(QuerySet)的对象数量。 <11> first(): 返回第一条记录 <12> last(): 返回最后一条记录 <13> exists(): 如果QuerySet包含数据,就返回True,否则返回False
4.1基于对象查询(sql子查询) (学习博客:http://www.cnblogs.com/yuanchenqi/articles/7552333.html#_label3)
author 1对1 authordetail
多对多多
book 多对1 publish
一对一:
正向查询:用字段 反向查询:表名小写
一对多:
正向查询:用字段 反向查询:表名小写_set
多对多:
正向查询:用字段 反向查询:表名小写_set
代码
一对一: 正向查询:用字段 反向查询:表名小写 author_obj=author.objects.filter(name="alex").first() author_obj.authordetail.telephone authordetail_obj=authordetail.objects.filter(addr="烟台").first() # !!! authordetail_obj.author.得到一个对象,不是对象集合 authordetail_obj.author.name # !!!不可以authordetail_obj.author.all() 一对多: 正向查询:用字段 反向查询:表名小写_set book_obj=book.objects.filter(nid=2).first() book_obj.publish.email publish_obj=publish.objects.filter(name="橘子出版社").first() publish_obj.book_set.all().values("title") 多对多: 正向查询:用字段 反向查询:表名小写_set book_obj=book.objects.filter(title="python").first() book_obj.authors.all().values("name") obj=author.objects.filter(name="alex").first() obj.book_set.all()
4.2 基于queryset和__双下划线查询(join查询)
正向查询,按字段 反向查询,表名小写__字段 ( 不区分1对1 ,1对多,多对多)
(1)查nid=2 的书对应的出版社邮箱 # book.objects.filter(nid=2).values("title","price") book.objects.filter(nid=2).values("publish__email") (2)橘子出版社出版过的所有的书籍的名字 publish.objects.filter(name="橘子出版社").values("book__title") (3)查询金 所有作者的名字 book.objects.filter(title="金").values("authors__name") (4)查询alex出版的书籍个数 author.objects.filter(name="alex").values("book__title").count() (5)查alex的手机号 author.objects.filter(name="alex").values("authordetail__telephone") (6)住在烟台的作者的名字 authordetail.objects.filter(addr="烟台").values("author__name")
4.3分组查询 正向查询,按字段 反向查询,表名小写__字段 ( 不区分1对1 ,1对多,多对多)
from django.db.models import Count,Avg # 每一个出版社的名字以及出版的对应书籍的个数 Publish.objects.all().annotate(c=Count("book__title")) # 还是Publish的query_set对象, 只是多了c字段 Publish.objects.all().annotate(c=Count("book__title")).values("name",c) # 每一个作者的名字以及对应的书籍的平均价格 Author.objects.all().annotate(a=Avg("book__price")).values("name",a) 单表分组查询: select 哪个字段就按照哪个字段进行GROUP BY # 查每一个部门的平均工资 emp.objects.values("dep").annotate(avg=Avg("salary")).values("dep","avg")
values values_list 返回结果不同
[{ 'dname': u'ACCOUNTING'} , { 'dname': u'RESEARCH'} , { 'dname': u'SALES'} , { 'dname': u'OPERATIONS'} , { 'dname': u'Test'} , { 'dname': u'OPS'}] [( u'ACCOUNTING', 10L) , ( u'RESEARCH', 20L) , ( u'SALES', 30L) , ( u'OPERATIONS', 40L) , ( u'Test', 42L) , ( u'OPS', 43L)]
通过logging可以查看翻译成的sql语句,settints.py配置
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }
----------------------------------------------------------
模版语言
<tbody>
{% for i in publisher_list %}
<tr>
<td>{{ i.id }}</td>
<td>{{ i.name }}</td>
</tr>
{% endfor %}
</tbody>