Django APP之contenttypes简单应用

 

Conttenttypes介绍

当你看到contenttype你是否是想到了请求头的contenttype?python

可是数据库

此contenttypes不是请求头Content-Type而是Django自带的appdjango

或许你当时没有注意到contenttypes,这里简单的介绍一下,如何用Django自带的contenttypes编程

 

业务需求

咱们要开设两大门课程,一个是专业课,一个是学位课,网络

好比专业课有:app

  •  21天python入门
  • 网络编程
  • Linux基础

学位课:运维

  • Python全栈开发
  • Linux运维

每个课程有不一样的周期,不一样的周期对应不一样的价格.spa

好比专业课的21天python入门 周期7天10块钱 周期14天15块钱设计

那么你如何设计的你表结构呢?code

 

一张学位课表,一张专业课表示必须的,那么价格表如何设计呢?

使用一张价格表?

若是某天咱们须要添加一门面授课,那么你须要在价格表上修改字段吗?增长一个Fk对应面授课?

显然不行

那么每个课对应一张表?那我有10个课,那岂不是有10个价格表?形成了资源的浪费.

 

那么有什么好的方案?

xid对应着哪一门具体的课程,table_id对应着表的名字,好比第一条table_id对应Course表id为1 21天入门python

下次须要增长课的时候,只须要增长课表,还有在存放表名的表中增长一个id对应的表名就能够解决.

可能你会说这样查询起来很麻烦,NO Django已经帮你作好了.

 

Conttenttypes的应用

加入表简单的表结构

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation


class DegreeCourse(models.Model):
    """学位课程"""
    name = models.CharField(max_length=128, unique=True)
    course_img = models.CharField(max_length=255, verbose_name="缩略图")
    brief = models.TextField(verbose_name="学位课程简介", )


class Course(models.Model):
    """专题课程"""
    name = models.CharField(max_length=128, unique=True)
    course_img = models.CharField(max_length=255)

    # 不会在数据库生成列,只用于帮助你进行查询
    policy_list = GenericRelation("PricePolicy")


class PricePolicy(models.Model):
    """价格与有课程效期表"""
    content_type = models.ForeignKey(ContentType,on_delete=models.CASCADE)  # 关联course or degree_course
    object_id = models.PositiveIntegerField()

    #不会在数据库生成列,只用于帮助你进行添加和查询
    content_object = GenericForeignKey('content_type', 'object_id')

    valid_period_choices = (
        (1, '1天'),
        (3, '3天'),
        (7, '1周'), (14, '2周'),
        (30, '1个月'),
        (60, '2个月'),
        (90, '3个月'),
        (180, '6个月'), (210, '12个月'),
        (540, '18个月'), (720, '24个月'),
    )
    valid_period = models.SmallIntegerField(choices=valid_period_choices)
    price = models.FloatField()
content_object = GenericForeignKey('content_type', 'object_id')里面的字段名必须是content_type,object_id 由于GenericForeignKey类的源码里已经写清楚了

 

建立字段

那么咱们如何添加一个价格字段?

    models.PricePolicy.objects.create(
        valid_period=14,
        price=9.9,
content_object=models.Course.objects.get(id=1) )

 content_object 字段对应的必须是一个对象,是你想要关联的object_id的对象.只要对应了一个对象他就会自动的帮你添加

content_type 对应的存放表id
object_id 对应了课表的id

在你建立表的时候,Djnaog会自动帮你建立第三张表,就是id对应表名

 

查询

   # 2. 根据某个价格策略对象,找到他对应的表和数据,如:关联课程名称
    price = models.PricePolicy.objects.get(id=2)
    print(price.content_object.name) 
    # 自动帮你找到对应课程的对象

 

若是要课程查询全部价格须要在课程表上添加一个字段

    # 不会在数据库生成列,只用于帮助你进行查询
    policy_list = GenericRelation("PricePolicy")
根据这个字段名能够跨表查询
# 3.找到某个课程关联的全部价格策略
    obj = models.Course.objects.get(id=1)
    for item in obj.policy_list.all():
        print(item.id,item.valid_period,item.price)

 

何时要用contenttypes?

  • 某一张表须要对应多个Fk字段的时候 且Fk所对应的表是同一种类型
  • 且一旦增长业务的时候,须要在该表增长FK字段
相关文章
相关标签/搜索