Django中的模型管理器(Manager)提供了强大的数据库访问方法,可以根据需求创建自定义管理器以实现特定的查询和操作。
1. 创建自定义模型管理器方法
a. 添加额外的管理器
通过添加额外的管理器,可以为模型添加表级功能。例如,在Book
模型中添加一个名为title_count()
的管理器方法,用于统计标题中包含特定关键字的书籍数量。
# models.py from django.db import models class BookManager(models.Manager): def title_count(self, keyword): return self.filter(title__icontains=keyword).count() class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) ... objects = BookManager() # 将自定义管理器赋值给模型的objects属性
b. 修改初始管理器Queryset
通过覆盖Manager.get_queryset()
方法,可以修改管理器返回的初始Queryset。以下示例为Book
模型定义了两个管理器,一个返回所有对象,另一个仅返回作者是Roald Dahl的书籍。
# models.py from django.db import models class DahlBookManager(models.Manager): def get_queryset(self): return super(DahlBookManager, self).get_queryset().filter(author='Roald Dahl') class Book(models.Model): title = models.CharField(max_length=100) author = models.CharField(max_length=50) ... objects = models.Manager() # 默认Manager dahl_objects = DahlBookManager() # 自定义的特殊Manager
2. 自定义模型方法
为了给模型实例对象添加行级功能,可以定义自定义模型方法。这些方法只对特定模型实例起作用。
# models.py from django.db import models class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) birth_date = models.DateField() def baby_boomer_status(self): # 返回人的婴儿潮状态 import datetime if self.birth_date < datetime.date(1945, 8, 1): return 'Pre-boomer' elif self.birth_date < datetime.date(1965, 1, 1): return 'Baby boomer' else: return 'Post-boomer' def _get_full_name(self): # 返回人的全名 return f'{self.first_name} {self.last_name}' full_name = property(_get_full_name) # 将类方法包装为属性
3. 重写预定义的模型方法
可以重写预定义的模型方法,如save()
和delete()
,以改变它们的行为。确保调用父类方法以执行默认操作。
# models.py from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() def save(self, *args, **kwargs): do_something() super(Blog, self).save(*args, **kwargs) # 调用“真实”的save()方法 do_something_else()
4. Model.clean()
Model.clean()
方法用于提供自定义模型验证和修改模型属性。可以用它来自动填充字段的值或用于需要一起验证的多个字段的情况。
# models.py import datetime from django.core.exceptions import ValidationError from django.db import models class Article(models.Model): ... def clean(self): # 不允许草稿条目具有发布日期 if self.status == 'draft' and self.pub_date is not None: raise ValidationError('Draft entries may not have a publication date.') # 如果发布状态的条目的发布日期尚未设置,则设置为今天 if self.status == 'published' and self.pub_date is None: self.pub_date = datetime.date.today()
以上方法提供了在Django模型中添加自定义功能和修改默认行为的灵活性。记住要小心选择默认管理器,并在覆盖模型方法时调用父类方法,以确保模型的一致性和正确性。
暂无评论内容