Django ContentType(ORM操作)
阅读原文时间:2023年07月08日阅读:2

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解决的问题:一个表的两个字段与另外两张表有关联(关联关系是交叉的)
"""

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')

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器