Django:Model系统

一、表结构

class Author(models.Model):
    name=models.CharField(max_length=32)
    age=models.IntegerField()
    
    def __str__(self):
        return self.name
    
class Publisher(models.Model):
    name=models.CharField(max_length=32)
    email=models.EmailField(unique=True)
    
    def __str__(self):
        return self.name
    
class Book(models.Model):
    title=models.CharField(max_length=32)
    author=models.ForeignKey("Author")
    publisher=models.ForeignKey("Publisher")
    content=models.TextField()
    date=models.DateField(auto_now=True)
    
    def __str__(self):
        return self.title

什么鬼?没关系,让我给你仔细说说————

二、表结构设计

在你使用数据库时,一个个创建,很麻烦,所以django提供了ORM。然而,怎么用?先不说这个,先设计一下图书管理系统的表结构——

这是书表。那么有个问题——author_id是啥?直接写作者名不就OK了?注意了,我是用fk的方式(学过MySQL的应该知道,一对多关联)做的。在ORM里,可以自动帮你转换成一个对象。

这是Publisher表。没什么可说的,id字段就是默认的关联(存储id,ORM自动根据id查到Publisher的对象)

也没什么可说的。下面来说说细节问题吧:

这个你可以按照自己的喜好来确定这些细节。设计完了,你要再梳理一遍。

三、Model模型

Django ORM支持很多字段。

Django字段还支持很多参数。

 Django的表里有一些存储在数据库里的元信息,可以在表里写Meta类。

 

四、连表操作

连表操作之fk
连表操作之o2o
连表操作之m2m

五、创建表结构

python manage.py makemigrations
python manage.py migrate  

六、Model操作

需求1:创建苹果出版社

################第一种方式############
models.Publisher.objects.create(
     id=1,
    name="苹果出版社",
    email="apple@126.com"   
)
############### 第二种方式##############
obj = models.Publisher(
    id=1,
    name="苹果出版社",
    email="apple@126.com"
)
obj.save()

需求二、删除苹果出版社

obj = models.Publisher.objects.get(id=1) # 获取苹果出版社的对象
obj.delete() # 删除对象  

需求三、查看苹果出版社的邮箱

#########第一种#######
obj=models.Publisher.objects.filter(id=1) # 获取所有id=1的对象,如果没有则为空
print(obj.first().email) # 所有对象的第一个的邮箱
#########第二种#######
obj=models.Publisher.objects.get(id=1) # 获取一个id=1的对象,如果没有则报错
print(obj.email)

需求四、更改苹果出版社的邮箱

 

########第一种########
obj=models.Publisher.objects.get(name="苹果出版社")
obj.email = "apple@163.com"
obj.save()
########第二种(支持批量修改)##
obj=models.Publisher.objects.filter(name="苹果出版社")
obj.update(email="apple@163.com")

需求五、创建《跟老男孩学Linux》书

Author.objects.create(id=1,name='老男孩',age=100)
Book.objects.create(id=1,title='跟老男孩 Linux',author_id=1,publisher_id=1,content="112233",date="2019-07-12")
# 用 字段_id 设置fk的id 

需求六、查询《跟老男孩学Linux》的出版社的邮箱

obj=Book.objects.get(title="跟老男孩学Linux") # filter or get
print(obj.publisher.email)  

需求七、根据出版社邮箱查所有的书

 obj=Book.objects.filter(publisher__email="apple@163.com") 

需求八、查表的数据库里的名字

models.Book._meta.db_table 

需求九、执行原生SQL拿到全部的书

from django.db import connection, connections
cursor = connection.cursor()  # cursor = connections['default'].cursor()
cursor.execute("""SELECT * from book """)
row = cursor.fetchone()

需求10、前几天,老男孩过了生日,现在要你在不知道他年龄的情况下改他的年龄

from django.db.models import F
models.Author.objects.update(age=F('age')+1)  

需求11、排序

orderby_id_all = Author.objects.all().order_by("id")
# 全部根据id排序
orderby_name_all = Author.objects.all().order_by("name")
# 全都根据name排序

需求12、多字段搜索

######### 写法1(不支持多字段,仅支持查询) ###########
from django.db.models import Q
q = Q(name="苹果出版社")
filterby_q = models.Publisher.objects.filter(q)

######### 写法2(支持多字段,可以搜索了) #############
from django.db.models import Q
q = Q()
q.connector = "OR"
q.children.append("name",'苹果出版社')
q.children.append("email","苹果出版社")
filterby_q = models.Publisher.objects.filter(q)  

需求13、查苹果出版社出版的所有书籍  

publisher=models.Publisher.objects.filter(name="苹果出版社")
books=publisher.book_set # fk的反向查询  

 需求14、o2o反向查询(与项目无关)

o = models.Tb.objects.get(fff="111")
o.tb2 # 直接obj.表名小写  

需求15、m2m正向查询(与项目无关)

ttt = models.Tb.objects.get(fff="222")
ttt.sdf.all() # 字段是ManyToManyRel
# ManyToManyRel().count()  有多少个数据
# ManyToManyRel().all() 数据列表

需求16、取到所有书本(id小于3)的数量

a=Author.objects.all().extra(select={"n",'select count(1) from cmdb_book where id<3'},select_params=[1])
for obj in a:
    print(obj.id,obj.name,obj.n)  

需求17、分组(annotate)

from django.db.models import Count, Sum, Max, Min
v = Author.objects.values("name","id").annotate(xxxx=Count(5)) # group by 加聚合函数
print(v.query) # sql语句  

需求18、annotate having

from django.db.models import Count, Sum, Max, Min
v = Author.objects.values("name","id").annotate(xxxx=Count(5)).filter(xxxx__gt=18) # group by 加聚合函数 filter在前是where filter在后是having
print(v.query) # sql语句    

需求19、复杂条件过滤

Author.objects.filter(id__gt=1) # 大于
Author.objects.filter(id__lt=1) # 小于
Author.objects.filter(id__gte=1) # 大于等于
Author.objects.filter(id__lte=1) # 小于等于
Author.objects.filter(id__in=[1,2,3]) # 在谁里面(必须传列表)
Author.objects.filter(id__startswith="老男") # 从什么开始 
Author.objects.filter(id__endswith="老男")
Author.objects.filter(id__contains="男孩") # 包含
Author.objects.exclude(id__gt=1)  # 排除,不等于  

需求20、查一本书的名字和作者

#######第一种######
Book.objects.values('name','author') # 列表套字典
#######第二种######
Book.objects.all().only('name','author') # 对象
# 注意:想拿什么取什么  

需求21、查一本书除了出版社以外的信息

Book.objects.all().defer('publisher')  

七、QuerySet操作

在前面我们讲的一大堆需求里面,取到的数据大都是QuerySets。所以,你必须要会操作QuerySets,因为他比values好用。

 1 #################################
 2 querysets = models.Book.objects.all()
 3 for row in querysets: # 可以循环拿到字段的数据
 4     print(row.title,row.publisher.name,row.author.name)
 5 
 6 #################################
 7 querysets = models.Book.objects.all().order_by("id") # 排序
 8 
 9 ##################################
10 v = models.Book.objects.all().values() # 换成列表套字典的格式
QuerySets操作

八、作业

作业需求:

1. 图书管理系统

   a.  表结构课上

   b. 列出所有图书,作者,出版社

   c. 可以增删改查

 

九、练习题

        0. 创建博客表结构,自己设计,并且完成下面练习题:

  1. 创建5条account和5条新tag纪录
  2. 创建5条article信息,关联上面的不同的用户和tag
  3. 在account表里找到用户名包含al的纪录,然后把密码改掉
  4. 在article表找到文章内容包含“电影”2个字的,把这些文章加上”大文娱”tag
  5. 把用户elina发表的文章找出来,并且把作者都改成alex
  6. 找到用户表里注册日期在2018-04月,并且signature为空的纪录
  7. 打到文章中标签为“投资”的所有文章
  8. 找到每个月8号注册的用户
  9. 找到每年5月发表的文章 
  10. 找到2015-2017年5月发表的文章 
  11. 找到文章作者以’a’或’k’开头的文章

    

 

posted @ 2019-07-12 18:40  等待唐僧的电脑人  阅读(116)  评论(0)    收藏  举报