ContentType组件

什么时候才用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")

 

posted @ 2020-10-30 15:27  断浪狂刀忆年少  阅读(87)  评论(0编辑  收藏  举报