Remark——备注模型

文章讲述了在Django项目中,作者开始时使用外键在Remark模型中处理一对多的备注需求,随着模型增多感到不便。后来通过引入ContentType和GenericForeignKey,实现了在添加新模型时无需修改Remark模型,简化了设计并提高了灵活性。
摘要由CSDN通过智能技术生成

在众多业务相关的模型中,如Product,Project都有进行备注的需求,而且备注是多条的,即Product或Project等和备注是一对多的关系。

项目在刚开始的时候,定义Remark模型,并在Remark模型中定义和其他需要备注功能的模型的外键,实现一对多的关系。

一开始时,项目不大,要使用备注的模型不多,就3-5个左右,用这种方法还是能够接受的。但随着需要使用备注的模型越来越多,我就对这种设计越来越不爽,因为每新增一个新的模型,就要在Remark模型中新增一个外键,但一直没有找到什么好的方法(对Django了解得还是太少,直接就开干项目了)。

后面在做历史记录功能时,接触到了LogEntry这个模型,这个模型里使用了ContentType,在了解了ContentType的用法后,果断改造Remark模型。

class Remark(BaseModel):
    info = RichTextUploadingField('备注', blank=True)
    creater = models.ForeignKey(
        User, on_delete=models.SET_NULL,  blank=True, null=True,
        verbose_name='创建者', related_name='remarks_created')
    updater = models.ForeignKey(
        User, on_delete=models.SET_NULL,  blank=True, null=True,
        verbose_name='更新者', related_name='remarks_updated')
    content_type = models.ForeignKey(ContentType, blank=True,null = True,on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField(blank=True,null = True)
    content_object = GenericForeignKey('content_type', 'object_id')

精髓其实是在content_type,object_id和content_object上。

ContentType的用法不在这里过多讲解,就是通过content_type和object_id这两个属性就可以让某个Remark对象唯一对应到其他model对象上。

content_object不是一个field,自行搜索了解下GenericForeignKey就明白了。

使用了ContentType的设计后,不敢后面的需要新增多少模型,Remark这个model都不用动了,除非Remark本身的设计需要优化。

在CommonModel这个抽象类中,有一个get_remarks函数,其他继承了CommonModel的model对象通过调用get_remarks就可以获取到相关的所有备注信息了。

    def get_remarks(self):
        try:
            remarks = Remark.objects.filter( Q(content_type = self.get_contentType(), object_id = self.id) )   
            return remarks
        except Exception as err:  
            ccom_log_error(err)
            return Remark.objects.none()

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值