Fork me on GitHub

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,
    })
posted @ 2019-03-11 11:12  seymourgao  阅读(246)  评论(0编辑  收藏  举报