背景

现在我们要出售两种课程,一种学位课程一种专业课程,两种课程中都有很多课,并且不同的课根据时间不同售价也不同,现在我们要求两种课程分为两张表,然后在价格表中我们应该有时间周期字段,价格字段,还应该有和课程关联的字段,这时我们可以做一个外键关联

但是这里有两张课程表,所以我们要有两个外键字段,分别关联两张课程表,这样就可以实现我们的要求,但是如果现在我们又添加一种课程,那在价格表中就需要多一个关联字段,这样增加字段是不太好的,所以我们要想一个办法,让它能满足我们的要求

建表

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=32)

class Course(models.Model):
    name = models.CharField(max_length=32)

    # 数据库不生成,只用于链表查询
    policy_list = GenericRelation("PricePolicy")

class PricePolicy(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()

    # 不在数据库中生成,只用于帮助你做数据操作
    content_object = GenericForeignKey('content_type', 'object_id')

    period = models.CharField(max_length=32)
    price = models.FloatField()

可以看到我们创建了3张表,学位课程表,专业课程表和价格表,在价格表中我们有一个content_boject字段,这个字段不会在数据库中生成,只用来帮我们做数据操作,还有两个字段,分别是content_type字段,这个字段其实对应的就是一个表名,而object_id字段对应

的就是相应表中的数据id,这样不管有几个课程表,我们都可以用这两个字段来表示出数据的关联

那么这个content_type字段关联的是什么呢,其实我们在建表后进行数据化迁移时django会自动帮我们生成一些表

其中有一张django_content_type表

可以看到,这个表中放着我们所有生成表的表名,通过这张表我们就能将我们的价格和表名关联上了

给价格表增加内容

为专业课1添加3个价格策略

# course_obj内部包含:id=1,表名称=course
course_obj = models.Course.objects.get(id=1)
models.PricePolicy.objects.create(period='10', price=9.9, content_object=course_obj)
models.PricePolicy.objects.create(period='20', price=19.9, content_object=course_obj)
models.PricePolicy.objects.create(period='30', price=29.9, content_object=course_obj)

首先通过专业1的id我们可以找到这个专业课对象,然后给价格表添加价格策略时我们不需要单独给content_type和object_id字段添加数据,这样会很麻烦(我们需要查询出专业课1对应的表名在django_content_type表中的id),我们可以直接使用我们之前设置的字段

content_boject,让这个字段等于我们之前查到的专业课对象course_obj即可,这样django就会自动帮我们添加content_type和object_id字段(其实course_obj中包含了id和表名称)

显示所有的价格策略,并将其对应的课程名称显示

policy_list = models.PricePolicy.objects.all()
for obj in policy_list:
    print(obj.period,obj.price,obj.content_object,obj.content_object.id,obj.content_object.name)

通过content_object字段我们可以直接取到每一条价格策略对象对应的课程对象obj.content_object,这样就可以直接点出课程的名称,这有点像正向查询

给你课程ID,获取课程信息+该课程的所有价格策略

course_obj = models.Course.objects.get(id=2)
print(course_obj.id)
print(course_obj.name)
policy_list = course_obj.policy_list.all()
for item in policy_list:
    print(item.price,item.period)

通过课程id我们可以找到对应的课程对象,这样课程的id和name都可以直接点出来,而课程对应的所有价格策略我们可以通过之前定义的policy_list字段获得,这个字段不会在数据库中生成,只是帮我们操作数据的,拿到所有的价格策略后我们使用for循环打印每一个

价格策略的周期和价格,这有点像反向查询

posted on 2018-04-12 19:29  Py行僧  阅读(132)  评论(0编辑  收藏  举报