前言
本文主要给大家介绍了关于Django中Model使用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。
创建模型
使用Django的模型主要注意两个方面:字段的类型和方法的重写。这里用一个例子来说明,其中包含了常用的字段类型和如何重写方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
from django.db import models
class School(models.Model):
pass
class Message(models.Model):
pass
class Teacher(models.Model):
pass
class Student(models.Model):
GENDER_CHOICES = (
( 'male' , "男" ),
( 'female' , "女" ),
( 'secret' , "保密" )
)
name = models.CharField(max_length = 40 , blank = True , verbose_name = "姓名" )
gender = models.CharField(max_length = 6 , choices = GENDER_CHOICES, default = "secret" , verbose_name = "性别" )
age = models.IntegerField(default = 0 , verbose_name = "年龄" )
rank = models.PositiveIntegerField(default = 1 , verbose_name = "排名" , unique = True )
discount = models.DecimalField(max_digits = 3 , decimal_places = 2 , verbose_name = "折扣" , default = 1.0 )
school = models.ForeignKey(to = School, verbose_name = "学校" , on_delete = models.CASCADE)
message = models.OneToOneField(to = Message, verbose_name = "信息" , on_delete = models.CASCADE)
teacher = models.ManyToManyField(verbose_name = "老师" , to = Teacher, blank = True )
introduce = models.TextField(blank = True , verbose_name = "介绍" )
grade = models.FloatField(default = 0.0 , verbose_name = "成绩" )
url = models.URLField(verbose_name = "个人主页" , max_length = 100 )
email = models.EmailField(verbose_name = "邮箱" )
image = models.ImageField(upload_to = 'img/%Y/%m/%d/' , verbose_name = '上传图片' , null = True )
file = models.FileField(upload_to = "file/%Y/%m/%d/" , verbose_name = "上传文件" , blank = True )
is_deleted = models.BooleanField(verbose_name = "已删除" , default = False , blank = True )
time_added = models.DateTimeField(verbose_name = "添加时间" , auto_now_add = True , blank = True )
def delete( self , using = None , keep_parents = False ):
self .is_deleted = True
# some actions
self .save()
def save( self , force_insert = False , force_update = False , using = None ,
update_fields = None ):
# some actions
self .name = self .name.capitalize() # 首字母大写
return super ().save(force_insert = force_insert, force_update = force_update, using = using,
update_fields = update_fields)
def __repr__( self ):
return "UserProfile:{}" . format ( self .name)
def __str__( self ):
return self .name
class Meta:
ordering = [ '-time_added' ]
verbose_name = "用户信息"
verbose_name_plural = verbose_name
db_table = "student_info"
|
字段类型
这里对常见字段中值得注意的地方作一下说明。
CharField
字符串类型值得注意的是当该字段只能在是某些指定的值时,要使用choices参数来指向预先设定的值。
IntergerField & PositiveIntegerField
整数类型和正整数类型。
DecimalField
十进制浮点数,其中,参数max_digits代表数字有多少位,decimal_places代表小数部分有多少位。
ForeignKey
使用to指向被关联的模型,使用on_delete来规定被关联对象删除时该对象的处理方式。主要有两种取值,models.CASCADE和models.SET_NULL。models.CASCADE表示当被关联对象删除时删除该对象,models.SET_NULL表示当被关联对象被删除时将该对象设置为空,此设置的前提是该字段要允许为空。
ImageField & FileField
使用upload_to参数来指定文件保存的路径。注意,该路径前面再加上 MEDIA_ROOT中设置的路径就是上传的文件真实保存路径了,如 MEDIA_ROOT的路径是'/home/media',那图片上传的路径就类似/home/media/img/2018/03/06。
BooleanField
布尔类型,可以使用default指定默认值。
DateTimeField
在Django中,代表时间字段的有三种:DateTimeField、DateField、TimeField,三种类型分别对应datetime()、date()、time(),都有auto_now和auto_now_add参数。
-
auto_now
默认值为False,设置为True时会在每次修改该对象时自动更新为当前时间,但是无法手动修改该字段的值。 -
auto_now_add
默认值为False,设置为True时会在创建对象时自动设置为当前时间,之后都不再修改,也不能手动修改其值。 -
默认当前时间,又能修改
有时候我们需要在创建对象时设置字段的值为当前时间,在后续时又能修改,使用auto_now或者auto_now_add都无法实现这一点。此时,可以使用default参数来设置默认值,如下
1
2
3
4
5
|
from django.db import models
from django.utils import timezone
class Message(models.Model):
add_date = models.DateTimeField(verbose_name = '保存日期' ,default = timezone.now)
mod_date = models.DateTimeField(verbose_name = '最后修改日期' , auto_now = True )
|
重写方法
delete
Django默认的删除是将数据从数据库里删除,有时候我们需要软删除,保存以前的数据,这时候我们可以使用一个布尔类型的字段标识该条数据是否删除,这时需要重写delete方法实现软删除。
在delete方法中将is_deleted的值设置为True,表示该条数据已删除。此外还可以执行一些关联的动作,比如对相关字段赋值等,最后保存对象。
save
重写save方法可以让我们在保存数据时做一些相关的操作,比如保存姓名时自动设置为首字母大写,执行完之后需要调用父类的save方法进行保存。
repr & str
两者的作用是将变量或者常量转换为字符串对象,这里重写该方法使得对象实例能被转化为字符串。
class Meta
- ordering:结果集按照何种方式排序,上面例子表示按添加时间的逆序排序
- verbose_name:对象的名称
- verbose_name_plural:对象复数形式的名称
- db_table:在数据库中的表名
常用方法
在对常用方法介绍部分,由于上面的模型包含字段较多,所以不使用上面创建的模型。这里使用一些常见的模型,通过名字就可以知道代表的内容,因此就不列出模型了。
创建实例
create
使用create方法可以创建一个模型实例,将各字段在参数中设置各个字段的值。
1
|
student = Student.objects.create(name = 'zhangsan' , gender = 'male' )
|
get_or_create
get_or_create的作用是查询一个实例,当实例不存在时则创建一个实例。
1
2
3
4
5
|
obj, created = Person.objects.get_or_create(
first_name = 'John' ,
last_name = 'Lennon' ,
defaults = { 'birthday' : date( 1940 , 10 , 9 )},
)
|
函数返回一个(object, created)的tuple,object是查询或者创建的对象实例,created是个布尔类型的值,表示是否是新创建的实例。在查询时使用defaults以外的参数进行查询,当实例不存在时将包含default参数一起创建一个新的实例。功能类似于如下代码:
1
2
3
4
5
|
try :
obj = Person.objects.get(first_name = 'John' , last_name = 'Lennon' )
except Person.DoesNotExist:
obj = Person(first_name = 'John' , last_name = 'Lennon' , birthday = date( 1940 , 10 , 9 ))
obj.save()
|
update_or_create
update_or_create的作用是更新一个实例,当实力不存在时则创建一个实例。
1
2
3
4
|
obj, created = Person.objects.update_or_create(
first_name = 'John' , last_name = 'Lennon' ,
defaults = { 'first_name' : 'Bob' },
)
|
函数返回一个(object, created)的tuple,object是更新或者创建的对象实例,created是个布尔类型的值,表示是否是新创建的实例。在查询的对象实例存在时,使用default中的参数进行更新,当实例不存在时,创建新的对象实例,需要更新的字段的值设置为default中的值。功能类似:
1
2
3
4
5
6
7
8
9
10
11
|
defaults = { 'first_name' : 'Bob' }
try :
obj = Person.objects.get(first_name = 'John' , last_name = 'Lennon' )
for key, value in defaults.items():
setattr (obj, key, value)
obj.save()
except Person.DoesNotExist:
new_values = { 'first_name' : 'John' , 'last_name' : 'Lennon' }
new_values.update(defaults)
obj = Person( * * new_values)
obj.save()
|
add
这里补充一下add方法,add用在多对多的关系模型上,表示添加该字段的指向对象。
1
2
3
4
5
|
>>> john = Author.objects.create(name = "John" )
>>> paul = Author.objects.create(name = "Paul" )
>>> george = Author.objects.create(name = "George" )
>>> ringo = Author.objects.create(name = "Ringo" )
>>> entry.authors.add(john, paul, george, ringo)
|
上面的Author表示作者模型,entry表示书籍条目,一本书可以有多个作者,采用多对多关系。add可以为书的实例添加多个作者。
查询
all
all方法查询该对象的所有实例。
1
|
all_entries = Entry.objects. all ()
|
get
使用get查询实例,当实例不存在时会返回一个不存在异常。
1
2
|
>>> entry = Entry.objects.get(pk = 1 )
>>> cheese_blog = Blog.objects.get(name = "Cheddar Talk" )
|
filter
filter返回一个QuerySet,而不是对象实例,当查询结果不存在时返回空的QuerySet,而不是返回一场,可以对结果集作切片操作来获取实例内容。下面代码功能在有对象实例时等同于上面get的操作。
1
2
|
>>> entry = Entry.objects. filter (pk = 1 )[ 0 ]
>>> cheese_blog = Blog.objects. filter (name = "Cheddar Talk" )[ 0 ]
|
filter结果可以链式地进行操作,也就是后面可以接多个过滤条件。
1
2
3
|
Entry.objects. filter (pub_date__year = 2006 )
Entry.objects. all (). filter (pub_date__year = 2006 )
Entry.objects. filter (blog__name__year = "zhangsan" )
|
上面的pub_date__year表示取出DateField类型的pub_date的年,类似的可以取出月__month,日__day。在使用外键ForeignKey时可以使用双下划线来表示被关联对象的字段。
现在来看一下链式过滤的例子。
1
2
3
4
5
6
7
|
Entry.objects. filter (
... headline__startswith = 'What'
... ).exclude(
... pub_date__gte = datetime.date.today()
... ). filter (
... pub_date__gte = datetime.date( 2005 , 1 , 30 )
... )
|
首先使用__startswith过滤标题以'What'开始的数据。然后保留让发布日期小于今天的数据,exclude表示排除条件内的那部分数据,条件使用了__gte表示大于当前日期,该部分过滤类似于filter后面使用__lte小于。最后也是使用__gte大于一个自定义的日期。
除了上面的过滤条件外,常见的还有__icontains,表示包含该内容。
Q
Q是Django自带的内容,用于查询。主要的用途是在页面的搜索框中输入内容后台查询相应的数据集。
1
2
3
4
|
student = student. filter (Q(name__icontains = search) |
Q(teacher__name__icontains = search) |
Q(gender__icontains = search) |
Q(url__icontains = search))
|
上述例子常用在一个搜索框可能搜索多个字段的内容时,各个过滤条件之间使用“|”进行或者运算。当多条件查询时,各个条件是并运算,使用“&”代替“|”。
Q可以复制给个变量,有时候我们需要对Q后面的内容先做一些处理,如将日期拼凑出来等,这时候可以先把Q赋值给一个变量,然后对变量进行“|”或者“&”操作。
1
2
3
|
query = Q(name__icontains = search)
query = query | Q(teacher__name__icontains = search)
student = student. filter (query)
|
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:http://www.cnblogs.com/suraer/p/8515416.html