疯狂的暑假学习之 Django学习笔记(三)—— 模型 model
参考:《The Django Book》 第5章
1.setting.py 配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.', # 用什么数据库管理系统
'NAME': '', # 数据库名称,如果用sqlite,要写完整路径
'USER': '', # 如果用sqlite,这个不用写
'PASSWORD': '', # 如果用sqlite,这个不用写
'HOST': '', # 告诉Django连接那一台. Not used with sqlite3. 如果用sqlite也空白
'PORT': '', # 设置端口,空白就是默认,一般用默认的就行了。对于sqlite没用。
}
}
'ENGINE' 可以有:
'ENGINE' 数据库管理系统 适配器 适配器下载地址
django.db.backends.postgresql_psycopg2 PostgreSQL psycopg http://www.djangoproject.com/r/python-pgsql/.
django.db.backends.mysql MySQL MySQLdb http://www.djangoproject.com/r/python-mysql/
django.db.backends.sqlite3 SQLite
django.db.backends.oracle Oracle cx_Oracle http://www.djangoproject.com/r/python-oracle/
注意:用那个DBMS,就要安装对应DBMS的适配器。SQLite的,python默认已经装好了。
可用下面来命令测试数据库配置,如果没有显示错误信息,配置就是正确的。
>>> from django.db import connection
>>> cursor = connection.cursor()
2.创建APP
project跟APP的区别:一个是配置,一个是代码。一个project可以包含很多app以及它们的配置。一个app是一套Django功能的集合,通常包括模型和视图,按python的包结构的方式存在。
前面你可以创建app,但是如果要用模型,你就必须创建一个app。模型必须放在apps中。
创建一个“books”模型
python manage.py startapp books
它会创建一个books包,内容如下
books/
├── admin.py
├── __init__.py
├── models.py
├── tests.py
└── views.py
然后在settings.py中INSTALLED_APPS中添加 'books',
3.定义模型,模型安装
例子:
在models.py 中添加
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
Publisher模块相当于:
CREATE TABLE "books_publisher" (
"id" serial NOT NULL PRIMARY KEY,
"name" varchar(30) NOT NULL,
"address" varchar(50) NOT NULL,
"city" varchar(60) NOT NULL,
"state_province" varchar(30) NOT NULL,
"country" varchar(50) NOT NULL,
"website" varchar(200) NOT NULL
);
注意:这里没有显示的为这些模型定义任何主键。除非指明,Django会自动为每个模型生成一个自增长的单独主键 id
可以用下面的命令验证模型的有效性
python manage.py validate
可以用下面命令生成SQL语句,它这只是生成SQL语句,不会执行
python manage.py sqlall books
如果想执行,执行下面语句(这个语句,在里添加新的模型或者app时才有用,修改删除模型syncdb不会做出任何反应)
python manage.py syncdb
4.数据库操作
(1)数据库插入,显示
>>> from books.models import *
>>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue',
... city='Berkeley', state_province='CA', country='U.S.A.',
... website='http://www.apress.com/')
>>> p1.save()
>>> p2 = Publisher(name="O'Reilly", address='10 Fawcett St.',
... city='Cambridge', state_province='MA', country='U.S.A.',
... website='http://www.oreilly.com/')
>>> p2.save()
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Publisher object>, <Publisher: Publisher object>]
单单的p1=Publisher(...) 不会插入,必须要p1.save() 后才会真正生效
如果想一次性完成插入执行下面的命令
>>> from books.models import *
>>> p1 = Publisher.objects.create(name='Apress',
... address='2855 Telegraph Avenue',
... city='Berkeley', state_province='CA', country='U.S.A.',
... website='http://www.apress.com/')
>>> p2 = Publisher.objects.create(name="O'Reilly",
... address='10 Fawcett St.', city='Cambridge',
... state_province='MA', country='U.S.A.',
... website='http://www.oreilly.com/')
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Publisher object>, <Publisher: Publisher object>]
Publisher.objects.all()相当于 select
在输入publisher_list时,返回的对象名字都一样,不好分辨,解决方法就是,在模板类中添加__unicode__() 方法
如:
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __unicode__(self):
return self.name
这样重新启动,输入下面命令,就可以分辨出来。
>>> from books.models import Publisher
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Apress>, <Publisher: O'Reilly>]
(2)数据库更新
例子:
>>> p = Publisher(name='Apress',
... address='2855 Telegraph Ave.',
... city='Berkeley',
... state_province='CA',
... country='U.S.A.',
... website='http://www.apress.com/')
>>> p.save()
>>> p
<Publisher: Apress>
>>> p.id
3
>>> p.name = 'Apress Publishing'
>>> p.save()
>>> p
<Publisher: Apress Publishing>
注意:下面这样是更行不了的
>>> Publisher.objects.all()[0].name='AAAAAA'
>>> Publisher.objects.all()[0].save()
>>> Publisher.objects.all()[0]
<Publisher: Apress Publishing>
得要这样更新
>>> p = Publisher.objects.get(name='Apress')
>>> p
<Publisher: Apress>
>>> p.name = 'Apress Publishing'
>>> p.save()
>>> p
<Publisher: Apress Publishing>
上面的更行方法,用l了save(),这样不管有没有改过的数据,都会更行。可以用update(...),它只会更新要改的
>>> Publisher.objects.filter(id=1).update(name='Apress')
1
>>> Publisher.objects.all()
[<Publisher: Apress>, <Publisher: O'Reilly>]
但是update(),对结果集(QuerySet)有效,get(),[0],无效
如下面的命令会报错
>>> Publisher.objects.get(id=1).update(name='Apress')
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Publisher' object has no attribute 'update'
(3)选择对象
Publisher.objects.all()显示所有对象
>>> Publisher.objects.all()
[<Publisher: Apress>, <Publisher: O'Reilly>]
Publisher.objects.filter(name='Apress')
Publisher.objects.filter(...) 筛选
>>> Publisher.objects.filter(name='Apress')
[<Publisher: Apress>]
filter(...) 可以有多个参数,相当与SQL中的AND
>>> Publisher.objects.filter(country="U.S.A.",state_province="CA")
[<Publisher: Apress>]
如果想使用SQL中的 LIKE 查询,要用 XX__contains
>>> Publisher.objects.filter(name__contains="press")
[<Publisher: Apress>]
name__contains="press" 相当与 LIKE “%press%”
(4)获取单个对象
filter 只要满足条件的都会输出
获取单个对象用get
>>> Publisher.objects.get(name='Apress')
<Publisher: Apress>
如果满足的不止一个会有异常,如果没有会抛出DoesNotExist异常
>>> Publisher.objects.get(country='U.S.A.')
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/lib64/python2.7/site-packages/django/db/models/manager.py", line 151, in get
return self.get_queryset().get(*args, **kwargs)
File "/usr/lib64/python2.7/site-packages/django/db/models/query.py", line 310, in get
(self.model._meta.object_name, num))
MultipleObjectsReturned: get() returned more than one Publisher -- it returned 2!
(5)数据库排序
用order_by
>>> Publisher.objects.order_by("name")
[<Publisher: Apress>, <Publisher: O'Reilly>]
倒叙,只需要,加上“-”
>>> Publisher.objects.order_by("-name")
[<Publisher: O'Reilly>, <Publisher: Apress>]
(6)连锁查询
例子:
>>> Publisher.objects.filter(country="U.S.A.").order_by("-name")
[<Publisher: O'Reilly>, <Publisher: Apress>]
(7)限制返回查询
例子:
>>> Publisher.objects.order_by("-name")[0]
<Publisher: O'Reilly>
>>> Publisher.objects.order_by("-name")[0:2]
[<Publisher: O'Reilly>, <Publisher: Apress>]
(8)删除对象
用 delete()
>>> Publisher.objects.all()
[<Publisher: Apress>, <Publisher: O'Reilly>]
>>> Publisher.objects.filter(name='Apress').delete()
>>> Publisher.objects.all()
[<Publisher: O'Reilly>]
删除所有对象
>>> Publisher.objects.all().delete()
>>> Publisher.objects.all()
[]