Django 模型层

Django模型是 Web 应用程序的核心组成部分之一。Django 模型层允许开发者定义各种数据对象,包括但不限于 Users、Posts、Comments 等,这些对象可以映射到数据库,并且可以添加、查询、更新和删除。

1. 模型类

在 Django 中,模型是由 Python 类表示的。每个模型类都是 django.db.models.Model 的子类,并且在模型类中定义一些属性来表示与数据库中对应的数据表、数据字段、数据关系等。

1.1 定义模型类

下面是一个简单的示例:

from django.db import models

class Person(models.Model):

name = models.CharField(max_length=32)

age = models.IntegerField()

class Meta:

db_table = 'person'

这里定义了一个名为 Person 的模型类,通过继承 django.db.models.Model 类。模型类中定义了两个属性 name 和 age,这两个属性会映射成数据库表 person 的两个字段。CharField 类型会映射为 VARCHAR 数据类型,IntegerField 类型会映射为 INT 数据类型。

在模型类中可以定义多种类型的数据字段,例如 BooleanField、DateField、DateTimeField、DecimalField、EmailField、FileField、ImageField 等等,每种类型都有对应的参数,用于设置该字段在数据库中对应的数据类型和约束。可以通过名称、值、null、blank、default、unique、verbose_name、help_text 等参数来定义每个字段。

此外,还可以使用 ForeignKey、OneToOneField、ManyToManyField 等字段实现模型之间的关系。

1.2 迁移和同步

在定义模型类后,我们需要进行迁移,将模型类映射到数据库表:

$ python manage.py makemigrations myapp

$ python manage.py migrate

这里我们使用了两个命令,makemigrations 会为应用程序创建一个迁移文件,其中包含了将使用的所有改变;migrate 命令将应用程序中的所有迁移应用到数据库中,以使数据库与模型定义保持同步。

2. 模型查询

Django 提供了强大的 ORM 查询接口,使我们可以轻松地从数据库中获取数据。查询可以通过模型类的 Manager 对象完成,每个模型类都有一个默认的 Manager 对象,可以通过 objects 属性访问。

2.1 基本查询

Django 查询 API 中最常见和最基本的接口是 all() 和 get() 方法,分别用于获取模型类的所有对象和获取指定模型的单个对象。

from myapp.models import Person

# 获取所有 Person 对象

persons = Person.objects.all()

# 获取一个 Person 对象

person = Person.objects.get(id=1)

在查询时可以使用过滤器来指定查询条件,过滤器基于字符和连字符组成,例如:

from django.db.models import Q

# 使用过滤器获取某些 Person 对象

persons = Person.objects.filter(age__gte=18, name__icontains='tom')

# 使用 Q 对象进行复杂查询

persons = Person.objects.filter(Q(age__gte=18) | Q(name__icontains='tom'))

在这里使用了 age__gte=18 和 name__icontains='tom' 这两个过滤器,其中 __gte 是指 age 大于等于 18,而 __icontains 则是指 name 忽略大小写包含 'tom'。在第二个例子中使用了 Q 对象对两个过滤器进行或运算。

2.2 排序和分页查询

在查询时,还可以对查询结果进行排序和分页,这可以通过 order_by 和 offset、limit 实现,Django 也提供了类似的接口:

# 排序查询结果

persons = Person.objects.all().order_by('name')

# 分页查询结果

persons = Person.objects.all()[offset:offset+limit]

这里的 order_by('name') 指按照 name 字段进行升序排序,也可以指定 '-name' 进行降序排序。另外,对于分页查询,建议使用 Django 分页模块实现分页功能:

from django.core.paginator import Paginator

def paginated_persons(request):

persons = Person.objects.all()

paginator = Paginator(persons, 10) # 每页10条记录

page_number = request.GET.get('page')

page_obj = paginator.get_page(page_number)

return render(request, 'myapp/persons.html', {

'page_obj': page_obj,

})

这里使用了 Paginator 对象,按照每页 10 条记录对查询结果进行分页,然后在视图中处理请求,根据请求参数获取指定的页数,最后将数据传递给模板渲染。

3. 模型管理器

Django 中的模型管理器用于处理数据库对模型的增删改查。每个模型都有一个默认的管理器,可以通过定义一个继承自 models.Manager 的类来重写管理器方法。

3.1 默认管理器

默认情况下,Django 为每个模型类提供一个名为 objects 的默认管理器。这个管理器包含常用的数据库操作,如 create()、get()、filter() 等,可以用于实现模型实例的 CRUD 操作。

例如,如果我们想创建一个 Model 对象,可以使用 objects.create() 方法:

from myapp.models import Person

Person.objects.create(name='Tom', age=18)

类似地,我们可以使用 filter() 方法来获取符合条件的 Person 对象:

persons = Person.objects.filter(age__gte=18)

3.2 自定义管理器

除了默认管理器,我们也可以在模型类中定义自己的管理器。自定义管理器是一个继承自 models.Manager 的类,可以实现指定的数据库操作。

下面是一个简单的示例,定义了一个管理器,可以用 filter 方法查询年龄大于等于 18 岁的 Person 对象:

from django.db import models

class AdultManager(models.Manager):

def get_queryset(self):

return super().get_queryset().filter(age__gte=18)

class Person(models.Model):

name = models.CharField(max_length=32)

age = models.IntegerField()

# 自定义管理器

adults = AdultManager()

class Meta:

db_table = 'person'

这里我们定义了一个 AdultManager 管理器类,并重写了该类的 get_queryset() 方法,在该方法中调用了父类原本的 get_queryset() 方法,再使用 filter() 方法筛选出符合条件的 Person 对象。然后在 Person 模型中定义了一个名为 adults 的属性,并将其设置为 AdultManager 类的实例,这样我们就可以使用 adults.filter() 方法查询年龄大于等于 18 岁的 Person 对象了。

4. 模型之间的关系

Django 模型支持多种关系,例如一对多、一对一、多对多等,这些关系可以通过 ForeignKey、OneToOneField、ManyToManyField 等字段实现。

4.1 外键

外键是一种关系,用来表示两个模型之间的一对多关系。在 Django 中,外键由 ForeignKey 字段表示,将一个模型字段关联到另一个模型的主键上。

例如,假设我们有一个模型 User,有一个模型 Post,每个文章都要有一个作者。我们可以这样定义模型:

from django.db import models

class User(models.Model):

name = models.CharField(max_length=32)

class Post(models.Model):

title = models.CharField(max_length=32)

author = models.ForeignKey(User, on_delete=models.CASCADE)

这里 Post 模型中定义了一个外键 author,它关联到 User 模型。on_delete=models.CASCADE 参数表示当用户被删除时,与其关联的所有 Post 对象也将被删除。有关外键详细信息,请参阅 Django 文档。

4.2 一对一关系

一对一关系是指两个模型之间的关系,其中一个模型与另一个模型中的一个对象有且仅有一个对应关系。在 Django 中,可以使用 OneToOneField 字段实现一对一关系。

例如,假设我们有一个模型 Person,还有一个模型 Profile,每个 Person 对象只能有一个 Profile 对象。我们可以这样定义模型:

from django.db import models

class Person(models.Model):

name = models.CharField(max_length=32)

class Profile(models.Model):

person = models.OneToOneField(Person, on_delete=models.CASCADE)

email = models.EmailField()

这里我们使用 OneToOneField 建立了 Person 与 Profile 之间的一对一关系。Person 模型中没有任何关于 Profile 的信息,Profile 对象的 person 属性将是与其相关联的 Person 对象——每个 Person 对象都有一个唯一的 Profile 对象。

4.3 多对多关系

多对多关系表示两个模型之间的关系,其中一个模型中的一个对象可以与另一个模型中的多个对象相关联,反之亦然。在 Django 中,可以使用 ManyToManyField 字段实现多对多关系。

例如,假设我们有一个模型 Person,还有一个模型 Group,每个 Person 对象可以隶属于多个 Group 对象,每个 Group 对象也可以包含多个 Person 对象。我们可以这样定义模型:

from django.db import models

class Person(models.Model):

name = models.CharField(max_length=32)

groups = models.ManyToManyField('Group')

class Group(models.Model):

name = models.CharField(max_length=32)

这里我们使用 ManyToManyField 建立了 Person 和 Group 之间的多对多关系。因为 Group 对象可能还不存在,我们可以通过字符串来引用 Group 对象。

5. 总结

Django 模型层是开发 Web 应用程序不可或缺的一个重要组成部分。在 Django 中,模型由 Python 类表示,每个模型类都是 django.db.models.Model 的子类,并且在模型类中定义一些属性来表示与数据库对应的数据表、数据字段、数据关系等。我们可以通过模型管理器实现模型实例的 CRUD 操作,使用 Django 查询 API 实现查询、排序、分页等功能。一对一、一对多和多对多关系是 Django 模型中非常重要的一部分,可以通过 ForeignKey、OneToOneField、ManyToManyField 等字段实现。

后端开发标签