Django-model基础
Posted East-L
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django-model基础相关的知识,希望对你有一定的参考价值。
一、OPM
映射关系:
表名 <-------> 类名 字段 <-------> 属性 表记录 <------->类实例对象
二、创建表(建立模型)
实例:我们来假定下面这些概念,字段和关系
作者模型:一个作者有姓名和年龄。
作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息。作者详情模型和作者模型之间是一对一的关系(one-to-one)
出版商模型:出版商有名称,所在城市以及email。
书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)。
class Author(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) age=models.IntegerField() # 与AuthorDetail建立一对一的关系 authorDetail=models.OneToOneField(to="AuthorDetail") class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday=models.DateField() telephone=models.BigIntegerField() addr=models.CharField( max_length=64) class Publish(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField( max_length=32) publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2) keepNum=models.IntegerField()<br> commentNum=models.IntegerField() # 与Publish建立一对多的关系,外键字段建立在多的一方 publish=models.ForeignKey(to="Publish",to_field="nid") # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors=models.ManyToManyField(to=‘Author‘)
三、表记录操作
(1)单表记录的操作:
1 添加 #方式1: obj=models.表名(**kwargs) obj.save() #方式2: models.表名.objects.create(**kwargs) 2 修改: #方式1: obj=models.表名.objects.fllter(name="python")[0] obj.name="Java" obj.save # 方式2 update models.表名.objects.fllter(name="python").update(**kwargs) 3 删除: models.表名.objects.fllter(name="python").delete() 4 查询: models.表名.objects.all() # QuerySet集合对象 [obj1,obj2,...] models.表名.objects.filter(**kwargs) # QuerySet集合对象 models.表名.objects.get(**kwargs) # model对象 models.表名.objects.all().values(*arg) # QuerySet集合对象[{"":""},{"":""}] models.表名.objects.all().values_list(*arg) # QuerySet集合对象[(),()] models.表名.objects.exclude(**kwargs) # QuerySet集合对象 models.表名.objects.order_by(*arg) # QuerySet集合对象 models.表名.objects.distinct(*arg) # QuerySet集合对象 models.表名.objects.filter(**kwargs).first() # model对象 models.表名.objects.filter(**kwargs).last() # model对象 models.表名.objects.filter(**kwargs).count() # 整形数字 models.表名.objects.filter(**kwargs).exist() # True 或者false
# jquery的链式操作 $(this).css("color","red") $(this).next().css("fontSize","30px") $(this).css("color","red").next().css("fontSize","30px") 了不起的双下划线: models.表名.objects.filter(id__gt=10) models.表名.objects.filter(title__startswith="py") models.Tb1.objects.filter(id__range=[1, 2]) models.Tb1.objects.filter(id__in=[11, 22, 33])
(2)关联表记录操作:
添加记录:
一对多: 创建一对多: publish=models.ForeignKey("Publish",related_name="bookList") #添加记录方式1: models.Book.objects.create(publish_id=1) #添加记录方式2: #pubObj=models.Publish.objects.filter(name="人民出版社")[0] · #models.Book.objects.create(publish=pubObj) # 关联的出版社对象 多对多: 创建多对多关系: authorlist=models.ManyToManyField("Author",related_name="bookList") 多对多添加记录: book_obj=models.Book.objects.create(title="追风筝的人", price=100, publishDate="2017-12-12", publish_id=2) alex_obj=models.Author.objects.filter(name="alex")[0] egon_obj=models.Author.objects.filter(name="egon")[0] book_obj.authorlist.add(alex_obj,egon_obj)
查询记录:
正向查询:
一对多: linux_obj=models.Book.objects.filter(title="linux").first() print(linux_obj.publish.name) # 与这本书对象关联的出版社对象的名字 多对多: linux_obj=models.Book.objects.filter(title="linux").first() print(linux_obj.authorlist.all()) # 与这本书关联的所有作者对象集合
反向查询: #一对多的反向查询: eg:人民出版社出版过的书籍的名字 publish_obj=models.Publish.objects.filter(name="人民出版社")[0] print(publish_obj.bookList.all()) # 与该年出版社关联的所有书籍对象的集合 #多对多的反向查询: 查询yuan出版过的所有书籍的名字和价格: author_yuan=models.Author.objects.get(name="yuan") print(author_yuan.bookList.all()) # 与该作者关联的所有书籍书籍对象的集合
models.Book.objects.filter(**kwargs): querySet [obj1,obj2] models.Book.objects.filter(**kwargs).values(**kwargs) : querySet [{},{},{}] models.Book.objects.filter(**kwargs).values_list(title) : querySet [(),(),()]
(3)跨表查询:
class Book(models.Model): title = models.CharField(max_length=32) publish=models.ForeignKey("Publish") # 创建一对多的外键字段 authorList=models.ManyToManyField("Author") # 多对多的关系,自动创建关系表 class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) class Author(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() ad=models.models.OneToOneField("AuthorDetail") class AuthorDetail(models.Model): tel=models.IntegerField()
2、基于对象关联查询:
一对多查询(Book--Publish):
正向查询,按字段:
book_obj.publish : 与这本书关联的出版社对象 book_obj.publish.addr: 与这本书关联的出版社的地址
反向查询,按表名_set
publish_obj.book_set: 与这个出版社关联的书籍对象集合 publish_obj.book_set.all() :[obj1,obj2,....]
一对一查询(Author---AuthorDetail):
正向查询,按字段:
author_obj.ad : 与这个作者关联的作者详细信息对象
反向查询:按表名:
author_detail_obj.author : 与这个作者详细对象关联的作者对象
多对多(Book----Author):
正向查询,按字段:
book_obj.authorList.all(): 与这本书关联的所有这作者对象的集合 [obj1,obj2,....]
反向查询,按表名_set:
author_obj.book_set.all() : 与这个作者关联的所有书籍对象的集合
3、基于双下滑线的跨表查询:
一对多查询(Book--Publish):
正向查询,按字段: # 查询linux这本书的出版社的名字: models.Book.objects.all().filter(title="linux").values("publish__name") 反向查询:按表名: # 查询人民出版社出版过的所有书籍的名字 models.Publish.objects.filter(name="人民出版社出版").values("book__title")
一对一查询(Author---AuthorDetail):
正向查询,按字段: models.Author.objects.filter(name="egon).values("ad__tel") 反向查询:按表名: models.AuthorDetail.objects.filter(tel="151").values("author__name")
多对多(Book----Author):
正向查询,按字段: models.Book.objects.filter(title="python").values("authorList__name") [{},{},{},{}] 正向查询,按表名: models.Author.objects.filter(name="alex").values("book__price")
注意:
publish=models.ForeignKey("Publish",related_name="bookList") authorlist=models.ManyToManyField("Author",related_name="bookList") ad=models.models.OneToOneField("AuthorDetail",related_name="authorInfo") 反向查询的时候都用:related_name
聚合查询:
querySet().aggregate(聚合函数)------返回的是一个字典,不再是一个querySet Book.objects.all().aggregate(average_price=Avg(‘price‘))
分组查询:
querySet().annotate() --- 返回的是querySet #统计每一个出版社中最便宜的书籍的价格
sql: select Min(price) from book group by publish_id; ORM: models.Book.objects.values("publish__name").annotate(Min("price"))