• ContentType


    1.ContentType定义

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

    2.特点

    数据库迁移后会自动生成django_content_type表,有新的表生成,数据库迁移时,会自动增加表记录

    3.应用场景

    一张表与多张表有一对多的关系时

    以商品与很优惠券的表关系为例

    正常表结构建立

     1 from django.db import models
     2 
     3 class Electrics(models.Model):
     4     """
     5     id    name
     6      1   日立冰箱
     7      2   三星电视
     8      3   小天鹅洗衣机
     9     """
    10     name = models.CharField(max_length=32)
    11 
    12 
    13 class Foods(models.Model):
    14     """
    15     id   name
    16     1    面包
    17     2    烤鸭
    18     """
    19     name = models.CharField(max_length=32)
    20 
    21 
    22 class Clothes(models.Model):
    23     name = models.CharField(max_length=32)
    24 
    25 
    26 class Coupon(models.Model):  # 特殊关系表
    27 
    28 #   id    name    electric_id   food_id   cloth_id   more...   
    29 #     1   通用优惠券   null       null      null
    30 #     2   冰箱满减券   2         null     null
    31 #     3   面包狂欢节   null        1      null
    32 
    33     name = models.CharField(max_length=32)
    34     electric = models.ForeignKey(to='Electrics', null=True,on_delete=models.CASCADE)
    35     food = models.ForeignKey(to='Foods', null=True,on_delete=models.CASCADE)
    36     cloth = models.ForeignKey(to='Clothes', null=True,on_delete=models.CASCADE)

    缺点: 每增加一张表,关系表的结构就要多加一个字段。

    通过ContentType建立的表结构

     1 from django.db import models
     2 from django.contrib.contenttypes.models import ContentType
     3 from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
     4 
     5 
     6 class Electrics(models.Model):
     7     name = models.CharField(max_length=32)
     8     price = models.IntegerField(default=100)
     9     coupons = GenericRelation(to='Coupon')  # 用于反向查询,不会生成表字段
    10 
    11     def __str__(self):
    12         return self.name
    13 
    14 
    15 class Foods(models.Model):
    16     name = models.CharField(max_length=32)
    17     price=models.IntegerField(default=100)
    18     coupons = GenericRelation(to='Coupon')
    19 
    20     def __str__(self):
    21         return self.name
    22 
    23 
    24 class Clothes(models.Model):
    25     name = models.CharField(max_length=32)
    26     price = models.IntegerField(default=100)
    27     coupons = GenericRelation(to='Coupon')
    28 
    29     def __str__(self):
    30         return self.name
    31 
    32 
    33 class bed(models.Model):
    34     name = models.CharField(max_length=32)
    35     price = models.IntegerField(default=100)
    36     coupons = GenericRelation(to='Coupon')
    37 
    38 
    39 class Coupon(models.Model):
    40     """
    41     Coupon
    42         id    name                      content_type_id       object_id_id
    43     美的满减优惠券            9(电器表electrics)  3
    44     猪蹄买一送一优惠券        10                    2
    45     南极被子买200减50优惠券   11                    1
    46     """
    47     name = models.CharField(max_length=32)
    48 
    49     content_type = models.ForeignKey(to=ContentType) # step 1 外键关联contenttype表
    50     object_id = models.PositiveIntegerField() # step 2 标记指定的指定id的对象
    51     content_object = GenericForeignKey('content_type', 'object_id') # step 3 用于反向查询的字段
    52 
    53     def __str__(self):
    54         return self.name

    4.使用

    正向查询:id为1的优惠券对应的商品名称

    正常查询

     1 #0.引入需要用到的表
     2 from app01.models import * 
     3 from django.contrib.contenttypes.models import ContentType
     4 #1.找到主键为1的优惠券对象
     5 coupon=Coupon.objects.filter(pk=1).first()
     6 #2.找到该优惠券对相应的contentType中的相应对象的id
     7 contentType_obj_id=coupon.content_type_id
     8 #3.找到该优惠券对相应的contentType中的相应对象
     9 contentType_obj=ContentType.objects.filter(pk=contentType_obj_id).first()
    10 #4.找到该对象对应的模型表
    11 model_class=contentType_obj.model_class()
    12 #5.在模型表中查找优惠券对应的商品名称
    13 ge_name=model_class.objects.filter(id=coupon.object_id)

    contentType提供的简便查询

    1 #0.引入需要用到的表
    2 from app01.models import * 
    3 from django.contrib.contenttypes.models import ContentType
    4 #1.找到主键为1的优惠券对象
    5 coupon=Coupon.objects.filter(pk=1).first()
    6 #2***.用优惠券对象直接.content_obj,Django会替我们找到该优惠券对应的商品对象***
    7 coupon.content_object

    反向查询:查询美的冰箱(id=1)的所有优惠券

    1 #1.在电器表中找到id为1的商品
    2 ele=Electrics.objects.filter(pk=1).first()
    3 #2.通过coupons字段获取该商品的所有优惠券
    4 ele.coupons.all()

     

     

     

     

     

  • 相关阅读:
    一个好的时间函数
    Codeforces 785E. Anton and Permutation
    Codeforces 785 D. Anton and School
    Codeforces 510 E. Fox And Dinner
    Codeforces 242 E. XOR on Segment
    Codeforces 629 E. Famil Door and Roads
    Codeforces 600E. Lomsat gelral(Dsu on tree学习)
    Codeforces 438D The Child and Sequence
    Codeforces 729E Subordinates
    【ATcoder】D
  • 原文地址:https://www.cnblogs.com/shanghongyun/p/10069053.html
Copyright © 2020-2023  润新知