您当前的位置: 首页 >  django
  • 1浏览

    0关注

    214博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Django(四):ORM模型的增删改成操作+图片字段的处理

不愿透露姓名の网友 发布时间:2019-09-11 20:37:37 ,浏览量:1

文章目录
  • 一、ORM字段类型
    • 1.字段类型
    • 2.字段属性
    • 3.元数据
  • 二、ORM的单表操作
    • 2.1 准备工作
    • 2.2 添加数据
    • 2.3 查询数据
    • 2.4 修改数据
    • 2.5 删除数据
  • 三、多表查询(一对多)
    • 1.准备工作
    • 2.增加数据
    • 3.查询数据
    • 4.更新数据
    • 5.删除数据
  • 四、多表查询(多对多关系)
    • 1.建表
    • 2.添加
    • 3.查询
    • 4.修改
    • 5.删除
  • 五、聚合函数和F/Q对象
  • 六、图片字段的配置

一、ORM字段类型 1.字段类型 类型含义CharFieldvarchar类型,需要指定长度IntegerField整型DecimalField浮点型,需要指定最大长度和小数点位数DateField日期,例如datetimeImageField图片ForeignKey做外键

而ForeignKey 做外键又有以下几个参数

①to 设置关联表
②to_field 关联表要关联的键名,默认为关联表中的id,可以不写
③on_delete 当删除关联表中的数据的时候,从表做什么行为,
 	(1)CASCADE  当关联表中数据删除的时候,外键所在表中的数据也会被删除
 	(2)SET_NULL  当关联表中数据删除的时候,外键所在表中的外键设置为空
 	(3)SET_DEFAULT  当关联表中数据删除的时候,外键所在表中的外键设置一个默认值
 	(4)PROTECT 关联保护,当关联表的数据被删除的时候,报异常,
 	(5)DO_NOTHING  当关联表中数据删除的时候,外键所在的表不做任何事情
2.字段属性 属性备注max_length最大长度verbose_name备注,站点管理中用于显示字段为中文max_digits浮点型最大长度decimal_places小数点位数auto_now= True获取的是当前时间null= True可为空,默认是不为空 3.元数据 属性备注db_table修改表的名字长度verbose_name备注,站点管理中用于显示模型名字为中文,会出现sverbose_name_plural显示复数名称(站点管理处)ordering= [’-age’]指定排序

二、ORM的单表操作 2.1 准备工作

1.数据库创建一个stu库 2.在model.py添加一个Person类

from django.db import models
# 创建学生表
class Person(models.Model):
    # id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32, verbose_name='名字')
    age = models.IntegerField(verbose_name='年龄')
    height = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='身高', null=True)  # 长度为5,两位小数
    birthday = models.DateField(verbose_name='生日')

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'person'
        verbose_name = '用户'
        verbose_name_plural = verbose_name  # 显示的是后台模块的名字

3.然后在命令行进行数据迁移

python mange.py makemigrations
python mange.py migrate

4.查看mysql数据库,数据库创表成功 在这里插入图片描述 5.在url处配置路由,并在view处添加对应方法 在这里插入图片描述

2.2 添加数据 方法使用save需要声明model类的对象,然后可以使用对象.属性添加,也可以使用类中声明时候直接添加属性,注意最后需要对象.save()保存create借助objects.create(属性1,属性2)添加
def addPerson(request):
    # 添加方法一:save()
    person=models.Person(name='张三',age=11,birthday='1912-12-22')
    person.save()
	# 或者
    person=models.Person()
    person.name='迪迦'
    person.age=22
    person.birthday='1998-11-23'
    person.save()
    
	#------------------------------------------------------------------
    # 添加方法二:create()
    models.Person.objects.create(name='泰罗', age=76, birthday='1954-07-15')
    
    return HttpResponse('添加数据成功')
2.3 查询数据

首先看一下查询的常用查询方法

 all():查询所有结果
  
 filter(**kwargs):它包含了与所给筛选条件相匹配的对象
  
 get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
  
 exclude(**kwargs):它包含了与所给筛选条件不匹配的对象
  
 values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
  
 values_list(*field):它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
  
 order_by(*field): 对查询结果排序
  
 reverse():对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。
  
 distinct(): 从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。)
  
 count(): 返回数据库中匹配查询(QuerySet)的对象数量。
  
 first(): 返回第一条记录
  
 last(): 返回最后一条记录
  
 exists(): 如果QuerySet包含数据,就返回True,否则返回False  

然后总结一下

类型备注返回QuerySet对象的方法all()、filter()、exelude()、order_by()、reverse()、distinct()特殊的QuerySet1.values() :返回一个可迭代的字典序列 2. values_list() 返回一个可迭代的元祖序列返回具体对象的方法get()、first()、last()返回布尔值的方法exists()返回数字的方法count()

​ 使用举例

def getPerson(request):
    # 1.all 方法
    # data = models.Person.objects.all()
    # print (data)
    # print (data[0].name)
    # print (data[0].age)
    # print (data[0].height)
    # for one in data:
    #     print('生日:', one.birthday)
    #     print('名字:', one.name)
    
    # --------------------------------------------------------------------
    # 2.filter()方法,筛选条件,但是返回的是一个queryset类型
    # data = models.Person.objects.filter(birthday='1912-12-22')
    # for i in data:
    #     print(i.age)
    # -----------------------------------------------------------------------
    # 3.exclude()方法和filter方法相反,返回的是非符合条件的
    # data = models.Person.objects.exclude(birthday='1912-12-22')
    # for i in data:
    #     print(i.name)
    # --------------------------------------------------------------------
    # 4.get()方法,筛选条件,一般参数为主键,只能筛选唯一符合条件的
    # data=models.Person.objects.get(birthday='1912-12-22')
    # print(data)
    # --------------------------------------------------------------------
    # 5.first()和last()方法,将选出第一条和最后一条数据
    # data=models.Person.objects.filter(age=11).first()
    # print(data)
    # data=models.Person.objects.filter(age=11).last()
    # print(data)
    # --------------------------------------------------------------------
    # 6.order_by 排序,默认升序,降序在参数前加-
    # data=models.Person.objects.order_by('-age')
    # for i in data:
    #     print(i.name)
    # ---------------------------------------------------------------------
    # 7.values,会将查询到的对象以字典形式将详细数据查询出来,并放在列表中
    # data=models.Person.objects.all().values()
    # print(data)
    # ---------------------------------------------------------------
    # 8.exists(),查询符合条件的数据是否存在,返回true或false
    # data=models.Person.objects.filter(age=33).exists()
    # print(data)
    # -----------------------------------------------------------------
    # 9.count()记录符合条件的条数
    # data=models.Person.objects.all().count()
    # print(data)

然后还有其他的双下划线查询方法

下划线查询法用法__gt>__lt<__gte≥__lte≤__in包含__range范围__isnull为空startswitch开始,类似 like ‘a%’endswitch结束,类似 like ‘%a’contains类似 %a% ,对大小写敏感icontains类似 %a% ,对大小写不敏感

举例用法:

def getPerson(request):
    #__gt大于   __lt小于  __gte大于等于 __lte  小于等于
    # data=models.Person.objects.filter(age__gt=20)
    # print(data[0].name)
	# ---------------------------------------------------------
    #__in包含,exclude不包含,range范围
    # data=models.Person.objects.filter(age__in=(22,))
    # for i in data:
    #     print(i.name)
    
    # data = models.Person.objects.exclude(age__in=(22,))
    # for i in data:
    #     print(i.name)
    
    # data=models.Person.objects.filter(age__range=(15,30))
    # for i in data:
    #     print(i.name)
    
    # ---------------------------------------------------------
    # 查询身高为__isnull
    # data=models.Person.objects.filter(height__isnull=True)
    # for i in data:
    #     i.height=1.11
    #     i.save()

	# ---------------------------------------------------------
    #查询开头的startswitch和查询结尾的endswitch
    # data=models.Person.objects.filter(name__startswith='讲师')#like '讲师%'
    # print(data[0].name)
    # data=models.Person.objects.filter(name__endswith='罗')
    # print(data[0].name)
	
	# ---------------------------------------------------------
    #包含的contains类似like %a%   对大小写敏感    icontains 对大小写不敏感
    data=models.Person.objects.filter(name__contains='师')
    print(data[0].name)
    return HttpResponse('查询数据成功')
2.4 修改数据
def updatePerson(request):
    #1.save(),先查要修改的数据,然后直接用对象.属性=修改值,如果查询的数据为多个需要用遍历修改
    # data=models.Person.objects.get(id=2)
    # data.height=233.34
    # data.save()

    #--------------------------------------------------------------
    #2.update(),先查后更新
    models.Person.objects.filter(id=3).update(name='孙悟空') # 更新什么写什么字段
    return HttpResponse('修改数据成功')
2.5 删除数据

先查询后删除

def delPerson(request):
    models.Person.objects.get(id=6).delete()
    return HttpResponse('删除数据成功')
三、多表查询(一对多) 1.准备工作

创建多表,并进行数据迁移 在这里插入图片描述 models.py 在这里插入图片描述

2.增加数据
# 方法1--------------------------------------------------
# 增加出版社
# Publish.objects.create(name='清华出版社',address = '北京')
# Publish.objects.create(name='中国出版社',address = '北京朝阳')
# Publish.objects.create(name='河南出版社',address = '洛阳')

# 增加书
# Book.objects.create(name='python入门',publish_id = 1)

# 将出版社和书关联
# publish = Publish.objects.get(name='中国出版社')
# Book.objects.create(name='python入门', publish_id=publish.id)

# 方法2--------------------------------------------------
# Book.objects.create(name='python核心编程',publish = Publish.objects.get(name='中国出版社'))

# 方法3--------------------------------------------------
# 正向操作    从外键所在的表到主表叫正向
book = Book()
book.name= '笨办法学python'
book.publish = Publish.objects.get(name='河南出版社')
book.save()

# 反向操作  从主表到从表 叫反向
publish_obj = Publish.objects.get(name="中国出版社")
publish_obj.book_set.create(name='pythonWeb开发')
3.查询数据
# 方法1--------------------------------------------------
# publish = Publish.objects.get(name="中国出版社")
# book = Book.objects.filter(publish_id=publish.id).all()
# for x in book:
#     print (x.name)

# 方法2--------------------------------------------------
# 正向查询  从外键所在的表到主表叫正向
# 查询  pythonWeb开发 属于哪一个出版社
# book = Book.objects.filter(name='pythonWeb开发').first()
# print (book.name)
# print (book.publish.name)

# 方法3--------------------------------------------------
# 反向查询 从主表到从表  叫 反向查询     _set
publish = Publish.objects.get(name='中国出版社')
book = publish.book_set.all()
print (book)
4.更新数据
# 一对多更新数据
def updatemore(request):
    # save
    # book=models.Book.objects.get(id=2)
    # book.publish=models.Publish.objects.get(name='清华出版社')
    # book.save()
    # #upadate
    # models.Book.objects.update(name='python',publish=models.Publish.objects.get(id=3))

    #set
    # 反向,类似数据库中的update
    publish = models.Publish.objects.get(name='蓝翔出版社')
    book = models.Book.objects.get(id=2)
    book2 = models.Book.objects.get(id=1)
    publish.book_set.set([book, book2])

    return HttpResponse('修改数据成功')
5.删除数据
# 一对多删除数据
def delmore(request):
    # 一般先删除从表再删除主表,根据模型类里的外键设置决定
    models.Book.get(id=2).delete()
    models.Publish.get(id=2).delete()
    return HttpResponse('删除数据成功')
四、多表查询(多对多关系) 1.建表

在这里插入图片描述 models.py

class Person(models.Model):
    # id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32,verbose_name="姓名")
    age = models.IntegerField(verbose_name="年龄")
    height = models.DecimalField(max_digits=5,decimal_places=2,verbose_name="身高",null=True)
    birthday = models.DateField(verbose_name="生日",auto_now=True)

    def __str__(self):
        return str(self.name)

    class Meta:
        db_table = 'person'
        verbose_name = "用户"
        verbose_name_plural = verbose_name
        # ordering= ['-age','id','name']

class Teacher(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField(default=0)
    gender = models.CharField(max_length=8)
    person = models.ManyToManyField(to=Person)
    class Meta:
        db_table = 'teacher'
2.添加
# 多对多添加
def addmanytomany(request):
    # 添加老师
    # models.Teacher.objects.create(name='僵尸王宗涛',gender=1)
    # models.Teacher.objects.create(name='僵尸张环宇',gender=0)
    # models.Teacher.objects.create(name='僵尸温俊鹏',gender=1)

    # 正向操作
    # 添加新学生,和僵尸王宗涛关联
    # teacher=models.Teacher.objects.get(name='僵尸王宗涛')
    # teacher.person.create(name='孙悟空',age=3)

    # 老学生关联温老师,需要将两个数据都查出来,并使用add()
    # teacher=models.Teacher.objects.get(id=3)
    # person=models.Person.objects.filter(name='泰罗').first()
    # teacher.person.add(person)

    # 反向操作
    teacher = models.Teacher.objects.get(id=2)
    person = models.Person.objects.get(id=1)
    person.teacher_set.add(teacher)
    return HttpResponse('添加成功')

3.查询
# 多对多查询
def getmanytomany(request):
    # 寻找id为3的老师教的所有学生
    teacher = models.Teacher.objects.get(id=3)
    person = teacher.person.all()
    print(person.values())
    # 根据学生查老师
    person = models.Person.objects.get(id=6)
    teacher = person.teacher_set.all()
    print(teacher.values())

    return HttpResponse('查询成功')

4.修改
# 多对多修改
def updatemanytomany(request):
    # 正向修改
    # 将讲师王宗涛的学生改为234,set后边放列表,列表里传入更改的关联数据
    # teacher=models.Teacher.objects.get(id=1)
    # person1=models.Teacher.objects.get(id=2)
    # person2=models.Teacher.objects.get(id=3)
    # person3=models.Teacher.objects.get(id=4)
    # teacher.person.set([person1,person2,person3])

    # 反向
    person = models.Person.objects.get(id=2)
    teacher1 = models.Teacher.objects.get(id=3)
    teacher2 = models.Teacher.objects.get(id=2)
    person.teacher_set.set([teacher1, teacher2])

    return HttpResponse('修改成功')
5.删除
# 多对多删除
def delmanytomany(request):
    # remove 解除关系
    # 正向
    # teacher=models.Teacher.objects.get(id=1)
    # person=models.Person.objects.get(id=3)
    # teacher.person.remove(person)

    # 反向
    # person=models.Person.objects.get(id=4)
    # teacher=models.Teacher.objects.get(id=1)
    # person.teacher_set.remove(teacher)

    # del删除
    models.Person.objects.get(id=2).delete()
    return HttpResponse('删除成功')
五、聚合函数和F/Q对象
# 聚合函数
from django.db.models import Max, Min, Count, Avg, Sum


def juhe(request):
    data = models.Person.objects.all().aggregate(Avg('age'))
    print(data)  # 显示的是queryset
    data = models.Person.objects.all().aggregate(Avg('age'), sum('age'))
    print(data)  # 显示的是queryset

    return HttpResponse('聚合查询')


# --------------------------------------------------------------------python
from django.db.models import F, Q


# F和Q对象
# F对象: 用于比较同一个模型中的两个字段的值
def Ftest(request):
    # 查询book中销量大于库存的
    book = models.Book.objects.filter(xiaoliang__gt=F('kucun')).all()
    print(book)
    return HttpResponse('f对象')


# Q对象:用于处理多条件中的逻辑关系   and or not
def Qtest(request):
    # and
    book = models.Book.objects.filter(Q(xiaoliang=20) & Q(kucun=50))
    print(book)
    book = models.Book.objects.filter(xiaoliang=20, kucun=50)
    print(book)
    # or
    book = models.Book.objects.filter(Q(xiaoliang=20) | Q(kucun=50))
    print(book)
    # not
    book = models.Book.objects.filter(~Q(xiaoliang=20) | ~Q(kucun=50))
    print(book)
    return HttpResponse('q对象')

六、图片字段的配置
1.模型中添加照片字段,注意最后的null和blank的意思
	photo=models.ImageField(upload_to='img',null=True,blank=True)
	#null针对数据库,表示可以为空,即在数据库储存可以为空
    #blank针对表单,表示在表单中该字段可以不填,但是对数据库无影响
    
2.在settings末尾添加
	MEDIA_URL='/media/'
	#指定的媒体文件上传路径
	MEDIA_ROOT=os.path.join(BASE_DIR,'static')
关注
打赏
1657102503
查看更多评论
立即登录/注册

微信扫码登录

0.0416s