好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Django中的模型与数据库(Modelsanddatabase)

Django中的模型与数据库(Models and database) 对于数据库大家都不陌生,但是Models该怎么理解,官方文档中有这么一句话: A model is the single, definitive source of data about your data. It contains the essential fields and behaviors of thedata yo

Django中的模型与数据库(Models and database)

对于数据库大家都不陌生,但是Models该怎么理解,官方文档中有这么一句话:
A model is the single, definitive source of data about your data. It contains the essential fields and behaviors of thedata you’re storing. Generally, each model maps to a single database table.

下文暂且称Models为“模型”(个人叫法)

那么,模型具备以下三个特征:

每一个模型都是一个python子类。继承django.db.models.Model模型的每一个属性代表一个数据库字段除了上述之外,jango还提供了自动生成数据库访问的API为了方便理解我们举个例子下面这个例子我们建立了一个Person的模型,且有两个字段)first_name,last_name

  from  django.db  import  models
  class   Person  (models.Model) : 
    first_name = models.CharField(max_length= 30 )
    last_name = models.CharField(max_length= 30 )

first_name和last_name是Person模型的Field,每一个Field都是一个指定的类的属性,每一个属性映射到数据库的没一列  

这里我就有一个疑问,到底Field能不能称为字段?

 上面的Person模型将会对应一张这样的数据库表:

CREATE TABLE myapp_person (
     "id"  serial NOT NULL PRIMARY KEY,
     "first_name"  varchar( 30 ) NOT NULL,
     "last_name"  varchar( 30 ) NOT NULL
);

下面我们聊聊使用,一旦你声明了一个models,你需要去告诉jango你将会去使用该models,在你的settings里把你的

应用名加到INSTALLED_APPS中

INSTALLED_APPS = (
 #... 
’myapp’,
 #... 
)
当你在INSTALLED_APPS添加新应用后,需要执行manage.py migrate   

接下来我们再来说说Fields

 它是模型的重要的一部分,它定义了数据库表的字段

 from  django.db  import  models
  class   Musician  (models.Model) : 
    first_name = models.CharField(max_length= 50 )
    last_name = models.CharField(max_length= 50 )
    instrument = models.CharField(max_length= 100 )
      class   Album  (models.Model) : 
    artist = models.ForeignKey(Musician)
    name = models.CharField(max_length= 100 )
    release_date = models.DateField()
    num_stars = models.IntegerField()

模型中每一个field是一个Field类实例,jango通过Field类类型去确定一下几个点。
 1. 数据库字段的类型
 2. 使用默认的HTML部件但渲染表单的field时(e.g.  , )  

Field option

 每一个Field都有一个特定参数,例如CharField,max_length
null  如果是真,jango将会存储空值null进数据库 默认为false
blank 如果为真,field将会允许空格的输入, 默认为false
choices 一个二位元组,如果field中使用choices 则在前端展示的HTML组件就是 
  

举个例子

 
YEAR_IN_SCHOOL_CHOICES = (
(’FR’, ’Freshman’),
(’SO’, ’Sophomore’),
(’JR’, ’Junior’),
(’SR’, ’Senior’),
(’GR’, ’Graduate’),
)

 from  django.db  import  models
  class   Person  (models.Model) : 
    SHIRT_SIZES = ( 
        (’S’, ’Small’),
        (’M’, ’Medium’),
        (’L’, ’Large’),
    )
    name = models.CharField(max_length= 60 )
    shirt_size = models.CharField(max_length= 1 ,choices=SHIRT_SIZES)



 >>>  p = Person(name= "Fred Flintstone" , shirt_size= "L" )
 >>>  p.save()
 >>>  p.shirt_size
u’L’
 >>>  p.get_shirt_size_display()
u’Large’  

save()
这个在后台执行了一个插入sql。但是并没有真正的导数据库知道用户执行了save(),save()没有返回值,但是save()支持参数

 Model.save ([force_insert= False , force_update= False , using=DEFAULT_DB_ALIAS, update_fields= None 
] )  

当你执行save()操作,jango执行以下步鄹

1:触发pre-save事件,这个信号,任何一个函数都可以监听这个事件

2:一些有特殊的字段类型的字段做处理,例如dateField和auto_now=True这时候得到的值是jango生成的时间,这里要注意的是,数据库的时间可能跟服务器的不一样,所以这里要注意时间同步。

3:为插入准备数据,每一个字段提供一个处理后的值

4:为插入准备sql,这里我理解为拼sql

5:发给数据库执行sql

all()

 all_entries = Entry.objects.all() 查看所有的内容

filter(**kwargs)

我们现在看下通过过滤器(filters)获取具体的值

Entry.objects.filter(pub_date__year= 2006 )

exclude(**kwargs)

Entry.objects.filter(
 ...  headline__startswith=’What’
 ...  ).exclude(
 ...  pub_date__gte=datetime.date.today()
 ...  ).filter(
 ...  pub_date__gte=datetime( 2005 ,  1 ,  30 )
… )

返回除去与查找条件相符的数据

get()

如果想要返回指定的一个数据

one_enty = Entry.objects.get(pk= 1 )
  

字段查询

__id
 被指定的查询字段名字必须是模型field名字相对应,除非外键的情况

Entry.objects.filter(blog_id= 4 )

这时候返回并不是Entry中id= 4 的数据行,而是id对应主键算在的数据行  
__exact
 最普通的情况(默认添加)

Entry.objects.get(headline__exact= "Man bites dog" )

翻译成sql就为

SELECT ... WHERE headline = ’Man bites dog’;


Blog.objects.get(id__exact= 14 )  # 明确的形式 
Blog.objects.get(id= 14 )  # __exact 默认添加   
__iexact
 Blog.objects.get(name__iexact= "beatles blog" )

结果可能是  "Beatles Blog" ,   "beatles blog" ,  or     "BeAtlES blOG" .

不区分大小写  
__contains
 Entry.objects.get(headline__contains=’Lennon’)

模糊搜索,翻译成sql

SELECT ... WHERE headline LIKE ’%Lennon%’;  
__ icontains
 Entry.objects.get(headline__icontains=’Lennon’)

sql:

SELECT ... WHERE headline ILIKE ’%Lennon%’;  
__in
 Entry.objects.filter(id__in=[ 1 , 3 , 4 ]
sql:
SELECT … WHERE id IN ( 1 , 3 , 4 );

这种也可以用复合sql的形式表示
 inner_qs = Blog.objects.filter(name__contains=’Cheddar’)

entries = Entry.objects.filter(blog__in=inner_qs)

sql:

SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE ’%Cheddar%’)  
__gt 大于
 Entry.objects.filter(id__gt= 4 )
sql:
SELECT … WHERE id >  4 
__gte 大于等于
__lt 小于
__lte 小于等于  
__range
  import  datetime
start_date = datetime.date( 2005 ,  1 ,  1 )
end_date = datetime.date( 2005 ,  3 ,  31 )
Entry.objects.filter(pub_date__range=(start_date, end_date))

sql:
SELECT ... WHERE pub_date BETWEEN ’ 2005 - 01 - 01 ’  and  ’ 2005 - 03 - 31 ’;  
__year
 Entry.objects.filter(pub_date_year= 2005 )
sql:
SELECT … WHERE pub_date BETWEEN ‘ 2005 - 01 - 01 ’  and  ‘ 2005 - 12 - 31 ’;  
__month __day __hour __minute
 Entry.objects.filter(pub_date__month= 12 )
sql:

SELECT ... WHERE EXTRACT(’month’ FROM pub_date) = ’ 12 ’;  
__isnull
 Entry.objects.filter(pub_date__isnull= True )
sql:
SELECT ... WHERE pub_date IS NULL;  

查看更多关于Django中的模型与数据库(Modelsanddatabase)的详细内容...

  阅读:42次