1. 程式人生 > >django之多表查詢

django之多表查詢

自動創建 dig strftime class 一個 圖片 mod date 山東

一、創建模型

在Models創建如下模型:

from django.db import models


# Create your models here.

# 用了OneToOneField和ForeignKey,模型表的字段,後面會自定加_id
# ManyToManyField會自動創建第三張表
# 一對一的關系:OneToOneField
# 一對多的關系:ForeignKey
# 多對多的關系:ManyToManyField


class Publish(models.Model):
    id = models.AutoField(primary_key=True)
    name 
= models.CharField(max_length=32) addr = models.CharField(max_length=64) email = models.EmailField() class Author(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) # 數據類型 sex = models.IntegerField() # 可以用ForeignKey,但是得設置唯一性約束,會報警告,不建議用,建議用OneToOneField
# authordetail=models.ForeignKey(unique=True) # to=‘AuthorDetail‘加引號,這個代表能找到就可以,不用引號,類必須在上面定義 authordetail = models.OneToOneField(to=AuthorDetail, to_field=id) def __str__(self): return self.name class AuthorDetail(models.Model): id = models.AutoField(primary_key=True) phone
= models.CharField(max_length=32) addr = models.CharField(max_length=64) class Book(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) publish = models.ForeignKey(to=Publish, to_field=id) authors = models.ManyToManyField(to=Author) def __str__(self): return self.name

註意事項:

  id 字段 是自動添加的

  對於外鍵字段,django會在字段名上添加“_id”來創建數據庫中的列名

  外鍵字段ForeignKey 有一個 null=True的設置(它允許外鍵接受空值NULL),你可以賦值給它none。

二、添加表記錄

1、一對多新增數據

# 添加一本北京出版社出版的書
# 方式一
ret=Book.objects.create(name=紅樓夢,price=35,publish_id=1)
print(ret.name)

# 方式二:存對象publish=出版社對象,存到數據庫,是一個 id
# publish=Publish.objects.get(id=1)
# pk是主鍵,通過主鍵查找
# publish=Publish.objects.get(pk= 1)
# publish=Publish.objects.filter(pk=2).first()
# ret=Book.objects.create(name=‘西遊記‘,price=45.5,publish=publish)
# print(ret.name)

技術分享圖片
 # -----一對多添加
    pub=Publish.objects.create(name=egon出版社,email=[email protected],city=山東)
    print(pub)

    # 為book表綁定和publish的關系
    import datetime,time
    now=datetime.datetime.now().__str__()
    now = datetime.datetime.now().strftime(%Y-%m-%d)
    print(type(now))
    print(now)
    # 日期類型必須是日期對象或者字符串形式的2018-09-12(2018-9-12),其它形式不行
    Book.objects.create(name=海燕3,price=333.123,publish_date=now,publish_id=2)
    Book.objects.create(name=海3燕3,price=35.123,publish_date=2018/02/28,publish=pub)
    pub=Publish.objects.filter(nid=1).first()
    book=Book.objects.create(name=測試書籍,price=33,publish_date=2018-7-28,publish=pub)
    print(book.publish.name)
    # 查詢出版了紅樓夢這本書出版社的郵箱
    book=Book.objects.filter(name=紅樓夢).first()
    print(book.publish.email)
View Code

2、多對多

 

# 為紅樓夢這本書新增一個叫 xcc的作者
# xcc = Author.objects.filter(name=‘xcc‘).first()
# zy=Author.objects.filter(name=‘張煜‘).first()
# book = Book.objects.filter(name=‘紅樓夢‘).first()
# add添加對象
# book.authors.add(xcc)
# book.authors.add(xcc,zy)
# add添加作者id
# book.authors.add(1,2)

# 刪除 remove,可以傳對象,可以傳id,可以傳多個,不要混著用
# book.authors.remove(xcc)
# book.authors.remove(2)
# book.authors.remove(1,2)
# clear清空所有
# book.authors.clear()

# set,先清空,再新增,要傳一個列表,列表內可以是id,也可以是對象
# book.authors.set([xcc,])
# book.authors.set([2,])

三、基於對象的跨表查詢

  1、一對多查詢

‘‘‘
一對多
正向   book---關聯字段在book--->publish   ------>  按字段
反向   publish------關聯字段在book--->book  -----> 按表名小寫_set.all()
‘‘‘
# 正向查詢紅樓夢這本書的出版社郵箱
# book = Book.objects.filter(name=‘紅樓夢‘).first()
# publish = book.publish
# print(publish.email)

# 反向查詢地址是北京的出版社出版的圖書
# publish = Publish.objects.filter(addr=‘北京‘).first()
# publish.book_set.all() 拿出所有圖書
# books=publish.book_set.all()
# books = publish.book_set.all().count()
# print(books)

2、一對一查詢:

‘‘‘
一對一
正向   author---關聯字段在author--->authordetail   ------>  按字段
反向   authordetail------關聯字段在author--->author  -----> 按表名小寫

‘‘‘
# 查詢xcc作者的手機號,正向查詢
# author = Author.objects.filter(name=‘xcc‘).first()
# # author.authordetail 就是作者的詳情對象
# authordetail = author.authordetail
# print(authordetail.phone)

# 查詢地址是安慶的作者名字,反向查詢
# authordetail = AuthorDetail.objects.filter(addr=‘安慶‘).first()
# # authordetail.author 這是作者的對象
# author = authordetail.author
# print(author.name)

3、多對多查詢:

‘‘‘
  多對多
  正向   book---關聯字段在book--->author   ------>  按字段.all()
  反向   author------關聯字段在book--->book  -----> 按表名小寫_set.all()
  ‘‘‘

# 查詢紅樓夢這本書的所有作者
# book = Book.objects.filter(name=‘紅樓夢‘).first()
# ret = book.authors.all()  # 是所有的作者,是一個queryset對象,可以繼續點
# print(ret)

# 查詢xcc寫的所有書
# xcc = Author.objects.filter(name=‘xcc‘).first()
# books = xcc.book_set.all()
# print(books)

# 連續誇表
# 查詢紅樓夢這本書所有的作者的手機號
# book = Book.objects.filter(name=‘紅樓夢‘).first()
# authors = book.authors.all()
# for author in authors:
#     authordetail = author.authordetail
#     print(authordetail.phone)

四、基於雙劃線的跨表查詢

# ************基於雙下劃線的查詢
# 一對一
# 查詢xcc作者的手機號,正向查詢,跨表的話,按字段
# 以author表作為基表
# ret = Author.objects.filter(name=‘xcc‘).values(‘authordetail__phone‘)
# print(ret)

# 以authordetail作為基表,反向查詢,按表名小寫,跨表的話,用表名小寫
# ret=AuthorDetail.objects.filter(author__name=‘xcc‘).values(‘phone‘)
# print(ret)

# 查詢xcc的性別和手機號 正向
# ret=Author.objects.filter(name=‘xcc‘).values(‘authordetail__phone‘,‘sex‘)
# print(ret)

# 查詢手機號是12234567的作者的性別

# ret=Author.objects.filter(authordetail__phone=‘12234567‘).values(‘sex‘)
# print(ret)

django之多表查詢