十一、ContentType组件


返回

11.1 模型

  • models.py

    from django.db import models
    from django.contrib.contenttypes.models import ContentType
    from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
    
    
    class Food(models.Model):
        """ 商品种类 """
        title = models.CharField(max_length=32)
        # 4. 和Coupon绑定外键关系,只用于反向查询,不生成字段
        coupons = GenericRelation(to="Coupon")
    
    ...
    
    class Coupon(models.Model):
        """ 优惠券 """
        title = models.CharField(max_length=32)
        # 1. 和ContentType绑定外键关系
        content_type = models.ForeignKey(to=ContentType, on_delete=models.CASCADE)
        # 2. 建立对象id
        object_id = models.IntegerField()
        # 3. 把object_id和object_id绑定外键关系,不生成字段
        content_object = GenericForeignKey("content_type", "object_id")
    
    

11.2 视图

  • views.py

    from rest_framework.views import APIView
    from rest_framework.response import Response
    from .models import Food, Coupon
    from django.contrib.contenttypes.models import ContentType
    
    
    class DemoView(APIView):
    
        def get(self, request):
            # 1. 找到具体食物对象
            food_obj = Food.objects.filter(id=1).first()
    
            # 2. 创建食物优惠券:手动实现(不推荐)
            # Coupon.objects.create(title="面包九五折", content_type_id=8, object_id=1)
    
            # 2. 创建食物优惠券:Django内置方法实现
            Coupon.objects.create(title="面包九五折", content_object=food_obj)
    
            # 3.1 通过食物对象查询优惠券对象(反向查询GenericRelation)
            coupons = food_obj.coupons.all()
            # 3.2 通过优惠券对象查询食物对象(正向查询content_object)
            coupon_obj = Coupon.objects.filter(id=1).first()
            content_obj = coupon_obj.content_object
    
            # 4. 通过ContentType表找到表模型:app名 + 表名
            content = ContentType.objects.filter(app_label="demo", model="food").first()
            print(content)  # food
            # model_class()方法得到食物表模型,即food_obj
            model_class = content.model_class()
            ret = model_class.objects.all()
            print(ret)  # <QuerySet [..., ...]>
    
            return Response("ContentType测试")
    
    
返回