• 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")
  • 相关阅读:
    Android菜鸟的成长笔记(5)——Android系统源代码你下载了吗?
    2014年你不用担心的10件事
    Android菜鸟的成长笔记(4)——你真的理解了吗?
    3. MariaDB设置主从复制
    2. MariaDB激活二进制日志
    如何在CSDN博客自定义栏目中添加“给我写信”
    告别码农,成为真正的程序员
    微信公众平台开发(75)自定义菜单
    大文件分片上传,断点续传,秒传 实现
    大文件上传-大视频上传,T级别的,求解决方案
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/11601110.html
Copyright © 2020-2023  润新知