Django笔记(六)

一对多

  • 一个出版社多本书
  • 一本书一个出版社

在数据库中的体现

  • 通过外键(Foreign Key)来体现一对多
  • 在(多)的表中增加对(一)的外键

语法

  • 使用外键(Foreign Key)在(多)的实体中增加
    • 属性的=models.ForeignKey(Entry)

给图书增加出版社外键实战案例源码

# 图书 Book:title publicate_date
class Book(models.Model): title = models.CharField(max_length=32, verbose_name='书名') publicate_date = models.DateField(auto_now=True, verbose_name='出版日期') # 增加对出版社的引用 publisher = models.ForeignKey('Publisher', null=True) def __str__(self): return self.title class Meta: verbose_name_plural = '图书' ordering = ['-publicate_date', 'title'] 
Python

查询

  • 正向查询 通过Book查询Publisher
    • 案例:查询id为1的书籍的信息
    • book=Book.objects.get(id=1)
    • publisher=book.publisher

正向查询实战案例源码

# 查询图书
def book(request): book = Book.objects.get(id=1) publisher = book.publisher.name # books=Book.objects.all() return render(request, 'book.html', { # 'books':books 'book': book, 'publisher': publisher }) 
Python
  • 反向查询 通过Publisher查询Book
    • Django会在(一)的实体中增加(多)的隐藏属性
    • 关联对象小写_set
    • 用于查询多的数据
    • 注意,查询的时候,必须要在管理属性后面加参数
    • all()或其他

反向查询实战案例源码

# 查询图书
def book(request): book = Book.objects.get(id=1) publisher = book.publisher.name #查询id为3的出版社的所有书籍 publisher1=Publisher.objects.get(id=1) books=publisher1.book_set.all() print(books) # books=Book.objects.all() return render(request, 'book.html', { # 'books':books 'book': book, 'books': books, 'publisher': publisher, 'publisher1': publisher1.name }) 
Python

多对多关联

  • 什么是多对多
    • A表中的一条记录可以对应B表中的多条记录
    • B表中的一条记录也可以对应A表中的多条记录
  • 案例
    • 作者和书籍
    • 商品和买家
  • 在数据库中的体现
    • 必须创建第三张表,关联涉及到的两张表的数据
  • 语法
    • 允许在任何一个实体中增加操作
    • entry=models.ManyToManyField(Entry)

回忆

  • Django数据库恢复备份状态的指令
  • python manage.py migrate index(应用名) 0001(状态id)

指定后台分组的实战源码

class PulisherAdmin(admin.ModelAdmin): # fields = ('name', 'city') fieldsets = ( ('分组1', {'fields': ('name', 'city'), 'classes': ('collapse',)}), ('分组2', {'fields': ('country', 'website')})) list_display = ['name', 'city', 'country', 'website'] 
Python

多对多查询

  • 正向查询
    • 通过作者(Author)表查询书籍(Book)表
    • author=Author.objects.get(id=1)
    • books=author.book.all() 通过关联属性.all()查询所有的数据

正向查询实战案例源码

# 多对多查询
def mtm(request): author = Author.objects.get(id=3) books = author.book.all() return render(request, 'mtm.html', { 'books': books, }) 
Python
  • 反向查询
    • 通过书籍(Book)表查询作者(Author)表
    • book=Book.objects.get(id=1)
    • authors=book.author_set.all()

反向查询实战案例元am

# 多对多查询
def mtm(request): author = Author.objects.get(id=3) books = author.book.all() # 反向查询 book = Book.objects.get(id=3) authors = book.author_set.all() return render(request, 'mtm.html', { 'books': books, 'author':author, 'authors': authors, }) 
Python

练习

  • 创建Author和Publisher的多对多关系
  • 查询李白所签约的所有出版社
  • 查询北京大学出版社下的所有作者

实战案例源码

# 出版社与作者多对多查询
def publisher2author(request): publisher = Publisher.objects.filter(name__exact='北京大学出版社').first() authors = publisher.author.all() return render(request, 'publisher2author.html', { 'authors': authors, }) 
Python

自定义查询对象 objects

  • 声明类EntryManager,继承自models.Manager
class EntryManager(models.Manager):
    def 函数名(self,自定义参数列表)
  • 使用EntryManager覆盖models类中的objects
class Entry(models.Model):
    objects=EntryManaer()

实战案例源码

# 声明自定义objects - models.Manager
class AuthorManager(models.Manager): # 添加自定义函数-查询Author表中共有多少条数据 def auCount(self): return self.all().count('*') # count方法统计多少个 # 作者 Author:name age email class Author(models.Model): # 使用AuthorManager覆盖当前的objects objects = AuthorManager() name = models.CharField(max_length=32, verbose_name='姓名') age = models.PositiveSmallIntegerField(verbose_name='年龄') email = models.EmailField(null=True, verbose_name='邮箱') # 增加一个状态列,来表示用户是启用的还是禁用的 isActive = models.BooleanField(default=True) wife = models.OneToOneField('Wife', null=True, verbose_name='妻子') # 创建与书籍的多对多关联 book = models.ManyToManyField('Book') def __str__(self): return self.name class Meta: verbose_name_plural = '作者' # 排序 年龄降序 id升序 ordering = ['-age', 'id'] # 在view控制器中调用 # 出版社与作者多对多查询 def publisher2author(request): publisher = Publisher.objects.filter(name__exact='北京大学出版社').first() authors = publisher.author.all() print('数据总数:', Author.objects.auCount()) return render(request, 'publisher2author.html', { 'authors': authors, }) 
Python

练习

  • 为Author指定自定义objects对象
    • 查询年纪小于指定年纪的作者的信息
  • 为Book指定自定义的objects对象
    • 查询书名中包含指定关键字的信息

查询书籍实战源码

# 声明自定义的objects - Book表
class BookManager(models.Manager): def like(self, s): return self.filter(title__contains=s) 
Python
# 图书 Book:title publicate_date
class Book(models.Model): objects = BookManager() title = models.CharField(max_length=32, verbose_name='书名') publicate_date = models.DateField(auto_now=True, verbose_name='出版日期') # 增加对出版社的引用 publisher = models.ForeignKey('Publisher', null=True, verbose_name='出版社') def __str__(self): return self.title class Meta: verbose_name_plural = '图书' ordering = ['-publicate_date', 'title'] 
Python
# 出版社与作者多对多查询
def publisher2author(request): publisher = Publisher.objects.filter(name__exact='北京大学出版社').first() authors = publisher.author.all() # AuthorManager测试 print('数据总数:', Author.objects.auCount()) # BookManager测试 print('查询包含字段的书籍:', Book.objects.like('三')) return render(request, 'publisher2author.html', { 'authors': authors, }) 
Python

年纪查询实战案例源码

# 声明自定义objects - models.Manager
class AuthorManager(models.Manager): # 添加自定义函数-查询Author表中共有多少条数据 def auCount(self): return self.all().count() # count方法统计多少个 # 查询年纪小于指定年纪的作者信息 def ltAge(self, i): return self.filter(age__lt=i) 
Python
# 作者 Author:name age email
class Author(models.Model): # 使用AuthorManager覆盖当前的objects objects = AuthorManager() name = models.CharField(max_length=32, verbose_name='姓名') age = models.PositiveSmallIntegerField(verbose_name='年龄') email = models.EmailField(null=True, verbose_name='邮箱') # 增加一个状态列,来表示用户是启用的还是禁用的 isActive = models.BooleanField(default=True) wife = models.OneToOneField('Wife', null=True, verbose_name='妻子') # 创建与书籍的多对多关联 book = models.ManyToManyField('Book') def __str__(self): return self.name class Meta: verbose_name_plural = '作者' # 排序 年龄降序 id升序 ordering = ['-age', 'id'] 
Python
# 出版社与作者多对多查询
def publisher2author(request): publisher = Publisher.objects.filter(name__exact='北京大学出版社').first() authors = publisher.author.all() # AuthorManager测试 print('数据总数:', Author.objects.auCount()) print('查询年纪小于指定信息的作者:', Author.objects.ltAge(100)) # BookManager测试 print('查询包含字段的书籍:', Book.objects.like('三')) return render(request, 'publisher2author.html', { 'authors': authors, })

猜你喜欢

转载自www.cnblogs.com/gx-1/p/10509399.html