欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Django ContentType组件详解

程序员文章站 2022-03-16 18:57:58
目录问题注意总结问题如何在一张表上对多个表进行外键关联from django.db import modelsclass appliance(models.model): """ 家用电器...

问题

如何在一张表上对多个表进行外键关联

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.每增加一张表就需要多增加一个字段,

定义

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

contenttypes是django内置的一个组件,可以追踪项目中所有app和model的对应关系,并记录在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, on_delete=none)
    # 第二步:定义integerfield字段,用来存储关联表中的主键
    object_id = models.integerfield()
    # 第三步 不会生成字段传入上面两个字段的名字
    content_object = genericforeignkey("content_type", "object_id")

app1\view.py

class demoview(apiview):
    def get(self, request):
        # 1.通过contenttype表找表模型
        content = contenttype.objects.filter(app_label="app1", model="food").first()
        # 获得表model对象 相当于models.app1
        model_class = content.model_class()
        ret = model_class.objects.all()
        print(ret)
        # 给面包创建一个优惠券
        food_obj = food.objects.filter(id=1).first()
        coupon.objects.create(title="面包九五折", content_type_id=8, object_id=1)
        coupon.objects.create(title="双十一面包九折促销", content_object=food_obj)
        # 正向查询:根据优惠信息查询优惠对象
        coupon_obj = coupon.objects.filter(id=1).first()
        content_obj = coupon_obj.content_object
        print(content_obj.title)
        # 反向查询:查询面包都有哪些优惠券
        coupons = food_obj.coupons.all()
        print(coupons[0].title)
        # 如果没定义反向查询
        content = contenttype.objects.filter(app_label="app1", model="food").first()
        result = coupon.objects.filter(content_type=content, object_id=1).all()
        print(result[0].name)
        return response("contenttype测试")

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!