Django 的 `Meta` 类和外键的使用
- 
- 
- [1. `Meta` 类的常用选项](#1. Meta类的常用选项)
- [2. 外键(ForeignKey)字段的使用](#2. 外键(ForeignKey)字段的使用)
- 
- [2.1 基本用法](#2.1 基本用法)
- [2.2 `ForeignKey` 参数](#2.2 ForeignKey参数)
- [2.3 外键删除选项(`on_delete`)](#2.3 外键删除选项(on_delete))
 
- [3. 外键和查询](#3. 外键和查询)
- 
- [3.1 获取作者的所有书籍](#3.1 获取作者的所有书籍)
- [3.2 通过书籍查找作者](#3.2 通过书籍查找作者)
- [3.3 使用 `select_related` 优化查询](#3.3 使用 select_related优化查询)
 
- 总结
 
- [1. `Meta` 类的常用选项](#1. 
 
- 
在 Django 中,Meta 类是模型的一个内部类,用来配置模型的行为和一些数据库选项。通过在模型中定义 Meta 类,你可以控制模型的一些特性,如数据库表名、排序方式、索引、唯一约束等。
1. Meta 类的常用选项
以下是 Meta 类中常用的配置选项:
- 
db_table:指定数据库表的名称。如果没有指定,Django 会默认使用模型类名的小写形式作为表名。pythonclass Tank(models.Model): name = models.CharField(max_length=100) speed = models.FloatField() class Meta: db_table = 'tank_table' # 指定数据库表名
- 
ordering:指定模型数据的默认排序方式。它接受一个字段名的列表(可以带负号表示降序)。pythonclass Tank(models.Model): name = models.CharField(max_length=100) speed = models.FloatField() class Meta: ordering = ['-speed'] # 按照速度降序排列
- 
verbose_name和verbose_name_plural:用于指定模型的单数和复数形式的可读名称,通常用于 Django 管理后台显示模型名称。pythonclass Tank(models.Model): name = models.CharField(max_length=100) speed = models.FloatField() class Meta: verbose_name = 'Tank' verbose_name_plural = 'Tanks'
- 
unique_together:指定多个字段组合成的联合唯一约束。Django 会确保这组字段的组合在数据库中是唯一的。pythonclass Tank(models.Model): name = models.CharField(max_length=100) speed = models.FloatField() class Meta: unique_together = ['name', 'speed'] # 确保每个name和speed组合是唯一的
- 
index_together:为多个字段组合创建数据库索引,提高查询效率。pythonclass Tank(models.Model): name = models.CharField(max_length=100) speed = models.FloatField() class Meta: index_together = ['name', 'speed'] # 为name和speed创建联合索引
- 
permissions:指定模型的权限。这会在auth_permission表中创建自定义权限。pythonclass Tank(models.Model): name = models.CharField(max_length=100) speed = models.FloatField() class Meta: permissions = [ ("can_drive", "Can drive the tank"), ("can_fight", "Can fight with the tank") ]
- 
default_manager_name:设置默认的管理器名称,Django 会在模型类中自动创建objects管理器。如果你有多个管理器,可以通过这个选项指定默认的一个。pythonclass Tank(models.Model): name = models.CharField(max_length=100) speed = models.FloatField() active_tanks = models.Manager() # 自定义管理器 class Meta: default_manager_name = 'active_tanks' # 使用自定义的管理器
2. 外键(ForeignKey)字段的使用
Django 的 ForeignKey 字段用于表示模型之间的"一对多"关系。在外键关系中,一个对象可以关联多个对象,常用于表示父子表关系。
2.1 基本用法
ForeignKey 用于表示两个模型之间的外键关系。通常情况下,它会生成一个新的字段,在数据库中存储关联对象的主键(id)。
假设我们有两个模型:Author 和 Book。每本书都由一个作者编写,因此我们需要在 Book 模型中添加一个外键字段,指向 Author 模型。
            
            
              python
              
              
            
          
          from django.db import models
class Author(models.Model):
    name = models.CharField(max_length=100)
    def __str__(self):
        return self.name
class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)  # 外键关系,关联到 Author 模型
    def __str__(self):
        return self.title2.2 ForeignKey 参数
- to:指定外键关联的模型类。可以是另一个模型的类名或字符串(例如- 'Author')。
- on_delete:当关联对象(如作者)被删除时,当前对象(如书籍)该如何处理。常见的选项包括:- models.CASCADE:级联删除,删除父对象时删除所有关联的子对象。
- models.PROTECT:阻止删除父对象,如果该对象仍被引用。
- models.SET_NULL:将外键字段设置为- NULL(前提是该字段允许为- NULL)。
- models.SET_DEFAULT:将外键字段设置为默认值。
- models.SET():可以设置一个特定的值。
 
- related_name:为反向关系定义名称。即通过外键模型,可以反向查询到当前模型实例的集合。默认情况下,Django 会使用模型名的小写形式加上- _set作为反向查询的名称。
- related_query_name:用于在查询时指定反向关系的名称。
- null:如果为- True,外键可以为空。
- blank:如果为- True,字段可以在表单中为空。
例如,添加 related_name 来进行反向查询:
            
            
              python
              
              
            
          
          class Author(models.Model):
    name = models.CharField(max_length=100)
    def __str__(self):
        return self.name
class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')  # 定义反向查询名称
    def __str__(self):
        return self.title现在,如果你有一个 author 实例,你可以通过 author.books.all() 获取该作者所有的书籍:
            
            
              python
              
              
            
          
          author = Author.objects.get(id=1)
books_by_author = author.books.all()  # 获取该作者所有的书籍2.3 外键删除选项(on_delete)
当父对象被删除时,Django 会根据你设置的 on_delete 参数来处理外键关系。以下是常用的 on_delete 选项:
- 
models.CASCADE:删除父对象时,删除所有引用该父对象的子对象。pythonauthor = Author.objects.get(id=1) author.delete() # 删除作者时,所有关联的书籍也会被删除
- 
models.PROTECT:如果该父对象仍被引用,禁止删除父对象。pythonauthor = Author.objects.get(id=1) author.delete() # 如果有书籍关联,删除时会引发异常
- 
models.SET_NULL:将外键字段设置为NULL。需要确保外键字段允许NULL。pythonclass Book(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True)
- 
models.SET_DEFAULT:将外键字段设置为默认值。pythonclass Book(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey(Author, on_delete=models.SET_DEFAULT, default=1)
- 
models.SET():你可以指定一个函数或值,当父对象删除时,外键字段会设置为指定的值。pythonclass Book(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey(Author, on_delete=models.SET('Unknown Author'))
3. 外键和查询
在 Django 中,你可以轻松地使用外键字段进行查询。例如:
3.1 获取作者的所有书籍
            
            
              python
              
              
            
          
          author = Author.objects.get(id=1)
books = author.books.all()  # 获取该作者的所有书籍3.2 通过书籍查找作者
            
            
              python
              
              
            
          
          book = Book.objects.get(id=1)
author = book.author  # 获取书籍的作者3.3 使用 select_related 优化查询
如果你查询外键字段时,经常会发起额外的数据库查询。你可以使用 select_related 来一次性加载相关的外键数据,减少查询次数。
            
            
              python
              
              
            
          
          books = Book.objects.select_related('author').all()  # 一次性查询所有书籍及其对应的作者总结
- Meta类用于在模型中配置数据库表的选项,如表名、排序、索引等。
- 外键字段(ForeignKey)用于表示模型之间的"一对多