当前位置: 首页 > news >正文

竞价网站做seo建筑设计公司名字

竞价网站做seo,建筑设计公司名字,福州自适应网站建设,北京企业建站系统模板文章目录 一、models字段类型概述属性命名限制使用方式逻辑删除和物理删除常用字段类型 二、常用字段参数常用字段选项(通过字段选项#xff0c;可以实现对字段的约束) 实践创建模型执行迁移命令 并 创建超级用户登录admin后台添加文件和图片字段定义模型字段和约束及在Admin后… 文章目录 一、models字段类型概述属性命名限制使用方式逻辑删除和物理删除常用字段类型 二、常用字段参数常用字段选项(通过字段选项可以实现对字段的约束) 实践创建模型执行迁移命令 并 创建超级用户登录admin后台添加文件和图片字段定义模型字段和约束及在Admin后台管理系统的表单情况 三、models基本操作3.1 增实践方式一方式二方式三方式四不会报错 测试添加多条数据 3.2 删删除多条数据 3.3 修改数据修改多条数据 3.4 查get() 获取单条数据all() 获取所有数据first() 返回第一条数据last() 返回最后一条数据filter() 过滤count(): 返当前查询集中的对象个数exists():判断查询集中是否有数据values(): 获取指定列的值values_list():获取指定列的值exclude() 排除取反聚合排序分页功能手动分页Django中的自动分页器 四、Django模型进阶4.1 配置MySQL实践报错1django.db.utils.NotSupportedError: MySQL 8 or later is required (found 5.7.26).报错2RuntimeWarning: Got an error checking a consistent migration history performed for database connection default: (1045, Access denied for user rootlocalhost (using password: YES)) 4.2 多模块关联关系4.3 Model连表结构4.3.1 一对多关联实践增加数据删除数据修改数据查询数据前三种查询第四种查询 4.3.2 多对多关联实践添加数据写法一写法二 修改数据删除数据删除电影删除用户 查询 4.3.3 一对一实践增删改查询 一、models字段类型 概述 django根据属性的类型确定以下信息 当前选择的数据库支持字段的类型渲染管理表单时使用的默认html控件在管理站点最低限度的验证 django会为表增加自动增长的主键列每个模型只能有一个主键列如果使用选项设置某属性为主键列后则django不会再生成默认的主键列。 属性命名限制 遵循标识符规则由于django的查询方式不允许使用连续的下划线写一个下划线是可以的写两个下划线_不可以 定义属性时需要字段类型字段类型被定义在django.db.models.fields目录下为了方便使用被导入到django.db.models中 使用方式 导入from django.db import models通过models.Field 创建字段类型的对象赋值给属性 逻辑删除和物理删除 对于重要数据都做逻辑删除不做物理删除实现方法是定义is_delete属性类型为BooleanField默认值为False is_delete models.BooleanField(defaultFalse) 常用字段类型 AutoField 一个根据实际ID自动增长的IntegerField通常不指定如果不指定主键字段id将自动添加到模型中 CharField(max_length字符长度) 字符串默认的表单样式是 Input DecimalField(max_digitsNone, decimal_placesNone) 使用python的Decimal实例表示的十进制浮点数参数说明 DecimalField.max_digits 位数总数 DecimalField.decimal_places 小数点后的数字位数 FloatField 用Python的float实例来表示的浮点数 BooleanField True/False 字段此字段的默认表单控制是CheckboxInput DateField( [auto_nowFalse, auto_now_addFalse] ) 使用Python的datetime.date实例表示的日期参数说明 DateField.auto_now 每次保存对象时自动设置该字段为当前时间用于最后一次修改”的时间戳它总是使用当前日期, 默认为false DateField.auto_now_add 当对象第一次被创建时自动设置当前时间用于创建的时间戳它总是使用创建时的日期默认为false 注意: auto_now_addauto_nowand default 这些设置是相互排斥的 , 他们之间的任何组合将会发生错误的结果 TimeField 使用Python的datetime.time实例表示的时间参数同DateField DateTimeField 使用Python的datetime.datetime实例表示的日期和时间参数同DateField FileField 一个上传文件的字段 ImageField 继承了FileField的所有属性和方法但对上传的对象进行校验确保它是个有效的image需要安装Pillow: pip install Pillow 二、常用字段参数 常用字段选项(通过字段选项可以实现对字段的约束) nullTrue 数据库中字段是否可以为空blankTrue django的Admin 中添加数据时是否可允许空值 一般nullTrue blankTrue 搭配着用出现nullTrue就用上blankTrue primary_key True 主键对AutoField设置主键后就会代替原来的自增 id 列auto_now和 auto_now_add auto_now           自动创建 - - - 无论添加或修改都是当前操作的时间 auto_now_add   自动创建 - - - 永远是创建时的时间choices   (后台admin下拉菜单) USER_TYPE_LIST (    (1, “超级用户”),    (2, ‘普通用户’), ) user_type models.IntegerField( choicesUSER_TYPE_LIST, default1, verbose_name‘用户类型’)max_length 最大长度default 默认值verbose_name    Admin(后台显示的名称)中字段的显示名称name | db_column   数据库中的字段名称在我做迁移的时候默认情况表当中的字段名称和写的属性名是一样的如果想不一样就用name 或者 db_column 来指定uniqueTrue   不允许重复db_index True   数据库索引, 例如: 如果你想通过name查询的更快的话给他设置为索引即可editableTrue   在Admin里是否可编辑不可编辑则不显示设置表名 class Meta:   db_table ‘person’ 实践 新建一个项目Day03DjangoPro01 创建模型 App\models.py from django.db import modelsclass UserModel(models.Model):# uid 它会成为主键原来的id不会创建uid models.AutoField(auto_createdTrue, primary_keyTrue)# CharField: 字符串类型 最大长度 unique唯一 db_index索引name models.CharField(max_length30, uniqueTrue, db_indexTrue)# IntegerField: 整数类型, default默认值age models.IntegerField(default18)# BooleanField 类型sex models.BooleanField(defaultTrue) # True男# TextField 大文本 nullTrue 可以为空 blankTrue 在Admin管理页面可以为空info models.TextField(nullTrue, blankTrue)# FloatField 小数salary models.FloatField(default100000.456)# DecimalField 十进制小数 max_digits9 总长度9 ,decimal_places2 小数点后保留2位money models.DecimalField(max_digits9, decimal_places2, default0)# 日期birthday models.DateField(default2000-3-4)birthday2 models.DateTimeField(auto_nowTrue) # auto_nowTrue 每一次修改后都会自动修改该时间为最新的修改时间birthday3 models.DateTimeField(auto_now_addTrue) # auto_now_addTrue 第一次添加数据的时候的时间以后不会修改 数据迁移 迁移的概念: 就是将模型映射到数据库的过程 生成迁移文件: python manage.py makemigrations 执行迁移: python manage.py migrate 如果遇到 Please select a fix: 1) Provide a one-off default now (will be set on all existing rows with a null value for this column) 2) Quit and manually define a default value in models.py. Select an option: 1)现在提供一次性默认值(将在所有现有行上设置此列的空值) 2)退出并在models.py中手动定义一个默认值。 这里是告诉你 因为新添加了字段原有数据因为没有这个新字段那么1就是设置一次性默认值填入到之前的数据中2 models.py中手动定义一个默认值default。 Select an option: 输入1或者2 回车 创建超级用户 python manage.py createsuperuser 用户名 admin 密码 123456 弹出信息你的密码太简单了太短了至少八个字符看你是否要使用Y就是的使用 执行迁移命令 并 创建超级用户登录admin后台 App\admin.py from django.contrib import adminfrom App.models import *# 后台管理系统的使用 # 在这里注册对应的模型 admin.site.register(UserModel)打开cmd workon envdjango4 python manage.py makemigrations python manage.py migrate python manage.py createsuperuser访问admin后台: http://127.0.0.1:8000/admin/ 添加一条数据在数据库观察 birthday2 和 birthday3 修改刚刚添加的数据 可以看到 birthday2 发生了变化birthday3 没有改变。 auto_nowTrue 每一次修改后都会自动修改该时间为最新的修改时间 auto_now_addTrue 第一次添加数据的时候的时间以后不会修改 添加文件和图片字段 App\models.py # 既可以上传文件又可以上传图片 icon models.FileField(nullTrue, blankTrue, upload_tostatic/uploads) # upload_to 上传的地方再重新生成迁移文件、执行迁移 python manage.py makemigrations python manage.py migrate执行完之后进入admin后台管理页面点击添加 App\models.py # 限制只能上传图片 icon2 models.ImageField(nullTrue, blankTrue, upload_tostatic/uploads)安装 # 1 python -m pip install Pillow # 2 pip install Pillow # 3 镜像 pip install pillow -i https://pypi.douban.com/simple再重新生成迁移文件、执行迁移 python manage.py makemigrations python manage.py migrate执行完之后进入admin后台管理页面点击添加 定义模型字段和约束及在Admin后台管理系统的表单情况 App\models.py # 其他约束 choices ((1, 青铜), (2, 白银), (3, 王者)) # 保存到数据库当中的是前面的数字123,显示出来的是青铜白银王者, #青铜白银王者在后台管理系统中会显示出来,实际上数据库存的是数字123 user_type models.IntegerField(choiceschoices, default1,nameutype, verbose_name用户类型) user_type2 models.IntegerField(default1, editableFalse,db_columnutype2, verbose_name用户类型2)再重新生成迁移文件、执行迁移 python manage.py makemigrations python manage.py migrateuser_type在后台系统显示user_type2不显示是因为editableFalse 三、models基本操作 一般的数据库操作流程 创建数据库设计表结构和字段连接Mysql数据库并编写数据访问层代码业务逻辑层去调用数据访问层执行数据库操作 Django通过Model操作数据库不管你数据库的类型是MySql或者SqliteDjango自动帮你生成相应数据库类型的SQL语句所以不需要关注SQL语句和类型对数据的操作Django帮我们自动完成。只要会写Model就可以了。     django使用对象关系映射 (Object Relational Mapping简称ORM) 框架去操控数据库。     ORM(Object Relational Mapping) 对象关系映射是一种程序技术用于实现面向对象编程语言里不同类型系统的数据之间的转换。 3.1 增 # ORM:模型 表类结构 - 表结构对象 - 表的一条数据类属性 - 表的字段# models基本操作 # 增:1) 创建对象实例,然后调用save方法:obj Author()obj.first_name zhangobj.last_name sanobj.save()2)创建对象并初始化,再调用save方法:obj Author(first_namezhang,last_namesan)obj.save()3)使用create方法Author.objects.create(first_namelilast_namesi)4)使用get_or_create方法可以防止重复Author.objects.get_or_create(first_namezhang, last_namesan)实践 我们单独再创建一个模型吧 App\models.py from django.db import models# 增删改查 class PersonModel(models.Model):name models.CharField(max_length30, uniqueTrue)age models.IntegerField(default18)# 表名class Meta:db_table person注意我们的name设置的是unique唯一的, 后面实践会用到 生成迁移文件、执行迁移 python manage.py makemigrations python manage.py migrate就不写子路由了根路由Day03DjangoPro01\urls.py from django.contrib import admin from django.urls import path from App.views import *urlpatterns [path(add/, add_person), # 添加path(admin/, admin.site.urls), ] 方式一 App\views.py from django.shortcuts import render, HttpResponsefrom App.models import *# 增加数据 def add_person(request):# 方式一try:p PersonModel()p.name 清风p.age 30p.save() # 同步到数据库表中except Exception as e:return HttpResponse(add fail! 添加失败)return HttpResponse(add success! 添加成功) 方式二 App\views.py def add_person(request):# 方式二try:p PersonModel(name微泫, age26)p.save() # 同步到数据库表中except Exception as e:return HttpResponse(add fail! 添加失败)return HttpResponse(add success! 添加成功)方式三 App\views.py def add_person(request):# 方式三try:PersonModel.objects.create(name意境, age26)except Exception as e:return HttpResponse(add fail! 添加失败)return HttpResponse(add success! 添加成功)方式四不会报错 App\views.py def add_person(request):# 方式四ret PersonModel.objects.get_or_create(name甘雨, age26)print(ret: , ret)# (PersonModel: PersonModel object (3), False) 失败# (PersonModel: PersonModel object (4), True) 成功print(type: , type(ret)) # class tupleprint(Bool: , ret[1]) # False 失败;True 成功if ret[1]:return HttpResponse(add success! 添加成功)return HttpResponse(add fail! 添加失败)测试 http://127.0.0.1:8000/add/ 第一次 第二次因为name我们设置的是唯一的所以添加失败 添加多条数据 App\views.py def add_person(request):# 添加多条数据for i in range(1, 10):PersonModel.objects.get_or_create(namef景{i}元, age18 i)return HttpResponse(add success! 添加成功)http://127.0.0.1:8000/add/ 3.2 删 使用Queryset的delete方法:# 删除指定条件的数据Author.objects.filter(first_namezhang).delete()# 删除所有数据Author.objects.all().delete()注意: objects不能直接调用delete方法。使用模型对象的delete方法:obj Author.objects.get(id5)obj.delete()根路由Day03DjangoPro01\urls.py path(del/, del_person), # 删除App\views.py def del_person(request):# 删除数据# 1. 先找到要删除的数据# 2. 然后删除# 删除一条数据try:p PersonModel.objects.first() # 第一条数据p.delete()except Exception as e:return HttpResponse(删除失败)return HttpResponse(删除成功)http://127.0.0.1:8000/del/ 删除多条数据 def del_person(request):# 删除多条数据try:PersonModel.objects.filter(age__gt23).delete() # 条件年龄 age 23 岁的except Exception as e:return HttpResponse(删除失败)return HttpResponse(删除成功)3.3 修改数据 Author.objects,filter(last_namedfdf).update(last_namesan) 模型没有定义update方法直接给字段赋值并调用save能实现update的功能比如:obj Author.objects.get(id3)obj.first_name zhangobj.save() save更新时会更新所有字段。如果只想更新某个字段减少数据库操作可以这么做:obj.first_name liobj.save(update_fields[first_name])Day03DjangoPro01\urls.py path(update/, updete_person)App\views.py def updete_person(request):# 修改数据# 1. 先找到要修改的数据# 2. 然后修改try:# 修改一条数据p PersonModel.objects.get(id7)p.age 110# p.save() # 同步到数据库表中p.save(update_fields[age]) # 指定更新的字段一定程度提高更新效率except Exception as e:return HttpResponse(修改失败)return HttpResponse(修改成功)http://127.0.0.1:8000/update 修改多条数据 def updete_person(request):# 修改多条数据try:PersonModel.objects.all().update(age66)except Exception as e:return HttpResponse(修改失败)return HttpResponse(修改成功)PersonModel.objects.all() 是一个查询集 3.4 查 get(): 获取单条数据Author.objects.get(id123)如果没有找到符合条件的对象会引发模型类.DoesNotExist异常如果找到多个会引发模型类.MultipleObjectsReturned 异常 first():返回查询集(QuerySet)中的第一个对象 last():返回查询集中的最后一个对象 count():返当前查询集中的对象个数 exists():判断查询集中是否有数据如果有数据返回True没有反之 a11():获取全部数据:Author.objects.al1() values(): 获取指定列的值可以传多个参数!返回包含字典的列表(保存了字段名和对应的值)Author.objects.all().values(password) values_list():获取指定列的值可以传多个参数!返回包含元组列表 (只保存值)Author.objects.al1().values_list(password)进阶操作:#获取个数Author.objects.filter(nameseven).count()Author.objects.filter(id__gt1)# 获取id大于1的值# select * from Author where id 1Author.objects.filter(id__gte1)# 获取id大于或等于1的值# select * from Author where id 1Author.objects.filter(id__lt10)# 获取id小于10的值# select * from Author where id 10Author.objects.filter(id__lte10)# 获取id小于或等于10的值# select * from Author where id 10Author.objects.filter(id__lt10, id__gt1) # 获取id大于1 且 小于10的值# select * from Author where id 10 and id 1Author.objects.filter(id__in[11, 22, 33] ) # 获id在11、22、33中的数据# select * from Author where id in (11,22,33)Author.objects.exclude(id__in[11, 22, 33]) # not in# select * from Author where id not in (11,22,33)Author.objects,filter(name__containsven) # contains (和数据库中like语法相同)# select * from Author where name like %ven%Author.objects.filter(name__icontainsven) # icontains大小写不敏感Author.objects.filter(name__regex^ven) # 正则匹配Author.objects.filter(name__iregex^ven) # 正则匹配,忽略大小写Author.objects.filter(age__range[10, 20])# 范围bettwen and 10-20# xx__startswith , xx__istartswith , xx__endswith, xx__iendswith:# 以什么开始以什么结束和上面一样带i的是大小写不敏感的其实不带i的也忽略大小写Author.objects.filter(nameseven).order_by(id)# asc升序Author.objects.filter(nameseven).order_by(-id)# desc降序Author.objects.a11()[10:20] # 切片取所有数据的10条到20条分页的时候用的到#下标从0开始不能为负数可以实现分页#手动分页page 页码per_page 每页数量 5第1页(page1):0-4 [0:5]第2页(page2):5-9 [5:10]第3页(page3):10-14 [10:15]第4页(page4):15-19 [15:20]...每一页数据范围:(page-1)*per_page: page*per_page #聚合使用aggregate()函数返回聚合函数的值Avg:平均值Count:数量Max:最大Min:最小Sum:求和from django.db.models import Count, Min, Max, SumAuthor.objects.aggregate(Max(age))注意双下划线__ Day03DjangoPro01\urls.py path(get/, get_person), # 查询get() 获取单条数据 如果没有找到符合条件的对象会引发模型类.DoesNotExist异常 如果找到多个会引发模型类.MultipleObjectsReturned 异常 App\views.py # 查询数据 def get_person(request):# get(): 得到一个对象一条数据p PersonModel.objects.get(id8)print(* * 52)print(p, type(p))print(p.name, p.age)print(* * 52)return HttpResponse(查询成功)http://127.0.0.1:8000/get/ 加入我调用get() ‘’id‘’不写会怎么样 # p PersonModel.objects.get(8) # 会报错pk:primary key p PersonModel.objects.get(pk8) # pk:primary key查询成功 注意1get()只能返回一个对象, 不然会报错 MultipleObjectsReturned p PersonModel.objects.get(age19) # 数据库只有一个age19,所以不会报错 p PersonModel.objects.get(age66) # 数据库有很多age66,所以报错 MultipleObjectsReturned注意2get() 查询结果不存在 DoesNotExist p PersonModel.objects.get(age1000) # 数据库没有age1000,所以报错 DoesNotExistall() 获取所有数据 App\views.py # 查询数据 def get_person(request):# 获取所有数据persons PersonModel.objects.all()print(persons, type(persons))# QuerySet 查询集# 可以遍历查询集for p in persons:print(p.name, p.age)return HttpResponse(查询成功)QuerySet [PersonModel: PersonModel object (7), PersonModel: PersonModel object (8),PersonModel: PersonModel object (9), PersonModel: PersonModel object (10),PersonModel: PersonModel object (11), PersonModel: PersonModel object (16)] class django.db.models.query.QuerySet 景1元 110 景2元 110 景3元 66 景4元 66 景5元 66 甘雨 19类型QuerySet 查询集 first() 返回第一条数据 返回queryset中匹配到的第一个对象如果没有匹配到对象则为None如果queryset没有定义排序则按主键自动排序。 all[0]: 与 first() 不同如果没有匹配到会报IndexError错误。 App\views.py def get_person(request):# 获取第一条数据p PersonModel.objects.first()print(p.name, p.age)return HttpResponse(查询成功)last() 返回最后一条数据 App\views.py def get_person(request):# 获取最后一条数据p PersonModel.objects.last()print(p.name, p.age)return HttpResponse(查询成功)filter() 过滤 使用最多。类似数据库中的where语句 App\views.py def get_person(request):persons PersonModel.objects.filter() # 默认没有条件, 得到所有数据persons PersonModel.objects.filter(age__gt100) # age100persons PersonModel.objects.filter(age__gte100) # age100persons PersonModel.objects.filter(age__lt100) # age100persons PersonModel.objects.filter(age__lte100) # age100persons PersonModel.objects.filter(age110) # age110print(persons.filter().filter())for p in persons:print(, p.name, p.age)return HttpResponse(查询成功)就算只拿到一个数据它也是一个查询集 QuerySet 。 查询集 QuerySet 可以继续去查询 filter 内部会返回self 所以它可以做链式调用。 count(): 返当前查询集中的对象个数 exists():判断查询集中是否有数据 App\views.py def get_person(request):persons PersonModel.objects.filter(age__gt100) # age100for p in persons:print(, p.name, p.age)print(persons.exists()) # 查询集是否存在数据如果存在则为True否则为Falseprint(persons.count()) # 查询集中的数据个数return HttpResponse(查询成功)values(): 获取指定列的值 可以传多个参数!返回包含字典的列表(保存了字段名和对应的值) App\models.py class PersonModel(models.Model):name models.CharField(max_length30, uniqueTrue)age models.IntegerField(default18)# 表名class Meta:db_table persondef __str__(self):return f{self.name}-{self.age}def __repr__(self):return f{self.name}--{self.age}__str__方法大家应该都不陌生它类似于Java当中的 toString 方法可以根据我们的需要返回实例转化成字符串之后的结果。 __str__ 和 __repr__ 这两个函数都是将一个实例转成字符串。但是不同的是两者的使用场景不同其中__str__更加侧重展示。所以当我们print输出给用户或者使用str函数进行类型转化的时候Python都会默认优先调用__str__函数。而__repr__更侧重于这个实例的报告除了实例当中的内容之外我们往往还会附上它的类相关的信息因为这些内容是给开发者看的。所以当我们在交互式窗口输出的时候它会优先调用__repr__。 App\views.py def get_person(request):persons PersonModel.objects.filter() # 默认没有条件, 得到所有数据print(persons: , persons)print(list(persons): , list(persons)) # 将查询集强制转换成列表# values() : 列表套字典,包括字段和值print(persons.values(): , persons.values()) # 列表套字典print(persons.values(name): , persons.values(name))print(persons.values(name, age): , persons.values(name, age))# values_list() : 列表套元组,只有值print(persons.values_list(): , persons.values_list())print(persons.values_list(name, age): , persons.values_list(name, age)) # 用法跟values一样return HttpResponse(查询成功)结果 persons: QuerySet [景1元--110, 景2元--120, 景3元--30, 景4元--66, 景5元--20, 甘雨--19] list(persons): [景1元--110, 景2元--120, 景3元--30, 景4元--66, 景5元--20, 甘雨--19] persons.values(): QuerySet [{id: 7, name: 景1元, age: 110}, {id: 8, name: 景2元, age: 120}, {id: 9, name: 景3元, age: 30}, {id: 10, name: 景4元, age: 66}, {id: 11, name: 景5元, age: 20}, {id: 16, name: 甘雨, age: 19}] persons.values(name): QuerySet [{name: 景1元}, {name: 景2元}, {name: 景3元}, {name: 景4元}, {name: 景5元}, {name: 甘雨}] persons.values(name, age): QuerySet [{name: 景1元, age: 110}, {name: 景2元, age: 120}, {name: 景3元, age: 30}, {name: 景4元, age: 66}, {name: 景5元, age: 20}, {name: 甘雨, age: 19}] persons.values_list(): QuerySet [(7, 景1元, 110), (8, 景2元, 120), (9, 景3元, 30), (10, 景4元, 66), (11, 景5元, 20), (16, 甘雨, 19)] persons.values_list(name, age): QuerySet [(景1元, 110), (景2元, 120), (景3元, 30), (景4元, 66), (景5元, 20), (甘雨, 19)]values_list():获取指定列的值 可以传多个参数!返回包含元组列表 (只保存值) exclude() 排除取反 App\views.py def get_person(request):person PersonModel.objects.filter(age__in[20, 50, 30]) # inprint(person: , person)person PersonModel.objects.exclude(age__in[20, 50, 30]) # not inprint(person: , person)return HttpResponse(查询成功)聚合 使用aggregate()函数返回聚合函数的值     Avg:平均值     Count:数量     Max:最大     Min:最小     Sum:求和 from django.db.models import Count, Min, Max, Sum PersonModel.objects.aggregate(Max(‘age’)) aggregate 是聚合的意思 App\views.py from django.db.models import Count, Min, Max, Sum, Avg def get_person(request):# 聚合函数result PersonModel.objects.aggregate(Max(age)) # 最大值print(result) # {age__max: 120}print(result[age__max]) # 120return HttpResponse(查询成功)def get_person(request):# 聚合函数result PersonModel.objects.aggregate(Max(age)) # 最大值 {age__max: 120}result PersonModel.objects.aggregate(Min(age)) # 最小值 {age__min: 19}result PersonModel.objects.aggregate(Sum(age)) # 求和 {age__sum: 365}result PersonModel.objects.aggregate(Avg(age)) # 求平均 {age__avg: 60.833333333333336}result PersonModel.objects.aggregate(Count(age)) # 统计个数 {age__count: 6}print(result)return HttpResponse(查询成功)排序 PersonModel.objects.all().order_by() App\models.py class PersonModel(models.Model):name models.CharField(max_length30, uniqueTrue)age models.IntegerField(default18)# 表名class Meta:db_table persondef __str__(self):return f{self.id}-{self.name}-{self.age}def __repr__(self):return f{self.id}--{self.name}--{self.age}def get_person(request):# 聚合函数person PersonModel.objects.all().order_by(age) # 默认升序person PersonModel.objects.all().order_by(age, id) # 先age做升序然后如果一样的用id来升序# 想要降序就加个负号-person PersonModel.objects.all().order_by(age, -id) # 先age做升序然后如果一样的用id来降序print(person)return HttpResponse(查询成功)分页功能 手动分页 Day03DjangoPro01\urls.py path(paginate/int:page/int:per_page/, paginate, namepaginate), # 分页功能App\views.py import math # 分页功能 def paginate(request, page1, per_page10):# 页码page1# 每页数据数量per_page10思路分页功能数据[1,2,3,...,47]第几页 数据范围 下标范围 切片page1, 1 ~ 10 0 ~ 9 [0:10]page2, 11 ~ 20 10 ~ 19 [10:20]page3, 21 ~ 30 20 ~ 29 [20:30]...pagen, [(n-1) * 10 : n * 10]pagepage, [(page-1)*per_page : page*per_page]# 实现分页功能persons PersonModel.objects.all()persons persons[(page - 1) * per_page:page * per_page]# 求总页数total PersonModel.objects.count() # 总数据条数total_page math.ceil(total / per_page) # 总页数可能是小数47/10,所以需要向上取整pages range(1, total_page 1)return render(request, paginate.html, {persons: persons,pages: pages,per_page: per_page}) templates\paginate.html !DOCTYPE html html langen headmeta charsetUTF-8title分页功能的实现/titlestyleul{list-style: none;padding: 0;}.btns{display: flex ;align-content: center;}.btns li{margin: 5px;}/style /head bodyh2分页功能/h2hr页数{{ per_page }}ul classbtns {# li#} {# a href{% url paginate 1 10 %}button1/button/a#} {# /li#} {# li#} {# a href{% url paginate 2 10 %}button2/button/a#} {# /li#} {# li#} {# a href{% url paginate 3 10 %}button3/button/a#} {# /li#}{% for page in pages %}lia href{% url paginate page per_page %}button{{ page }}/button/a/li{% endfor %}/ulhrul{% for person in persons %}li{{ person.name }} - {{ person.age }}/li{% endfor %}/ul /body /html浏览器http://127.0.0.1:8000/paginate/1/10/ 这就是最基本的分页功能啦 Django中的自动分页器 Day03DjangoPro01\urls.py path(paginate2/int:page/, paginate2, namepaginate2),App\views.py # 分页器自动分页 from django.core.paginator import Paginatordef paginate2(request, page1):per_page 10 # 每页数据数量all_data PersonModel.objects.all()# 使用分页器paginator Paginator(all_data, per_page)persons paginator.page(page) # 获取第page页的数据pages paginator.page_range # 页码的范围可以遍历data {persons: persons,pages: pages,per_page: per_page}return render(request, paginate2.html, data)新建一个 templates\paginate2.html !DOCTYPE html html langen headmeta charsetUTF-8title分页器/titlestyleul{list-style: none;padding: 0;}.btns{display: flex ;align-content: center;}.btns li{margin: 5px;}/style /head bodyh2分页器/h2hr页数{{ per_page }}ul classbtns{% for page in pages %}lia href{% url paginate2 page %}button{{ page }}/button/a/li{% endfor %}/ulhrul{% for person in persons %}li{{ person.name }} - {{ person.age }}/li{% endfor %}/ul /body /html浏览器 http://127.0.0.1:8000/paginate2/1/ 四、Django模型进阶 MYSQL和SQLite只是数据库不一样配置不一样其他的是一样的。 注意我的 Django版本是4.2MYSQL是8.0Python 3.11.3 4.1 配置MySQL 1.安装mysql2.MySQL驱动使用mysqlclientpip install mysqlclient(如果上面的命令安装失败则尝试使用国内豆瓣源安装:pip install -i https://pypi.douban.com/simple mysqlclient)(Linux Ubuntu下需要先安装:apt install libmysqld-dev再安装:apt install libmysqld-dev)3.在Django中配置和使用mysq1数据库 使用mysql数据库settings中配置如下DATABASES{default:{ENGINE:django.db.backends.mysql,NAME:mydb,USER:root,PASSWORD:123456,HOST:127.0.0.1,PORT:3306,}}实践 workon envdjango4 pip install mysqlclient新建一个新的项目Day04DjangoPro01 DATABASES {# MySQL 数据库配置default: {ENGINE: django.db.backends.mysql,NAME: mydb, # 数据库名字USER: root, # 数据库的用户名PASSWORD: 123456, # 用户名对应的密码HOST: 127.0.0.1, # 数据库的主机IPPORT: 3306, # 端口}# SQLite 数据库配置# default: {# ENGINE: django.db.backends.sqlite3,# NAME: BASE_DIR / db.sqlite3,# } }mysql -u root -p 输密码 我的是 123456 看一下数据库 show databases 创建新的数据库 create datadase 数据库名 charsetutf8;注意这个数据库要求是一个空的数据库 使用数据库use 数据库名show tables;怎么安装MySQL这里就不写了, 我偷懒就直接用小Pphpstudy吧。网盘链接https://pan.baidu.com/s/1Hc_oHRem4pY3VSmqCrbCjw?pwd6666 提取码6666 我们知道Django项目里面它自带本身有很多迁移文件我们是不是可以把内部的迁移文件生成到数据库里面去呀 生成迁移文件: python manage.py makemigrations 执行迁移: python manage.py migrate 然后就成功啦 报错1django.db.utils.NotSupportedError: MySQL 8 or later is required (found 5.7.26). 说是MYSQL兼容问题 解决办法数据库更新到 8.0就好啦 报错2RuntimeWarning: Got an error checking a consistent migration history performed for database connection ‘default’: (1045, “Access denied for user ‘root’‘localhost’ (using password: YES)”) 用户密码错了所以连接不上。 4.2 多模块关联关系 多个模块关联关联分类- ForeignKey:一对多将字段定义在多的端中- ManyToManyField: 多对多将字段定义在两端的任意一端中- OneToOneField:一对一将字段定义在任意一端中一对多关系举例说明 (一对一 多对多类似) :一个班级可以有多个学生一个学生只能属于一个班级class Grade(models.Model):name models.CharField(max_length20)class Student(models.Model):name models.CharField(max_length20)grade models.ForeignKey(Grade)对象的使用:正向 (在Student这边有grade属性的这一边):获取学生所在班级(对象):stu.grade获取学生所在班级的属性:stu.grade.name反向(在Grade这边):获取班级的所有学生(获取Manager对象):grade.student_set获取班级的所有学生(获取QuerySet查询集): grade.student_set.all()filter(),get()等操作中的使用:正向(在Student这边有grade属性的这一边)Student.objects.filter(属性__name1)如: Student.objects.filter(grade__name1)反向(在Grade这边)Grade.objects.filter(类名小写__id7)如: Grade.objects.filter(student__id7)xx_set 其实是一个管理器 类似于 objects 通过它 .filter() 或者 .all() 就可以拿到所有查询到的结果叫查询集。 4.3 Model连表结构 一对多: models.ForeignKey(其他表) 多对多: models.ManyToManyField(其他表) 一对一: models.OneToOneField(其他表) 应用场景:一对多:当一张表中创建一行数据时有一个单选的下拉框(可以被重复选择)例如: 创建用户信息时候需要选择一个用户类型[普通用户][金牌用户][铂金用户]多对多:在某表中创建一行数据时有一个可以多选的下拉框。 (猫眼App淘票票格拉瓦电影)例如:创建用户信息需要为用户指定多个爱好。一对一:在某表中创建一行数据时有一个单选的下拉框(下拉框中的内容被用过一次就消失了)例如:有个身份证表有个person表。每个人只能有一张身份证一张身份证也只能对应一个人这就是一对一关系。4.3.1 一对多关联 一对多关系即外键为什么要用一对多。先来看一个例子。有一个用户信息表其中有个用户类型字段存储用户的用户类型。如下class UserInfo(models.Model):username models.CharField(max_length32)age models.IntegerField()user_type models.CharField(max_length10)不使用外键时用户类型存储在每一行数据中。如使用外键则只需要存储关联表的id即可能够节省大量的存储空间。同时使用外键有利于维持数据完整性和一致性.当然也有缺点数据库设计变的更复杂了。每次做DELETE 或者UPDATE都必须考虑外键约束。刚才的例子使用外键的情况: 单独定义一个用户类型表:class UserType(models.Model):caption models.CharField(max_length32)class UserInfo(models.Model):user_type models.ForeignKey(UserType)username models.CharField(max_length32)age models.IntegerField()我们约定:正向操作: ForeignKey在UserInfo表里如果根据UserInfo去操作就是正向操作。反向操作: ForeignKey不在UserType里如果根据UserType去操作就是反向操作。一对多的关系的增删改查:正向操作:增1)创建对象实例然后调用save方法obj UserInfo(nameli,age44, user_type_id2)obj.save()2)使用create方法UserInfo.objects.create(nameli,age44,user_type_id2)3)使用get_or_create方法可以防止重复UserInfo.objects.get_or_create(nameli,age55,user_type_id2)4)使用字典dic {name:zhangsan, age:18, user_type_id:3}UserInfo.objects.create(**dic)5)通过对象添加usertype UserType.objects.get(id1)UserInfo.objects.create(nameli,age55,user_typeusertype)删和普通模式一样删除即可。如:UserInfo,objects.filter(id1).delete()改和普通模式一样修改即可。如:UserInfo.objects.filter(id2).update(user_type_id4)查正向查找所有用户类型为钻石用户的用户使用双下划线:users UserInfo.objects,filter(user_type__caption__contains钻石)# __contains是过滤条件 like %钻石%正向获取关联表中的属性可以直接使用点.语法比如:获取users查询集中第一个用户的caption:users[0].user_type.caption反向操作:增(一般使用正向增即可)通过usertype来创建userinfo1)通过userinfo_set的create方法#获取usertype实例ut UserType.objects.get(id2)#创建userinfout.userinfo_set.create(namesmith,age33)删删除操作可以在定义外键关系的时候通过on_delete参数来配置删除时做的操作。on_delete参数主要有以下几个可选值:models.CASCADE 默认值(Django1.11),表示级联删除即删除UserType时,相关联的UserInfo也会被删除。models.PROTECT 保护模式, 阻止级联删除。如果UserType还有关联的User存在那么他就阻止你不让你删除。删除的时候可能报错。models.SET_NULL 置空模式设为nullnullTrue参数必须具备。删除UserType的时候不会将所关联的用户删掉而是把关联的User外键的值置空models.SET_DEFAULT 置默认值 设为默认值default参数必须具备。如果删除UserType关联的User外键的值不置空设置成指定的值models.SET(函数名) 删除的时候重新动态指向一个实体访问对应元素可传函数models.DO_NOTHING 什么也不做。 (Django1.11)。外键不会动但是这样关联的外键就是错误的。注意:修改on_delete参数之后需要重新同步数据库如果使用的话。需要重新迁移一般建议 PROTECT 或者 SET_NULL 或者 SET_DEFAULT改和普通模式一样不会影响级联表查通过usertype对象来查用户类型为1的用户有哪些objUserType.objects.get(id1)obj.userinfo_set.all()可以通过在定义foreignkey时指定related_name来修改默认的userinfo_set,比如指定related_name为infouser_type models.ForeignKey(UserType, related_nameinfo)指定related_name之后反向查的时候就变成了obj.info.all()获取用户类型为1且用户名为shuaige的用户obj.info.filter(usernameshuaige)外键关系中django自动给usertype加了一个叫做userinfo的属性。使用双下划线。可以通过userinfo提供的信息来查usertype (了解)user_type_obj UserType.objects.get(userinfo__usernamezs)生成迁移文件: python manage.py makemigrations 执行迁移: python manage.py migrate 实践 OneToMany\models.py from django.db import models# 一对多 1:N # 用户类型:用户 1:N # 一种用户类型: 可以有多个用户 # 一个用户:只属于一个用户类型# 用户类型 class UserType(models.Model):name models.CharField(max_length30)# 用户 class User(models.Model):name models.CharField(max_length30)age models.IntegerField(default18)# 外键user_type models.ForeignKey(UserType, on_deletemodels.CASCADE)# models.CASCADE 级联删除即删除UserType时,相关联的User也会被删除。 生成迁移文件: python manage.py makemigrations 执行迁移: python manage.py migrate 注意用户表User中我们代码写的是user_type但是数据库写的是user_type_id这个有区别它的类型跟 用户类型UserType 的主键是一样的。我们在后面使用的时候可以使用user_type也可以使用user_type_id但其实得到user_type呢相当于得到上面UserType对象了 得到这个对象之后再去 .id .name是可以的。 增加数据 OneToMany\views.py from django.shortcuts import render, HttpResponse from OneToMany.models import *# 一对多关系# 添加数据 def add_user(request):# 给UserType添加数据user_types [青铜, 白银, 黄金, 钻石]for name in user_types:UserType.objects.create(namename)return HttpResponse(添加成功) 根路由Day04DjangoPro01\urls.py from django.contrib import admin from django.urls import path from OneToMany import views as onetomany_viewurlpatterns [path(admin/, admin.site.urls),# onetomanypath(onetomany/adduser/, onetomany_view.add_user ), ] 运行python .\manage.py runserver http://127.0.0.1:8000/onetomany/adduser/ 添加完之后代码注释了现在写添加User表OneToMany\views.py 第一种用 user_type_id id def add_user(request):# # 用完就注释# # 给UserType添加数据# user_types [青铜, 白银, 黄金, 钻石]# for name in user_types:# UserType.objects.create(namename)# 给User表添加数据for i in range(11, 30):User.objects.create(namef清风-{i},agei,user_type_idi % 4 1) # i % 4 1 1~4return HttpResponse(添加成功)http://127.0.0.1:8000/onetomany/adduser/ 第二种用 user_type 用户类型的对象 def add_user(request):# # 用完就注释# # 给UserType添加数据# user_types [青铜, 白银, 黄金, 钻石]# for name in user_types:# UserType.objects.create(namename)# 给User表添加数据for i in range(11, 30):# User.objects.create(namef清风-{i}, agei,# user_type_idi % 4 1) # i % 4 1 1~4User.objects.create(namef微泫-{i}, agei 100,user_typeUserType.objects.get(pki % 4 1))return HttpResponse(添加成功)http://127.0.0.1:8000/onetomany/adduser/ 删除数据 根路由Day04DjangoPro01\urls.py path(onetomany/deluser/, onetomany_view.del_user),OneToMany\views.py 删除用户数据 # 删除数据 def del_user(request):# 删除User数据User.objects.filter(id6).delete()return HttpResponse(删除成功)http://127.0.0.1:8000/onetomany/deluser/ 删除UserType数据 def del_user(request):# 删除User数据# User.objects.filter(id6).delete()# 删除UserType数据UserType.objects.filter(id2).delete()return HttpResponse(删除成功)http://127.0.0.1:8000/onetomany/deluser/ 执行之后可以观察到UserType表删除了id2的数据User表删除了外键user_type_id是2的数据。 因为前面Models设置了 models.CASCADE 表示级联删除即删除UserType时,相关联的User也会被删除。 试试其他的模式 OneToMany\models.py user_type models.ForeignKey(UserType, on_deletemodels.PROTECT) # 保护模式浏览器 http://127.0.0.1:8000/onetomany/deluser/ user_type models.ForeignKey(UserType, on_deletemodels.SET_NULL, nullTrue) # 置空模式user_type models.ForeignKey(UserType, on_deletemodels.SET_DEFAULT, default1) # 置默模式def fn():return 4# 用户 class User(models.Model):name models.CharField(max_length30)age models.IntegerField(default18)# 外键# user_type models.ForeignKey(UserType, on_deletemodels.CASCADE)# models.CASCADE 级联删除即删除UserType时,相关联的User也会被删除。# user_type models.ForeignKey(UserType, on_deletemodels.PROTECT) # 保护模式# user_type models.ForeignKey(UserType, on_deletemodels.SET_NULL, nullTrue) # 置空模式# user_type models.ForeignKey(UserType, on_deletemodels.SET_DEFAULT, default1) # 置默模式user_type models.ForeignKey(UserType, on_deletemodels.SET(fn)) # 删除的时候重新动态指向一个实体访问对应元素可传函数 其实models.SET(函数名) 跟 models.SET_DEFAULT 差不多 user_type models.ForeignKey(UserType, on_deletemodels.DO_NOTHING) # 什么都不做测试完我们还是用 user_type models.ForeignKey(UserType, on_deletemodels.PROTECT) # 保护模式 吧 生成迁移文件: python manage.py makemigrations 执行迁移: python manage.py migrate 修改数据 和普通模式一样不会影响级联表 根路由Day04DjangoPro01\urls.py path(onetomany/updateuser/, onetomany_view.update_user),OneToMany\views.py # 修改数据 def update_user(request):# 修改UserTypeUserType.objects.filter(id1).update(name王者)return HttpResponse(修改成功)def update_user(request):# 修改UserType# UserType.objects.filter(id1).update(name王者)# 修改UserUser.objects.filter(id2).update(age1000)return HttpResponse(修改成功)http://127.0.0.1:8000/onetomany/updateuser/ 查询数据 根路由Day04DjangoPro01\urls.py path(onetomany/getuser/, onetomany_view.get_user),正向查询有属性的地方直接查询写了外键的地方直接查就是正向查询通过 用户User 查找他所对应的 用户类型UserType 反向查询通过 用户类型UserType 查找 用户User OneToMany\views.py 前三种查询 1、正向查询 2、反向查询     UserType对象.user_set.all()     主表对象.从表名_set.all() 3、在filter中      User.objects.filter(UserType)     相比于第2种_set , 从时间成本来考虑的话还是使用 filter 筛选效率更高一些。 # 查询数据 def get_user(request):# 1.正向查询通过用户查找用户类型user User.objects.get(id2)print(用户:, user.name, user.age, user.user_type, user.user_type_id)# user.user_type UserType对象print(用户所属的类型:, user.user_type.id, user.user_type.name) # User所属UserType的所有数据print(- * 60)# 2.反向查询通过用户类型查找用户utype UserType.objects.get(pk1)print(UserType自己的属性, utype.id, utype.name)# user_set: 是内部自动生成的属性, 可以让你反向查询到所有用户User集合print(utype.user_set) # OneToMany.User.None 你可以认为它是一个管理对象print(type(utype.user_set)) # RelatedManager 关联的管理器对象# class django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.locals.RelatedManagerprint(utype.user_set.all()) # 所有数据的 查询集 QuerySetprint( * 60)# 3.在filter中还可以这么用# 比如查找用户类型名称为黄金的所有用户users User.objects.filter(user_typeUserType.objects.get(name黄金)) # 传入UserType对象users User.objects.filter(user_type_id4) # 传入user_type_idusers User.objects.filter(user_type__name黄金) # 传入UserType对象的name属性作为条件# filter(user_type__name黄金) 加两个下划线__反向引用去查找print(users)return HttpResponse(查询成功)第四种查询 4、related_name: 关联名称 related_name 是我们用于反向查找的内容。通常为所有外键提供 related_name 是一个好习惯而不是使用 Django 的默认相关名称。 related_name 默认是 小写外键的表名_set 或者也可以这么理解 子表的表名小写_set 主表 UserType表表中有一个主键被其他表用来当外键的表。 从表子表User表把另外一个表中的主键当做自己的外键的表。 主表对象.从表名_set.all()     主表对象.设置的related_name.all() OneToMany\models.py class User(models.Model):name models.CharField(max_length30)age models.IntegerField(default18)# 外键# related_name: 关联名称,设置反向查找的名称,原本 反向查找 使用的是user_set改为usersuser_type models.ForeignKey(UserType, on_deletemodels.PROTECT,related_nameusers # 建议使用)生成迁移文件: python manage.py makemigrations 执行迁移: python manage.py migrate OneToMany\views.py def get_user(request):print( * 60)# 4.related_name: 关联名称utype UserType.objects.get(pk1)# print(utype.user_set.all()) # 会报错 AttributeError UserType object has no attribute user_set# 使用了related_name就不可以在使用带_set的属性print(utype.users.all()) # QuerySet [User: User object (2), ...] return HttpResponse(查询成功)执行完迁移之后现在我们不能再用user_set了使用就会报错AttributeError ‘UserType’ object has no attribute ‘user_set’。如果我们使用了related_name原来的属性user_set就不能使用了。 使用了related_name就不可以在使用带_set的属性 4.3.2 多对多关联 多对多其实就是两个一对多如果不在乎中间表 我们可以直接建两边的表中间的不用管。 多对多关系针对多对多关系django会自动创建第三张表。也可以通过through参数指定第三张表。用户和组是典型的多对多关系:class Group(models.Model):name models.CharField(max_length20)def __str__(self):return self.nameclass User(models.Model):name models.CharField(max_length64)password models.CharField(max_length64)groups models.ManyToManyField(Group)def __str__(self):return self.name操作:增:先分别创建user和group再使用add关联u User(nameaa, password123)u.save()g Group(nameg5)g.save()通过Manager对象使用add()方法u.groups.add(g) 或 g.user_set.add(u)删:和一对多类似删除user或group会级联删除user_groups表中的关联数据改:和一对多类似只修改当前表查:正向:查询id2的用户所在的所有组groupu User.objects.get(id2)u.groups.al1()反向:查询id1的组中包含的所有用户g Group.objects.get(id1)g.user_set.all()实践 新建一个应用 叫 ManyToMany python manage.py startapp ManyToMany 创建好之后一定要记得注册 Day04DjangoPro01\settings.py ManyToMany\models.py from django.db import models# 多对多 # 用户:电影 N:M # 一个用户可以收藏多部电影,一部电影可以被不同用户收藏# 电影 class Movie(models.Model):name models.CharField(max_length52)duration models.IntegerField(default90) # 电影时长:默认90分钟# 用户 class User(models.Model):name models.CharField(max_length30)age models.IntegerField(default18)# 多对多关系movies models.ManyToManyField(Movie) 生成迁移文件: python manage.py makemigrations 执行迁移: python manage.py migrate 可以看到创建了三个表。 添加数据 子路由不写了直接写根路由上吧Day04DjangoPro01\urls.py 写视图函数ManyToMany\views.py from django.shortcuts import render, HttpResponse from ManyToMany.models import *# 多对多# 增加数据 def add(request):# 添加User数据for i in range(1, 10):User.objects.create(namef张三{i}, agei)# 添加Moviefor i in range(1, 10):Movie.objects.create(namef消失的她{i}, duration100i)return HttpResponse(添加成功)http://127.0.0.1:8000/manytomany/add/ 添加完这两个表之后我们要添加中间表的数据 写法一 ManyToMany\views.py def add(request):# 让 张三1 收藏 消失的她1user User.objects.get(name张三1)movie Movie.objects.get(name消失的她1)# 添加收藏user.movies.add(movie) # 用户收藏电影return HttpResponse(添加成功)浏览器 http://127.0.0.1:8000/manytomany/add/ 可以多刷新几次试试添加是不会重复的 写法二 ManyToMany\views.py def add(request):# 让 张三1 收藏 消失的她2user User.objects.get(name张三1)movie Movie.objects.get(name消失的她2)# 添加收藏# user.movies.add(movie) # 用户收藏电影movie.user_set.add(user) # 让用户收藏电影return HttpResponse(添加成功)浏览器 http://127.0.0.1:8000/manytomany/add/ 手动添加点数据吧 修改数据 一般多对多关系中不涉及到中间表修改如果要对单表修改那就跟前面的一样了。 删除数据 Day04DjangoPro01\urls.py path(manytomany/delete/, manytomany_view.delete),删除电影 ManyToMany\views.py def delete(request):# 删除User# User.objects.get(id9).delete()# 删除Movie# Movie.objects.get(id9).delete()# 删除中间表user User.objects.get(name张三1)user.movies.filter(name消失的她2).delete() # 删除用户收藏的电影# user.movies.filter 这里已经到了Movie,所以可以使用name,这个name是Movie的namereturn HttpResponse(删除成功)http://127.0.0.1:8000/manytomany/delete/ 效果电影表中 name消失的她2 都被删了中间表有关 电影消失的她2 的数据 也被删了。 注意 假如 中间表 张三1 没有收藏 消失的她2 的记录中间表、电影表那么就不会有任何效果。 删除用户 效果其实类似反过来就好了 ManyToMany\views.py def delete(request):movie Movie.objects.get(name消失的她1)movie.user_set.filter(name张三1).delete()return HttpResponse(删除成功)http://127.0.0.1:8000/manytomany/delete/ 查询 Day04DjangoPro01\urls.py path(manytomany/get/, manytomany_view.get_user_movie),ManyToMany\views.py # 查询数据 def get_user_movie(request):# 获取用户收藏的所有电影user User.objects.get(name张三1)print(user.movies.all())# 获取电影被哪些用户收藏了movie Movie.objects.get(name消失的她1)print(movie.user_set.all())return HttpResponse(查询成功)http://127.0.0.1:8000/manytomany/get/ 注意我的数据表里的数据我另外又加回来了     电影1 消失的她1     用户1 张三1 4.3.3 一对一 一对一关系一对一不是数据库的一个连表操作而是Django独有的一个连表操作。一对一关系相当于是特殊的一对多关系只是相当于加了uniqueTrue。一个人只能有一张身份证一张身份证对应一个人是一个典型的一对一关系。class IdCard(models.Model):idnum models.IntegerField()def __str__(self):return str(self.idnum)class Person(models.Model):idcard models.OneToOneField(IdCard) # 外键name models.CharField(max_length20)def __str__(self):return self.name一对一关系比较简单。两种表互相都有对方。比如: lisi Person.objects.get(id3) lisi.idcardIdCard: 123456 ids IdCard.objects.get(id3) ids.personPerson: lisi实践 这里演示查询就可以了其他的跟一对多差不多。 新建一个应用 叫 OneToOne python manage.py startapp OneToOne 创建好之后一定要记得注册 Day04DjangoPro01\settings.py OneToOne\models.py from django.db import models# 身份证 class IDCard(models.Model):idcard_num models.CharField(max_length18, uniqueTrue)address models.CharField(max_length200)# 用户表 class Person(models.Model):name models.CharField(max_length20)age models.IntegerField(default18)sex models.BooleanField(defaultTrue) # True是男# 一对一关系idcard models.OneToOneField(IDCard, on_deletemodels.PROTECT) # 外键生成迁移文件: python manage.py makemigrations 执行迁移: python manage.py migrate 一对一 和 一对多 一样 只有两个表不会产生中间表。 注意 Unique唯一约束 数据库插入点数据 增删改 和一对多是类似的。 查询 和一对多是类似的不同的是一对一得到的是 对方的对象 而不是 一个查询集。 Day04DjangoPro01\urls.py OneToOne\views.py from django.shortcuts import render, HttpResponse from OneToOne.models import *# 一对一# 查询 def get(request):# 查找某个用户对应的身份证信息person Person.objects.get(pk1)print(person.idcard) # 对象 IDCard object (1)print(person.idcard.idcard_num, person.idcard.address)# 查找身份证对应的用户idcard IDCard.objects.get(pk2)print(idcard.person) # 对象 Person object (2)# 注意不是idcard.person_setprint(idcard.person.name, idcard.person.age, idcard.person.sex)return HttpResponse(查询成功) 注意不是idcard.person_set 是 idcard.person http://127.0.0.1:8000/onetoone/get/
http://www.tj-hxxt.cn/news/232161.html

相关文章:

  • 撩人的网站怎么做网站建设需要配置环境么
  • 云南省网站备案要求做背景图获取网站
  • 怎么样通过做网站赚钱吗安徽高端网站建设
  • 楚州网站开发微信商城小程序多少钱
  • 南宁建网站龙岗网站建设企业
  • 网站文章推广如何建设小说网站
  • 巨鹿网站建设网络公司中国万网域名注册服务内容
  • 织梦网站被做跳转网站主机ip查询
  • 加人引流加人网站怎么做黄冈网站制作
  • 网站建设自查情况报告莘庄做网站
  • js判断是手机还是电脑访问网站垂直电商平台有哪些?
  • 宣传式网站网页设计培训传智教育
  • 嘉兴城乡建设网站做报纸版式的网站
  • 呼和浩特做网站的朝阳网站建设 慈云寺
  • 湘潭找工作网站个人的网站建设的目的
  • 哪家成都公司做网站网页游戏平台排名前10名
  • 网站建设和网站开发的区别深圳手机网站公司
  • 网站添加属性物流网站的功能与特色
  • 网络营销做得好的产品什么网站做优化最好?
  • 做网站的联系方式免费培训机构
  • 淘宝客网站WordPress最新注册公司流程及费用
  • 网站设计网页首页介绍如何搭建微信公众号平台
  • 直播网站可以做毕设吗网页模板网站有那些
  • 沧州做网站哪家好网页设计ppt模板
  • 东莞整站排名苏州品牌网站建设
  • 织梦网站后台模板wordpress移动
  • pdf怎么做电子书下载网站买了域名怎么做网站
  • 中国工商银行网站建设WordPress勾选评论
  • 哈尔滨房地产型网站建设资源共享课程网站开发毕业设计
  • 兰州展柜公司网站建设邯郸市网站建设多少钱