zoukankan      html  css  js  c++  java
  • Django ContentType组件

    Django ContentType组件

    需求

    现在我们有这样一个需求~我们的商城里有很多的商品~~节日要来了~我们要搞活动~~

    那么我们就要设计优惠券~~优惠券都有什么类型呢~~满减的~折扣的~立减的~~

    我们对应着我们活动类型~对我们的某类商品设计优惠券~~比如~~

    家电是一类商品~~食物是一类商品~那么我们可以设计家电折扣优惠券~~以及食物满减优惠券等~

    那么我们看表结构怎么设计~~

    # by gaoxin
    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)<br># 实际上我们商品的种类会特别的多,导致我们这张表外键越来越多

    遇到这种一张表要跟多张表进行外键关联的时候~我们Django提供了ContentType组件~

    ContentType组件

    ContentType是Django的内置的一个应用,可以追踪项目中所有的APP和model的对应关系,并记录在ContentType表中。

    当我们的项目做数据迁移后,会有很多django自带的表,其中就有django_content_type表,我们可以去看下~~~

    ContentType组件应用:

      -- 在model中定义ForeignKey字段,并关联到ContentType表,通常这个字段命名为content-type

      -- 在model中定义PositiveIntergerField字段, 用来存储关联表中的主键,通常我们用object_id

      -- 在model中定义GenericForeignKey字段,传入上面两个字段的名字

      --  方便反向查询可以定义GenericRelation字段

    代码如下:

      

    # by gaoxin
    from django.db import models
    from django.contrib.contenttypes.models import ContentType
    from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
     
     
    class Appliance(models.Model):
        """
        家用电器表
        id name
        1   冰箱
        2   电视
        3   洗衣机
        """
        name = models.CharField(max_length=64)
        coupons = GenericRelation(to="Coupon")
     
     
    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)
        # 第一步
        content_type = models.ForeignKey(to=ContentType)
        # 第二步
        object_id = models.PositiveIntegerField()
        # 第三步
        content_object = GenericForeignKey('content_type', 'object_id')  

    数据迁移后~添加数据~我们看下增删改查的操作~~

    基本的使用~

    from django.http import HttpResponse
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from django.contrib.contenttypes.models import ContentType
    from .models import Appliance, Coupon
     
    # Create your views here.
     
     
    class Test(APIView):
     
        def get(self, request):
            # 通过ContentType获得表名
            content = ContentType.objects.filter(app_label="app01", model="appliance").first()
            # 获得表model对象 相当于models.Applicance
            model_class = content.model_class()
            ret = model_class.objects.all()
     
            # 为海尔冰箱创建一条优惠记录
            ice_box = Appliance.objects.filter(id=1).first()
            Coupon.objects.create(name="海尔冰箱折扣券", content_object=ice_box)
     
            # 查询优惠券id=1绑定了哪个商品
            coupon_obj = Coupon.objects.filter(id=1).first()
            goods_obj = coupon_obj.content_object
            print(goods_obj.name)
     
            # 查询海尔冰箱的所有优惠券 id=1
            # 我们定义了反向查询
            results = ice_box.coupons.all()
            print(results[0].name)
     
            # 如果没定义反向查询
            content = ContentType.objects.filter(app_label="app01", model="appliance").first()
            result = Coupon.objects.filter(content_type=content, object_id=1).all()
            print(result[0].name)
            return HttpResponse(ret)
  • 相关阅读:
    VIM的强大功能
    BigDecimal.ROUND_HALF_XXX的各种用法
    拒绝服务攻击
    浅谈(接口)测试注意事项四
    jmeter 与 java http
    Xms Xmx PermSize MaxPermSize 区别
    Jquery过滤器
    JQ工具函数运用
    C#扩展方法
    LINQ TO XML基础
  • 原文地址:https://www.cnblogs.com/chengege/p/10990160.html
Copyright © 2011-2022 走看看