13.ContentType组件

1.问题:一张表上如何对多个表进行外键关联

from django.db import models
 
 
class Appliance(models.Model):
    """
    家用电器表
    id name
    1   冰箱
    2   电视
    3   洗衣机
    """
    name = models.CharField(max_length=64)
 
 
class Food(models.Model):
    """
    食物表
    id name
    1  面包
    2  牛奶
    """
    name = models.CharField(max_length=32)
 
 
class Fruit(models.Model):
    """
    水果表
    id  name
    1   苹果
    2   香蕉
    """
    name = models.CharField(max_length=32)
 
 
class Coupon(models.Model):
    """
    优惠券表
    id  name    appliance_id    food_id     fruit_id
    1   通用优惠券   null            null        null
    2   冰箱折扣券   1               null        null
    3   电视折扣券   2               null        null
    4   苹果满减卷   null            null        1
    """
    name = models.CharField(max_length=32)
    appliance = models.ForeignKey(to="Appliance", null=True, blank=True)
    food = models.ForeignKey(to="Food", null=True, blank=True)
    fruit = models.ForeignKey(to="Fruit", null=True, blank=True)

注意

1.每增加一张表就需要多增加一个字段,

2.定义:ContentTypes组件

ContentTypes是Django内置的一个组件

可以追踪项目中所有app和model的对应关系,并记录在ContentType表中

当一张表要跟多张表进行外键关联的时候,我们可以使用Django提供的ContentType 组件

app1/models.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
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      title
    1       面包
    2       牛奶
    """
    title = models.CharField(max_length=32)
    # 不会生成coupons字段,只用于反向查询
    coupons = GenericRelation(to="Coupon")


class Fruit(models.Model):
    """
    id      title
    1       苹果
    2       香蕉
    """
    title = models.CharField(max_length=32)


class Coupon(models.Model):
    title = models.CharField(max_length=32)
    # 第一步:在 model中定义ForeignKey字段,并关联到ContentType表
    content_type = models.ForeignKey(to=ContentType, null=True, blank=True, on_delete=models.SET_NULL)
    # 第二步:定义IntegerField字段,用来存储关联表中的主键
    object_id = models.IntegerField()
    # 第三步 不会生成字段传入上面两个字段的名字
    content_object = GenericForeignKey("content_type", "object_id")

django_content_type表

在这里插入图片描述

app1_coupon表

在这里插入图片描述

food表

在这里插入图片描述

app1\view.py

from django.contrib.contenttypes.models import ContentType
from django.http import HttpResponse
from django.views import View

from app1.models import Food, Coupon


class DemoView(View):

    def get(self, request):
        # 1.通过ContentType表找表模型
        content = ContentType.objects.filter(app_label="app1", model="food").first()
        content.get_object_for_this_type(id=1)
        # 2.获得表model对象 相当于models.app1
        model_class = content.model_class()
        print(model_class.objects.all())

        # 给面包创建一个优惠券
        food_obj = Food.objects.get(id=1)
        # 方式一
        Coupon.objects.create(title="面包九五折", content_type_id=8, object_id=1)
        # 方式二
        t = Coupon(title="双十一面包九折促销", content_object=food_obj)
        t.save()

        # 正向查询:根据优惠信息查询优惠对象
        coupon_obj = Coupon.objects.get(id=1)
        print(coupon_obj.content_object.title)

        # 反向查询:查询面包都有哪些优惠券
        food_obj = Food.objects.filter(id=1).first()
        coupons = food_obj.coupons.all()
        print(coupons[0].title)

        # 如果没定义反向查询
        food_obj = Food.objects.filter(id=1).first()
        food_type = ContentType.objects.get_for_model(Food)
        result = Coupon.objects.filter(content_type=food_type, object_id=food_obj.id).all()
        print(result[0].title)

        return HttpResponse("ContentType测试")

posted @   阿无oxo  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示