Django——Model的使用
Model使用
首先安装MySQL的python连接驱动,windows下安装可下下载,对应python-2.7:
https://code.google.com/p/soemin/downloads/detail?name=MySQL-python-1.2.3.win32-py2.7.exe&can=2&q=
简单的,先展示在view中使用mysql数据库操作
from django.shortcuts import render_to_response
import MySQLdb
def book_list(request):
db = MySQLdb.connect(user='me', db='mydb', passwd='secret', host='localhost')
cursor = db.cursor()
cursor.execute('SELECT name FROM books ORDER BY name')
names = [row[0] for row in cursor.fetchall()]
db.close()
return render_to_response('book_list.html', {'names': names})
from django.shortcuts import render_to_response
import MySQLdb
def book_list(request):
db = MySQLdb.connect(user='me', db='mydb', passwd='secret', host='localhost')
cursor = db.cursor()
cursor.execute('SELECT name FROM books ORDER BY name')
names = [row[0] for row in cursor.fetchall()]
db.close()
return render_to_response('book_list.html', {'names': names})
以上的做法比较原始,也有一些弊端:
1. 硬编码数据库连接参数,理想情况下,这些应该放到配置文件中去
2. 固定流程,总是打开连接,创建游标,关闭连接这几步,重复代码太多
3. 绑定mysql数据库,如果要切换别的数据库,修改太多了,要改连接参数,没准SQL语句也要修改
而Django数据库API就是为了解决以上问题而生。
from django.shortcuts import render_to_response
from mysite.books.models import Book
def book_list(request):
books = Book.objects.order_by('name')
return render_to_response('book_list.html', {'books': books})
from mysite.books.models import Book
def book_list(request):
books = Book.objects.order_by('name')
return render_to_response('book_list.html', {'books': books})
首先要在settings.py文件进行数据库的设定
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'test', # 数据库名称,如果使用sqlite3,则输入数据库文件路径,如'/home/django/mydata.
'USER': 'root', # Not used with sqlite3.
'PASSWORD': 'admin', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
一旦设置好数据库信息,可以使用python manage.py shell进行测试
>>> from django.db import connection
>>> cursor = connection.cursor()
如果不报错,则说明配置正常。
下面简单介绍一下project和app之间的区别:
1. project是一系列app集合的一个实例,外加对这些app的配置信息。
确切地说,project只需要提供一个配置文件,包括数据库连接信息,所安装的app的列表,模板路径等等
2. app是一系列Django提供的功能的可重用的集合,一般包括在同一个包中的modesl, views。
例如,一个Django project可以由很多个app组成,如一个评论系统,一个后台管理系统等,所有这些app
都可以在不同的project中重用,是独立的,当然也要看你的设计了。。。
然而app不是非要不可的,view+template+urlconf就足可以组建project,但是为了追求可重用性,以及想使用
Django强大的database level api--model,就一定要创建app,使用以下命令:
python manage.py startapp books
有人认为在python中重新定义一个数据表中的字段信息,是不是有点冗余,如果直接使用数据库本身的自省操作
在运行时,来确定数据模型的话,是不是更方便?
答案是错误的,
1. 后者因为是在运行时,如果每一个请求都在去自省一下数据库的表结构,这样就会产生额外的开销,
给系统造成负担。
2. 再者,把表结构写在python代码,容易管理和操作。
3. 然后,数据库中的数据类型比较单一,而Django中的数据类型丰富,比如邮件地址类型,网址类型等,
都可以提高生产力。。。
用python代码来表示数据表信息的做法有一个缺点就是一定要保持和数据库表信息一致,如果一方修改,
都需要进行修改。
使用model的一般步骤:
1. 在app的models文件中创建model子类
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()
2. 然后在settings.py中注册你的app
MIDDLEWARE_CLASSES = (
# 'django.middleware.common.CommonMiddleware',
# 'django.contrib.sessions.middleware.SessionMiddleware',
# 'django.contrib.auth.middleware.AuthenticationMiddleware',
)
INSTALLED_APPS = (
# 'django.contrib.auth',
# 'django.contrib.contenttypes',
# 'django.contrib.sessions',
# 'django.contrib.sites',
'books', #注意加上这个逗号来区分元组类型,同时记得是要用引号。。。
)
3. 可以使用命令来验证你的设置,0 errors代表正确
python manage.py validate
4. 通过model类定义来创建数据库表,可以使用命令:
python manage.py sqlall books #打印出创建相应的数据表的SQL语句
python manage.py syncdb #直接执行SQL语句,只用来检查是否表存在,如果没有,就创建新的表,
如果model中的数据有改动,这一句执行就没有用。
5. 使用model进行简单的数据表插入操作,Django直到save()才是真正地写入数据库。
python manage.py shell
>>> from books.models import Publisher
>>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue',
... city='Berkeley', state_province='CA', country='U.S.A.',
... website='http://www.apress.com/')
>>> p1.save()
使用manager进行查询
>>> publisher_list = Publisher.objects.all() #Publisher.objects返回的就是一个管理器
>>> publisher_list
[<Publisher: Publisher object>, <Publisher: Publisher object>]
这样就可以进行取出记录数据的操作,或者是你自己定义的其它逻辑操作
>>> publisher_list[0].address
u'2855 Tele Avenur'
如果想直接写入数据库,不用save(),则使用管理器的create()方法
>>> p1 = Publisher.objects.create(name='Apress',
... address='2855 Telegraph Avenue',
... city='Berkeley', state_province='CA', country='U.S.A.',
... website='http://www.apress.com/')
6. 在model的类中,增加__unicode__()函数,来代表各个类的字符串表示信息。相当于java中的toString()
def __unicode__(self):
return self.name
>>>[<Publisher: Apress>, <Publisher: O'Reilly>]
7. 更新的操作,就是简单的赋个新值,再save()一下
不过这样做效率一般,manager有update函数专门用于更新操作
>>> Publisher.objects.filter(id=52).update(name='Apress Publishing')
8. 条件选择操作,使用manager中的filter函数,返回的是QuerySet对象,类似结果集对象
>>> Publisher.objects.filter(name='Apress')
[<Publisher: Apress>]
更复杂的条件选择操作,是使用Django特有的lookup type修饰词来实现
>>> Publisher.objects.filter(name__contains="press")
[<Publisher: Apress>]
__contains:类似SQL语句中的like的模糊匹配操作:
WHERE name LIKE '%press%';
如果想获取单一的对象,使用get()函数,如果返回的对象有多个,就报错MultipleObjectsReturned。
如果返回值为空,也报错DoesNotExist。
>>> a = Publisher.objects.get(name="Apress")
>>> a
<Publisher: Apress>
>>> a.address
u'2855 Tele Avenur'
也可以进行取出记录数据的相应操作,就相当于取出了一个Publisher记录的对象。
9. 排序操作
>>> Publisher.objects.order_by("state_province", "address")
[<Publisher: Apress>, <Publisher: O'Reilly>]
>>> Publisher.objects.order_by("-name") #'-'表示倒序
QuerySet也可以像列表那样用索引取值
Publisher.objects.order_by("address")[1]
但是不支持负数
Publisher.objects.order_by("address")[-1]
不过可以用倒序来表示:
Publisher.objects.order_by("-address")[0]
10. 删除记录操作
对于单个model类或者是QuerySet类都有对应的delete()函数
>>> p = Publisher.objects.get(name="O'Reilly")
>>> p.delete()
>>> Publisher.objects.filter(country='USA').delete()
>>> Publisher.objects.all().delete()#如果要清空数据表,一就要显示地调用all(),再delete