ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

django中的content_type

2022-05-25 19:34:07  阅读:177  来源: 互联网

标签:name models price django content 车型 type id


转载于:网络

一。应用场景:
现在有3张表映射(一对多)一张表:表1,2,3一对多表4,每种车都有自己的价格策略

表1:巴士(Bus) → 字段:id,name

表2:出租车(Taxi) → 字段:id,name

表3:地铁(Metro) → 字段:id,name

表4:价格策略(PrecePolicy) → 字段:id,price,period,对应的车的表名称,id(对应表名称的行id)

二。原始解决方案:
表1,2,3分别创建,表4的创建为:

class PricePolicy(models.Model):
"""
价格策略
"""
price = models.IntegerField()
period = models.IntegerField()

table_name = models.CharField(verbose_name="关联的表名称")
object_id = models.CharField(verbose_name="关联的表中数据行的id")
缺点:这样创建和修改表比较麻烦

三。最终解决方案
1. 添加content_type字段,用来通过contentType表关联车型表

2. 添加object_id字段,用来关联车型表中的某一行

3. 添加content_object字段,用来使以上两个表关联起来

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

class PricePolicy(models.Model):
"""
价格策略
"""
price = models.IntegerField()
period = models.IntegerField()

content_type = models.ForeignKey(ContentType, verbose_name="关联的表名称", on_delete=models.CASCADE)
object_id = models.IntegerField(verbose_name="关联的表中数据行的id")
# 以下字段不添加数据表的列数,只帮助快速实现content_type操作
content_object = GenericForeignKey('content_type', 'object_id')


使用:

1. 为某一类型的车添加价格,也就是往PrecePolicy中添加数据
1.1 先获取bus的对象,可以根据任意途径获取

1.2 再添加PricePlicy,这里只设置content_object参数和PricePlicy的字段就好了

# 先获取bus的对象,可以根据任意途径获取
obj = models.Bus.objects.filter(name = 'mini').first()

# 再通过PricePlicy进行添加,这里只设置content_object参数就好了
models.PricePolicy.objects.create(price=29.9, period=90, content_object=obj)
2. 根据车型id获取车型,并获取该车型的所有价格策略
2.1 先在表类中加入GenericRelation关联反向查找的表

2.2 在view视图函数中,先获取要查找的车型对象

2.3 再通过车型获取所有的价格策略

from django.contrib.contenttype.fields import GenericRelation

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

# 这个字段不用于生成表字段,只用于反向查找
price_policy_list = GenericRelation("PricePolicy")


# 先获取车型
bus = models.Bus.objects.filter(id=1).first()

# 再通过车型获取所有的价格策略
bus.price_policy_list.all()
3. 删除车型,或者删除某一车型的某一行价格
3.1 删除车型:

只需要找出车型对象,执行delete()操作就性了,不过会把这个车型关联的价格策略全部删除

Bus.objects.filter(id=1).delete()
3.2 删除某车型的某一行价格:

# 先获取某一车型对象
busObj = Bus.objects.filter(id=1)

# 通过车型对象获取然后筛选所有要删除的价格
allBusPrice = busObj.price_policy_list.filter(price=30)

# 删除
allBusPrice.delete()
只需要找出某车型的所有对象,再通过filter过滤找到要删除的价格,执行delete()就可以了

4. 修改某车型的数据,或者修改某车型的某一行数据
4.1 修改车型:

只要找出某车型对象,然后修改,然后执行save()就行了(id还是关联contenttype表的,所以修改name不怕)

# 这里添加first表示获取对象而不是queryset
busObj = Bus.objects.filter(id=1).first()
# 修改字段数据
busObj.name = 'big'
# 保存修改
busObj.save()
4.2 修改某车型的某一行数据

先找出某车型对象对应的价格的所有对象,再通过filter过滤找到要修改的价格对象,然后修改,保存就行了

# 获取bus对象
busObj = Bus.objects.filter(id=1).first()

# 通过车型对象获取然后筛选要修改的价格对象(多个也可以,用循环就行)
changeBusPrice = busObj.price_policy_list.filter(price=30).first()

# 修改价格
changeBusPrice.price = 50

# 保存
changeBusPrice.save()

————————————————
版权声明:本文为CSDN博主「EuclideanSpace」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lgyt240054/article/details/104668769/

标签:name,models,price,django,content,车型,type,id
来源: https://www.cnblogs.com/wfitdongtao/p/16310476.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有