文章

7. 自定义模型管理器

模型管理器是在调用某个模型的objects方法时返回的对象, 如:

1
manager = Product.objects

6. 通用关系查询.md 中, 封装了通过content-type查询被标记的数据的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
from django.shortcuts import render
from django.contrib.contenttypes.models import ContentType
from store.models import Product
from tags.models import TaggedItem

def index(request):
    content_type = ContentType.objects.get_for_model(Product)
    query_set = TaggedItem.objects\
        .select_related('tag')\
        .filter(content_type=content_type, object_id=1)

    return render(request, 'tags.html')

但如果每次添加一个查询功能都要封装这些代码显然并不合适, 理想状态下的代码应该是

1
TaggedItem.objects.get_tags_from(Product, 1)

此时便需要设置自定义模型管理器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class TaggedItemManager(models.Manager):
    def get_tags_for(self, obj_type, obj_id):
        content_type = ContentType.objects.get_for_model(obj_type)

        return TaggedItem.objects \
            .select_related('tag') \
            .filter(
                content_type=content_type,
                object_id=obj_id
            )

class TaggedItem(models.Model):
    # 修改模型的管理器对象
    objects = TaggedItemManager()
    tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey()
本文由作者按照 CC BY 4.0 进行授权