zoukankan      html  css  js  c++  java
  • django -- ContentType

    前戏

    假设现在我们有很多张表,比如Food表,Fruit表等等。有一天这些东西都要打折,那我们要新建一张表,里面写的打折信息,要把所有的表都关联在一起,这样的话就会在一张表里有很多的外键,例如下面的。

    from django.db import models
    
    class Food(models.Model):
        """
        id    name
        1     麻婆豆腐
        2     木耳炒牛肉
        3     西红柿炒鸡蛋
        """
        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    title           food_id   fruit_id  ..........
        1    麻婆豆腐买一送一     1         null
        2     香蕉2折          null        2
        """
        title = models.CharField(max_length=32)
        food = models.ForeignKey(to="Food")
        fruit = models.ForeignKey(to="Fruit")

    优化表结构

    既然一张表里有这么多的外键,那我们可不可以新建一张表,专门用来存放app和表名的,如下

    from django.db import models
    
    class Food(models.Model):
        """
        id    name
        1     麻婆豆腐
        2     木耳炒牛肉
        3     西红柿炒鸡蛋
        """
        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    title           food_id   fruit_id  ..........
        1    麻婆豆腐买一送一     1         null
        2     香蕉2折          null        2
        """
        title = models.CharField(max_length=32)
        table = models.ForeignKey(to="MyTables")
        object_id = models.IntegerField()
    
    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)

    Mytables表里存放了我们所有的app名和表名,在Coupon表里通过外键关系关联到MyTables表,这样就解决了一张表里多个外键的问题

    ContentType

    Django在生成数据表的时候已经给我们提供了这张表“MyTables”,表名叫content_type,里面的字段含义和我们自定义的一样

     所以第三张表就不用我们自己创建了,直接使用Django自带的就可以了

    from django.db import models
    from django.contrib.contenttypes.models import ContentType
    from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
    
    
    
    class Food(models.Model):
    
        name = models.CharField(max_length=32)
        # 不生成字段只用于反向查询
        coupons = GenericRelation(to="Coupon")
    
    
    class Fruit(models.Model):
     
        name = models.CharField(max_length=32)
        coupons = GenericRelation(to="Coupon")
    
    
    class Coupon(models.Model):
       
        title = models.CharField(max_length=32)
        content_type = models.ForeignKey(to=ContentType)
        object_id = models.IntegerField()
        # 不会生成字段 只用于关联到对象的
        content_object = GenericForeignKey("content_type", "object_id")

    使用ORM添加数据

    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以及表对象
            food_obj = Food.objects.filter(id=1).first()
            # 往Coupon表里插数据
            Coupon.objects.create(title="水密桃大甩卖", content_object=food_obj)
            return HttpResponse("ok")

    查询数据

    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):
            # 查询出来的是Food或者Fruit对象
            coupon_obj = Coupon.objects.filter(id=1).first()
            # 通过content_object.name拿到对应的name值
            print(coupon_obj.content_object.name)
            # 查某个对象的优惠券
            food_obj = Food.objects.filter(id=1).first()
            print(food_obj.coupons.all())
            return HttpResponse("ok")
  • 相关阅读:
    垃圾回收的整个过程
    实验:老年代空闲空间放不下minorgc晋升的对象发生fullgc
    实验: survivor放不下的对象进入老年代
    实验: 动态对象年龄判定
    永久代、栈内存大小怎么设置
    如何设置高并发系统的jvm堆内存大小
    Bin、App_Data等文件夹详述(转自http://blog.csdn.net/zzjiadw/article/details/6801506)
    谈谈并行、并发或多线程
    SQL---存储过程---存储过程编写案例
    SQL---存储过程---sp_addextendedproperty表字段加描述
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/11601110.html
Copyright © 2011-2022 走看看