Django中Model的使用方法教程


Posted in Python onMarch 07, 2018

前言

本文主要给大家介绍了关于Django中Model使用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。

创建模型

使用Django的模型主要注意两个方面:字段的类型和方法的重写。这里用一个例子来说明,其中包含了常用的字段类型和如何重写方法。

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参数来设置默认值,如下
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方法可以创建一个模型实例,将各字段在参数中设置各个字段的值。

student = Student.objects.create(name='zhangsan', gender='male')

get_or_create

get_or_create的作用是查询一个实例,当实例不存在时则创建一个实例。

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参数一起创建一个新的实例。功能类似于如下代码:

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的作用是更新一个实例,当实力不存在时则创建一个实例。

obj, created = Person.objects.update_or_create(
 first_name='John', last_name='Lennon',
 defaults={'first_name': 'Bob'},
)

函数返回一个(object, created)的tuple,object是更新或者创建的对象实例,created是个布尔类型的值,表示是否是新创建的实例。在查询的对象实例存在时,使用default中的参数进行更新,当实例不存在时,创建新的对象实例,需要更新的字段的值设置为default中的值。功能类似:

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用在多对多的关系模型上,表示添加该字段的指向对象。

>>> 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方法查询该对象的所有实例。

all_entries = Entry.objects.all()

get

使用get查询实例,当实例不存在时会返回一个不存在异常。

>>> entry = Entry.objects.get(pk=1)
>>> cheese_blog = Blog.objects.get(name="Cheddar Talk")

filter

filter返回一个QuerySet,而不是对象实例,当查询结果不存在时返回空的QuerySet,而不是返回一场,可以对结果集作切片操作来获取实例内容。下面代码功能在有对象实例时等同于上面get的操作。

>>> entry = Entry.objects.filter(pk=1)[0]
>>> cheese_blog = Blog.objects.filter(name="Cheddar Talk")[0]

filter结果可以链式地进行操作,也就是后面可以接多个过滤条件。

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时可以使用双下划线来表示被关联对象的字段。

现在来看一下链式过滤的例子。

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自带的内容,用于查询。主要的用途是在页面的搜索框中输入内容后台查询相应的数据集。

student = student.filter(Q(name__icontains=search) |
       Q(teacher__name__icontains=search) |
       Q(gender__icontains=search) |
       Q(url__icontains=search))

上述例子常用在一个搜索框可能搜索多个字段的内容时,各个过滤条件之间使用“|”进行或者运算。当多条件查询时,各个条件是并运算,使用“&”代替“|”。

Q可以复制给个变量,有时候我们需要对Q后面的内容先做一些处理,如将日期拼凑出来等,这时候可以先把Q赋值给一个变量,然后对变量进行“|”或者“&”操作。

query = Q(name__icontains=search)
query = query | Q(teacher__name__icontains=search)
student = student.filter(query)

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python操作Word批量生成文章的方法
Jul 28 Python
基于python yield机制的异步操作同步化编程模型
Mar 18 Python
Django与JS交互的示例代码
Aug 23 Python
python+opencv实现动态物体识别
Jan 09 Python
Python二叉树的遍历操作示例【前序遍历,中序遍历,后序遍历,层序遍历】
Dec 24 Python
python requests.post带head和body的实例
Jan 02 Python
python列表,字典,元组简单用法示例
Jul 11 Python
PIL对上传到Django的图片进行处理并保存的实例
Aug 07 Python
Python压缩模块zipfile实现原理及用法解析
Aug 14 Python
python boto和boto3操作bucket的示例
Oct 30 Python
Python根据字符串调用函数过程解析
Nov 05 Python
pycharm实现猜数游戏
Dec 07 Python
python使用opencv按一定间隔截取视频帧
Mar 06 #Python
python+ffmpeg视频并发直播压力测试
Mar 06 #Python
小白如何入门Python? 制作一个网站为例
Mar 06 #Python
python调用系统ffmpeg实现视频截图、http发送
Mar 06 #Python
Python从零开始创建区块链
Mar 06 #Python
Django 实现下载文件功能的示例
Mar 06 #Python
python入门前的第一课 python怎样入门
Mar 06 #Python
You might like
PHP设计聊天室步步通
2006/10/09 PHP
PHP关联数组实现根据元素值删除元素的方法
2015/06/26 PHP
php微信公众平台开发(一) 配置接口
2016/12/06 PHP
Javascript图像处理思路及实现代码
2012/12/25 Javascript
js switch case default 的用法示例介绍
2013/10/23 Javascript
利用js(jquery)操作Cookie的方法说明
2013/12/19 Javascript
jQuery中mouseover事件用法实例
2014/12/26 Javascript
jquery获取节点名称
2015/04/26 Javascript
javascript+HTML5自定义元素播放焦点图动画
2016/02/21 Javascript
在 webpack 中使用 ECharts的实例详解
2018/02/05 Javascript
angular 组件通信的几种实现方式
2018/07/13 Javascript
如何基于filter实现网站整体变灰功能
2020/04/17 Javascript
Flexible.js可伸缩布局实现方法详解
2020/11/13 Javascript
Python采用raw_input读取输入值的方法
2014/08/18 Python
python求解水仙花数的方法
2015/05/11 Python
Python中pygame安装方法图文详解
2015/11/11 Python
python django 访问静态文件出现404或500错误
2017/01/20 Python
Python AES加密模块用法分析
2017/05/22 Python
Python3.4实现从HTTP代理网站批量获取代理并筛选的方法示例
2017/09/26 Python
Python中Scrapy爬虫图片处理详解
2017/11/29 Python
TF-IDF与余弦相似性的应用(二) 找出相似文章
2017/12/21 Python
Python使用Pandas库常见操作详解
2020/01/16 Python
django 实现后台从富文本提取纯文本
2020/07/02 Python
python 制作python包,封装成可用模块教程
2020/07/13 Python
浅谈Python 钉钉报警必备知识系统讲解
2020/08/17 Python
Html5监听手机摇一摇事件的实现
2019/11/07 HTML / CSS
高中毕业生自我鉴定范文
2013/09/26 职场文书
大学生个人总结的自我评价
2013/10/05 职场文书
会计员岗位职责
2014/03/15 职场文书
医药公司采购员岗位职责
2015/04/03 职场文书
研讨会致辞
2015/07/31 职场文书
中学生运动会广播稿
2015/08/19 职场文书
创业计划书详解
2019/07/19 职场文书
导游词之凤凰古城
2019/10/22 职场文书
MySQL索引知识的一些小妙招总结
2021/05/10 MySQL
nginx作grpc的反向代理踩坑总结
2021/07/07 Servers