• 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")
    幻想毫无价值,计划渺如尘埃,目标不可能达到。这一切的一切毫无意义——除非我们付诸行动。
  • 相关阅读:
    5
    4
    3
    crontab -e 报错(E518: Unknown option: foldenable)
    解决无法修改日志时间的问题(Local time zone must be set--see zic manual page 2019 )
    ping测试丢包率
    关闭SELinux
    iotop使用方法
    mysql的备份
    修改uid gid 的起始范围
  • 原文地址:https://www.cnblogs.com/TodayWind/p/13902376.html
Copyright © 2020-2023  润新知