django模型

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

一、PRoject 与app之间的关系

1个project中可包含多个app

eg:包含两个app的project的结构

project:存放对各个app的配置

app:真正的业务代码,包含models和views,以package的形式存在,

容易完整移植到其他project,从而被多个project复用

二、用python代码定义表结构

1、python通过models实现create table的操作:

fromdjango.dbimportmodelsclassBook(models.Model):

name= models.CharField(max_length=50)

pub_date= models.DateField()

2、python代码定义表结构的好处

1)无需考虑不同数据库平台的兼容性问题,无论是MySQL,mongodb,redis

从python代码create table的方式都是一样的

2)开发者专注于python代码,不用再去写sql,减轻大脑负担

3)django框架中有特定的数据类型, eg:email类型,url类型

4)性能考虑:不用每次系统启动或者发起请求都要先检查一下数据库结构,而是

可以根据python代码就知道了目标数据库的结构。

3、缺点

每次修改了python数据库结构后,需要手动修改数据库中的表结构

三、测试models在django中的使用

1、基本准备

1)创建django project和app

2)修改settings.py中的基本设置

模板位置:

TEMPLATE_DIRS =(

os.path.join(BASE_DIR,'templates'),

)

数据库连接:

DATABASES ={'default': {'ENGINE':'django.db.backends.mysql','NAME':'django_db','USER':'root','PASSWord':'feng','HOST':'127.0.0.1','PORT':'3306',

}

}

仅安装当前使用的app:

INSTALLED_APPS =(#'django.contrib.admin',#'django.contrib.auth',#'django.contrib.contenttypes',#'django.contrib.sessions',#'django.contrib.messages',#'django.contrib.staticfiles','model_test_app',

)

MIDDLEWARE_CLASSES=(#'django.contrib.sessions.middleware.SessionMiddleware',#'django.middleware.common.CommonMiddleware',#'django.middleware.csrf.CsrfViewMiddleware',#'django.contrib.auth.middleware.AuthenticationMiddleware',#'django.contrib.messages.middleware.MessageMiddleware',#'django.middleware.clickjacking.XFrameOptionsMiddleware',)

执行ctrl+r+syndbc时,只会根据INSTALLED_APPS设置的app来检查

对应的数据库表是否存在,其他没有设置的app不会被检查。

3)此时数据库中的状态(之前有过其他project的测试数据)

2、通过models.py定义表结构

1)models.py中录入以下代码:

fromdjango.dbimportmodelsclassPublisher(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()classAuthor(models.Model):

first_name= models.CharField(max_length=30)

last_name= models.CharField(max_length=40)

email=models.EmailField()classBook(models.Model):

title= models.CharField(max_length=100)

authors=models.ManyToManyField(Author)

publisher=models.ForeignKey(Publisher)

publication_date= models.DateField()

以上python定义表结构涉及到的知识点:

a)字段类型:

字符串类型,URL类型,Email类型,Date类型

b)多对多关系:

authors=models.ManyToManyField(Author)

c)外键:

publisher=models.ForeignKey(Publisher)

d)关于主键:

无需显式指明主键,django会自动为每个模型生成一个自增的整数id作为主键

2)通过python在数据库中创建表:

a)检查model的语法和逻辑是否正确:ctrl+r+validate

b)生成建表的sql语句:ctrl+r+sql

"D:\DevPlatform\PyCharm 3.1.3\bin\runnerw.exe"C:\Python27\python.exe"D:\DevPlatform\PyCharm 3.1.3\helpers\pycharm\django_manage.py"sql model_test_app D:/ProgramData/python/model_test

BEGIN;

CREATE TABLE `model_test_app_publisher` (

`id` integer AUTO_INCREMENT 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

)

;

CREATE TABLE `model_test_app_author` (

`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,

`first_name` varchar(30) NOT NULL,

`last_name` varchar(40) NOT NULL,

`email` varchar(75) NOT NULL

)

;

CREATE TABLE `model_test_app_book_authors` (

`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,

`book_id` integer NOT NULL,

`author_id` integer NOT NULL,

UNIQUE (`book_id`, `author_id`)

)

;

ALTER TABLE `model_test_app_book_authors` ADD CONSTRAINT `author_id_refs_id_206f10ad` FOREIGN KEY (`author_id`) REFERENCES `model_test_app_author` (`id`);

CREATE TABLE `model_test_app_book` (

`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,

`title` varchar(100) NOT NULL,

`publisher_id` integer NOT NULL,

`publication_date` date NOT NULL

)

;

ALTER TABLE `model_test_app_book` ADD CONSTRAINT `publisher_id_refs_id_f51d29ce` FOREIGN KEY (`publisher_id`) REFERENCES `model_test_app_publisher` (`id`);

ALTER TABLE `model_test_app_book_authors` ADD CONSTRAINT `book_id_refs_id_6f49ea9b` FOREIGN KEY (`book_id`) REFERENCES `model_test_app_book` (`id`);

COMMIT;

Process finished with exit code 0

此处多生成了一张表:model_test_app_book_authors,用于描述多对多关系

c)同步sql语句到数据库: ctrl+r+syncdb

运行之后数据库中的情况:

说明:1、实际上可以修改自动生成表名的规则

2、重复执行ctrl+r+syndbc是安全的,不会生成重复的表也不会冲掉旧数据

3、只会根据INSTALLED_APPS设置的app来检查对应的数据库表是否存在

3、基本数据访问

views.py

#coding:utf-8fromdjango.shortcutsimportrenderfromdjango.shortcutsimportrender_to_responsefrommodel_test_app.modelsimportPublisher#Create your views here.defdb_op(request):#删除#Publisher.objects.filter(name='Apress').delete()Publisher.objects.all().delete()#新增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.objects.create(name="O'Reilly",

address='10 Fawcett St.', city='Cambridge',

state_province='MA', country='U.S.A.',

website='http://www.oreilly.com/')#更新pub=Publisher.objects.get(name='Apress')

pub.country='China'pub.save()#查询publisher_list =Publisher.objects.all()forpublisherinpublisher_list:printpublisher.name,publisher.countryreturnrender_to_response('db_op.html', locals())

db_op.html:

<!DOCTYPE html><html><head><title>数据库操作</title></head><body><p>操作结果:</p><p><ul>{% for publisher in publisher_list %}<li>{{ publisher.name }}, {{publisher.country}}</li>{% endfor %}</ul></p></body></html>

执行结果:

页面:

后台输出:

4、模型中的__unicode__()方法:

用于自定义输出“模型”的字符串内容,类似于java中的toString方法

views.py中的输出操作:

defdb_op(request):#查询publisher_list =Publisher.objects.all()printpublisher_listreturnrender_to_response('db_op.html', locals())

未添加__unicode__()方法时:

增加了__unicode__()方法时:

fromdjango.dbimportmodelsclassPublisher(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.namedef__unicode__(self):returnu'%s, %s'%(self.name,self.country)

5、关于update操作中的p.save()

并不是只更新修改过的那个字段,所有的字段都会被更新

6、django中实现where条件

1)查询中对字段进行过滤

defdb_op(request):#查询publisher_list = Publisher.objects.filter(name='Apress',country='China')printpublisher_listreturnrender_to_response('db_op.html', locals())

执行结果:

2)like关键词在django中的实现

defdb_op(request):#查询publisher_list = Publisher.objects.filter(name__contains='eil')#publisher_list = Publisher.objects.all()printpublisher_listreturnrender_to_response('db_op.html', locals())

相当于:where name like '%eil%'

执行结果:

3)get方法获取单条记录:

a)恰好返回1条记录时

defdb_op(request):try:

pub=Publisher.objects.get(name__contains='eil')except:print'获取单条记录发生异常'else:printpub.namereturnrender_to_response('db_op.html', locals())

b)返回两条记录时

defdb_op(request):try:

pub=Publisher.objects.get(name__contains='e')except:print'获取单条记录发生异常'else:printpub.namereturnrender_to_response('db_op.html', locals())

c)没有记录返回时

defdb_op(request):try:

pub=Publisher.objects.get(name__contains='eeeeeee')except:print'获取单条记录发生异常'else:printpub.namereturnrender_to_response('db_op.html', locals())

4)排序

defdb_op(request):#升序publisher_list=Publisher.objects.order_by("name","country")printpublisher_list#降序publisher_list2=Publisher.objects.order_by("-name","country")printpublisher_list2returnrender_to_response('db_op.html', locals())

执行结果:

模型中指定默认排序规则:

classPublisher(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):returnu'%s, %s'%(self.name,self.country)classMeta:

ordering= ['-name']

defdb_op(request):

publisher_list=Publisher.objects.all()printpublisher_listreturnrender_to_response('db_op.html', locals())

执行结果:

5)where和order by同时使用

defdb_op(request):

publisher_list=Publisher.objects.filter(name="Apress").order_by("name")printpublisher_listreturnrender_to_response('db_op.html', locals())

6)limit的实现

defdb_op(request):#返回单个记录pub=Publisher.objects.order_by("name")[0]printpub#返回记录列表publisher_list=Publisher.objects.order_by("name")[0:100]printpublisher_listreturnrender_to_response('db_op.html', locals())

执行结果:

7)更新记录中的某些字段,而不是所有字段

使用结果集QuerySet的update()方法,而不是p.save()

defdb_op(request):#返回记录列表affectRowCount=Publisher.objects.filter(name__contains='e').update(country='Japan')printaffectRowCount

publisher_list=Publisher.objects.all()printpublisher_listreturnrender_to_response('db_op.html', locals())

执行结果:

8)删除一些记录,而不是单条记录

使用 使用结果集QuerySet的delete()方法,而不是先get单条p,再p.delete()

defdb_op(request):#返回记录列表affectRowCount=Publisher.objects.filter(name='Apress').delete()printaffectRowCount

publisher_list=Publisher.objects.all()printpublisher_listreturnrender_to_response('db_op.html', locals())

执行结果:

ps:不会返回被删除的行数

参考:http://djangobook.py3k.cn/2.0/chapter05/

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航