什么时候才用ContentType?
当一张表跟 n 张表动态地创建 ForeignKey 关系时,而不是创建太多列,因为数据表中会有很多空值。
ContentType 通过仅两列字段就实现了 n 张表的 ForeignKey 关系。
表的设计
from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation class Food(models.Model): """ id name 1 酱香饼 2 鸡蛋饼 3 水煎包 """ name = models.CharField(max_length=32) # 不生成字段只用于反向查询 coupons = GenericRelation(to="Coupon") class Fruit(models.Model): """ id name 1 红心蜜柚 2 黑美人西瓜 """ name = models.CharField(max_length=32) coupons = GenericRelation(to="Coupon") class Coupon(models.Model): """ id title food_id fruit_id .......... 1 酱香饼买一送一 1 null 2 黑美人西瓜2折 null 2 id title table_id object_id 1 酱香饼买一送一 1 1 2 黑美人西瓜2折 2 2 """ title = models.CharField(max_length=32) # 第一版设计 # food = models.ForeignKey(to="Food") # fruit = models.ForeignKey(to="Fruit") # 第二版设计 # table = models.ForeignKey(to="MyTables") # object_id = models.IntegerField() # 第三版 用django自带的ContentType表 content_type = models.ForeignKey(to=ContentType) object_id = models.IntegerField() # 不会生成字段 只用于关联到对象的 content_object = GenericForeignKey("content_type", "object_id") # class MyTables(models.Model): # """ # id app_name table_name # 1 Demo Food # 2 Demo Fruit # """ # app_name = models.CharField(max_length=32) # table_name = models.CharField(max_length=32)
视图
from django.shortcuts import render from rest_framework.views import APIView from django.http import HttpResponse from .models import Food, Fruit, Coupon from django.contrib.contenttypes.models import ContentType class TestView(APIView): def get(self, request): # 找到表id以及表对象 # content_type_obj = ContentType.objects.filter(app_label="Demo", model="food").first() # 这里拿到是表名 # print(type(content_type_obj)) # model_class = content_type_obj.model_class() # 这里拿到是模型表的类 # print(model_class) # print(content_type_obj.id) #拿到表Id # 给酱香饼创建优惠券 food_obj = Food.objects.filter(id=1).first() Coupon.objects.create(title="酱香饼买一送小威",content_object=food_obj) # 给黑美人创建优惠券 # fruit_obj = Fruit.objects.get(id=2) # Coupon.objects.create(title="黑美人2折", content_type_id=9, object_id=2) # 查询优惠券绑定对象 # coupon_obj = Coupon.objects.filter(id=1).first() # print(coupon_obj.content_object.name) # 查某个对象的优惠券 food_obj = Food.objects.filter(id=1).first() print(food_obj.coupons.all()) return HttpResponse("ok")