Django - ContentType 组件 - 与多个表进行快捷的关联

目录

一、表关系结构

二、models创建表结构

三、视图函数的数据操作

3-1 数据的插入操作

3-1-1 方式一:获取表C内 课程字段和表字段值,进行插入

3-1-2 方式二:获取表C内 content_obj字段对象,进行插入

3-2 数据的查询 - GenericRelation 字段的使用


一、表关系结构

二、models创建表结构

总结: 

  • ContentType - 内部存在的ContentType 表表名,需要额外导入 - 创建后默认名为django_content_type
    • from django.contrib.contenttypes.models import ContentType
  • GenericForeignKey - 生产内部字段,用于查询和插入
    • def __init__(self, ct_field='content_type', fk_field='object_id', for_concrete_model=True)
  • GenericRelation - 生产内部字段,用于建立表关系,方便字段的查询
    def __init__(self, to, 
                    object_id_field='object_id', 
                    content_type_field='content_type',
                    for_concrete_model=True,
                    related_query_name=None, limit_choices_to=None, **kwargs)
  • GenericForeignKey 和 GenericRelation 内的两个字段必须一一对应
    • ct_field 等于 content_type_field
    • fk_field 等于 object_id_field
from django.db import models

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


# Create your models here.

class Couser(models.Model):
    title = models.CharField(max_length=32)
    # 不需要做数据库迁移,这个字段不会在数据表中生成,只用来方便查询
    policy = GenericRelation('PricePolicy', object_id_field='course_id', content_type_field='table_id')

    def __str__(self):
        return self.title


class DegreeCouser(models.Model):
    title = models.CharField(max_length=32)
    policy = GenericRelation('PricePolicy', object_id_field='course_id', content_type_field='table_id')

    def __str__(self):
        return self.title


class PricePolicy(models.Model):
    price = models.DecimalField(max_digits=8, decimal_places=2)
    period = models.CharField(max_length=32)
    
    # 强调:如果是外部导入的表,不能带引号,
    # 表的id,外键ContentType表
    table_id = models.ForeignKey(to=ContentType)
    # table_bb = models.ForeignKey(to='contenttypes.ContentType')
    
    # 课程id -- PositiveIntegerField():正整数
    course_id = models.IntegerField()
    
    # 不需要做数据库迁移,也不会再数据库生成字段,只用来做查询和插入
    # 如果保存的时候,只需要传content_obj这个字段,内部自动会保存table_id,course_id
    content_obj = GenericForeignKey('table_id', 'course_id')
    # 如果表id 字段名叫:content_type ,课程id字段名叫:object_id  GenericForeignKey就不需要传参数
    # GenericForeignKey -- def __init__(self, ct_field='content_type', fk_field='object_id', for_concrete_model=True)

三、视图函数的数据操作

3-1 数据的插入操作

3-1-1 方式一:获取表C内 课程字段和表字段值,进行插入

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


def test3(request):

    # 为couser表内couser1,在表pricepolicy内添加三个价格策略
    course = models.Couser.objects.get(pk=1)
    table_id = ContentType.objects.get(model='couser')

    models.PricePolicy.objects.create(price=9.9, period='1个月', table_id=table_id, course_id=course.pk)
    models.PricePolicy.objects.create(price=19.9, period='2个月', table_id=table_id, course_id=course.pk)
    models.PricePolicy.objects.create(price=29.9, period='3个月', table_id=table_id, course_id=course.pk)

    return HttpResponse('ok')

3-1-2 方式二:获取 表C内content_obj字段对象,进行插入

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


def test3(request):

    # 使用contenttype插入
    course = models.Couser.objects.get(pk=2)
    models.PricePolicy.objects.create(price=9.9, period='1个月', content_obj=course)
    models.PricePolicy.objects.create(price=19.9, period='2个月', content_obj=course)
    models.PricePolicy.objects.create(price=29.9, period='3个月', content_obj=course)

    # 给degree表对象加一个价格策略
    degree_course=models.DegreeCouser.objects.get(pk=1)
    models.PricePolicy.objects.create(price=29.9, period='3个月', content_obj=degree_course)

    return HttpResponse('ok')

3-2 数据的查询 - GenericRelation 字段的使用

from django.shortcuts import render, HttpResponse
from app01 import models


def test3(request):


    # 查询所有价格策略,并且显示对应的课程名称
    ret = models.PricePolicy.objects.all()
    for i in ret:
        print(type(i.content_obj))  # <class 'app01.models.Couser'>
        print(i.content_obj)  # couser1 联系的表对象

    # 查询couser1所有的价格策略
    # 获取couser1对象
    course = models.Couser.objects.get(pk=1)

    # 笨办法:
    #   获取course课程
    #   获取course表名
    #   contenttype表中,根据表的名字查询表的id
    #   PricePolice表查询所有的价格策略

    # 新方法:利用 GenericRelation 字段 policy
    course_police = course.policy.all()
    for i in course_police:
        print(type(i))  # <class 'app01.models.PricePolicy'>
        print(i.period)  # 1个月

    return HttpResponse('ok')

猜你喜欢

转载自blog.csdn.net/qq_33961117/article/details/85162490
今日推荐