django model

django的数据模型

经典的例子:一本书有多个作者,一个作者有多本书,典型的多对多关系。
从这个经典的例子入手
从一本书可以获取作者的信息,
从作者的也可以获取书的信息。

from django.db import models  
# 作者表,作者的信息,定义表名为author
class Author(models.Model):  
    first_name = models.CharField(max_length=30)  
    last_name = models.CharField(max_length=40)  
    email = models.EmailField()  
    def __unicode__(self):  
        return self.name  
    class Meta:  
        db_table = "author"       
# 书籍表,书籍的信息,定义表名为book,添加author字段,设置为多对多。
class Book(models.Model):  
    title = models.CharField(max_length=200)  
    authors = models.ManyToManyField(Author)  
    def __unicode__(self):  
        return self.title  
    class Meta:  
        db_table = "book"    

查看数据库中的表,可以看到django为我们新建了一个表
book_authors表
就是用来存放书和作者多对多映射关系的。

查询的时候:
查找一本书的所有作者:
b=book.objects.get(id=1)
b.authors.all()
查找一个作者的所有书籍
a=author.objects.get(id=1)
a.book_set.all()
表名_set,固定格式。

#

之前做过的练习是新闻的点赞数和点赞者的多对多。
# 查询点赞数
# article_list = models.News.objects.all()
# for i in article_list:
# print “标题”,i.title
# print “内容”,i.content
# print “点赞数”,i.favor_set.count()
# print “以下人点赞了”,
# for item in i.favor_set.all():
# print item.user_obj.username

查询user1 点过赞的文章
# user1 = models.MyUser.objects.get(username=”user1”)
# print “user1 点过赞的文章”
# for i in user1.favor_set.all():
# print “文章标题”,i.new_obj.title
# print “文章内容”,i.new_obj.content
# print “给这篇文章点过赞的还有”,
# for item in i.new_obj.favor_set.all():
# print item.user_obj.username

正向添加
# 正向添加,通过有manytomany字段的对象
# 在host表里面有个manytomany 字段,通过host对象添加是正向的。
# host_obj = models.host.objects.get(host_name=”h4”)
# user_list = models.host_user.objects.filter(id__lt=4)
# host_obj.host_manager.add(*user_list)
# 多对多反向添加
# user_obj = models.host_user.objects.get(user_name=”hansz”)
# host_list = models.host.objects.filter(id__lt=3)
# 反向添加
# user_obj.host_set.add(*host_list)


select_related()使用的场景,是获取实体的同时,能快速获取到它对应的外键关系实体。如果获取实体时没有使用select_related(),要引用该实体的外键关系,那么就会重新连接数据库去获取对应实体了。比如 作者Author 书book两个表,他们的关系 是一个作者Author有多本book,;当我们想获取到一个作者的同时 直接引用该作者的所有书时,常规做法是会进行两次数据库连接的,但使用了select_related()后,情况就有所变化了,它第一次连接数据库获取该作者的时候,该作者的所有书被获取到了。
比如:
author=Author.objects.select_related().get(pk=1) #获取id是1的作者; 获取该作者的同时已经获取到该作者的所有书
books=author.book #获取id是1作者的所有book,这时并不需要连接数据库获取那些书了。
不使用select_related()时:
author=Author.objects.get(pk=1) #获取id是1的作者;仅仅获取该作者的实体
books=author.book#获取id是1作者的所有book,但需要连接数据库获取该作者的那些博客。
select_related()提供了一个备选参数depth,执行获取对象关联实体的深度。如 select_related(depth=2),这时不仅仅获取到相关的书,还能获取到书的关联实体,比如书的类别(另一个和书表相对应的表)之类的。如果不指定depth,默认情况将会获取到该作者的所有关联对象的 包括关联对象的子关联对象。由此可以想象,使用它有利有弊,当自己需要对象相关关联对象的时候,可以使用它,只是这样第一次查询的时候,将进行不少表的操作(要看表关联复杂程度)。
所以当我们获取对象需要它相关联的对象时,就请用select_related()吧,如果该对象关联的表很多,请指定depth的值,避免资源的浪费;反之避免select_related()。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值