Django ContentType(ORM操作)

ContentType-设计课程表

# 数据:
"""
免费课:Python入门
学位课:Python全栈

价格策略:
Linux入门        7        0
Python入门      7          0
Python入门      14         9.9
Python入门    30        199
Python全栈    180        18888
Python全栈    240        23888
"""

# 设计
""" 不合理
# Course表
# id         name         type          price_policy     normal_course     degreecourse
   1      Linux入门      免费课            1                    有            空
   2      Python入门    免费课            2                    有            空
   3      Python入门    免费课            3                    有            空    
   4      Python全栈    学位课            4                    空             有    

# PricePolicy表
# id         day         price
   1        7            0
   2        7            0
   3        14            9.9
   4        180            18888
"""

"""
# Course表
# id         name         normal_course(该表独有的字段)
   1      Linux入门              数据            
   2      Python入门            数据            

# DegreeCourse表
# id         name         degreecourse(该表独有的字段)
   1      Python全栈              数据        

# PricePolicy表
# id         day         price        couse_id    course_type
   1        7            0                1            免费课
   2        7            0                2            免费课
   3        14            9.9                2            免费课
   4        180            18888            1            学位课   
   
# 问题点:课程相关表的 主键 与 表名 两个信息 在价格策略表中
# 问题1:couse_id数据不具备唯一性,不能成为外键
# 问题2:couse_id与course_type能否生成联合唯一外键?
    -- course_type是与表名有联系,并不是 课程相关表 的表字段
    -- couse_id与course_type能不能保证唯一性
"""

# 解决方案
"""
# Course表
# id         name         normal_course(该表独有的字段)
   1      Linux入门              数据            
   2      Python入门            数据            

# DegreeCourse表
# id         name         degreecourse(该表独有的字段)
   1      Python全栈              数据        

# PricePolicy表
# id         day         price        couse_id    course_type(外键)
   1        7            0                1            1
   2        7            0                2            1
   3        14            9.9                2            1
   4        180            18888            1            2  

# TableName表 => ContentType
id         table_name
1          course
2          degree_course

ContentType解决的问题:一个表的两个字段与另外两张表有关联(关联关系是交叉的)
"""
View Code

ContentType-开发使用 

"""
# Course表
# id         name     
   1      Python入门        

# DegreeCourse表
# id         name         
   1      Python全栈    

# PricePolicy表
# id         day         price        couse_id    course_type(外键)
   1        7            0                1            1
   2        14            9.9                1            1
   3        180            18888            1            2  

# ContentType表
id         table_name
1          course
2          degreecourse
"""

models.py

from django.db import models

from django.contrib.contenttypes.fields import GenericRelation

class Course(models.Model):
    name = models.CharField(max_length=32)
    # price_policy = GenericRelation(to='PricePolicy',object_id_field='object_id',content_type_field='content_type')
    # 当你的类GenericRelation关联的表PricePolicy中的字段和(object_id_field='object_id', content_type_field='content_type'),
    # 字段名字完全一致时可以省略object_id_field和content_type_field的参数
    price_policy = GenericRelation(to='PricePolicy')  # 用户连表查询,不会在数据库中产生字段

class DegreeCourse(models.Model):
    name = models.CharField(max_length=32)
    price_policy = GenericRelation(to='PricePolicy')

from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey

class PricePolicy(models.Model):
    day = models.IntegerField()
    price = models.CharField(max_length=8)
    # course_id = models.IntegerField()  # 某课程表的主键,但是不具备唯一性,所以只能用IntegerField
    # course_type = models.CharField(max_length=16)  # 一会儿要改成外键
    # course_type = models.ForeignKey(to=ContentType, null=True)
    # model_object = GenericForeignKey(ct_field='course_type', fk_field='course_id')
    object_id = models.IntegerField()
    content_type = models.ForeignKey(to=ContentType, null=True)
    #   改操作只用于ContentType连表查询,不会产生表字段,就是关联课程表的对象
    # 当你在此类中有和GenericForeignKey所需要的参数(ct_field='content_type', fk_field='object_id'),
    # 即ct_field和fk_field参数所需的字段名字完全一致时可以胜率这两个参数的值
    model_object = GenericForeignKey()

Views.py

from django.shortcuts import HttpResponse
from api import models

def add_course(request):
    # 为python入门 免费课增加两条价格策略
    # course = models.Course.objects.filter(pk=1).first()
    # content_type = models.ContentType.objects.filter(model='course').first()# course应该写活
    # models.PricePolicy.objects.create(day=7, price=0, course_id=course.pk, content_type=content_type)
    # course = models.Course.objects.filter(pk=1).first()
    # print(course._meta.model_name)  # 为model对象表名小写
    # content_type = models.ContentType.objects.filter(model=course._meta.model_name).first()
    # models.PricePolicy.objects.create(day=14, price=9.9, course_id=course.pk, content_type=content_type)

    # 上述方法是在models.py中PricePolicy类中的course_id和course_type字段没有注释之前的方法
    # 为Python全栈 学位课程添加一条价格策略  采用ContentType来实现
    # degree_course = models.DegreeCourse.objects.filter(pk=1).first()
    # models.PricePolicy.objects.create(day=180, price=18888, model_object=degree_course)

    # 查找所有课程的所有价格策略
    # price_policy_list = models.PricePolicy.objects.all()
    # for price_policy in price_policy_list:
    #     print(price_policy.model_object.name, price_policy.day, price_policy.price)

    # 查看Python入门的所有价格策略
    course = models.Course.objects.filter(pk=1).first()
    price_policy_list = course.price_policy.all()
    for price_policy in price_policy_list:
        print(course.name, price_policy.day, price_policy.price)
    return HttpResponse('ok')
原文地址:https://www.cnblogs.com/ShenJunHui6/p/10910928.html