码迷,mamicode.com
首页 > 其他好文 > 详细

ContentType

时间:2020-06-20 16:50:58      阅读:48      评论:0      收藏:0      [点我收藏+]

标签:round   信息   并且   com   get   strong   lazy   object   osi   

组件的作用:可以通过两个字段让表和N张表创建FK关系

项目背景

有课程,学位课(不同的课程字段不一样),价格策略

问题:1 如何设计表结构,来表示这种规则
         2 为专题课,添加三个价格策略
           3 查询所有价格策略,并且显示对应的课程名称
           4 通过课程id,获取课程信息和价格策略

 版本一

一个课程表,包含学位课和专题课,一个价格策略表,一对多关联

技术图片

  版本二

学位课表,专题课表价格策略表(在价格策略课表中加入多个FK跟课程表做关联):后期再加其它课程,可维护性差

技术图片

   最终版(使用ContentType)

通过Django提供的ContentType表,来构建

技术图片  技术图片

   models层创建:

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)  # 关联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() 

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

models.py文件的表结构写好后,通过makemigrations和migrate两条命令迁移数据后,在数据库中会自动生成一个django_content_type表:

技术图片 

 每当我们创建了新的model并执行数据库迁移后,ContentType表中就会自动新增一条记录。比如我在应用app01的models.py中创建表DegreeCourse、course与PricePolicy。从数据库查看ContentType表,显示如下:

技术图片 

views层:

from django.shortcuts import render,HttpResponse
from app01 import models
from django.contrib.contenttypes.models import ContentType

def test(request):
    # 1.在价格策略表中添加一条数据
    # models.PricePolicy.objects.create(
    #     valid_period=7,
    #     price=6.6,
    #     content_type=ContentType.objects.get(model=‘course‘),
    #     object_id=1
    # )

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

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

    # 3.找到某个课程关联的所有价格策略
    obj = models.Course.objects.get(id=1)
    for item in obj.policy_list.all():
        print(item.id,item.valid_period,item.price)

    return HttpResponse(...)

 

ContentType

标签:round   信息   并且   com   get   strong   lazy   object   osi   

原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/13168828.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!