GenericForeignKey和GenericRelation的用法

GenericForeignKey和GenericRelation的用法

背景:

假设现在有几个新增的数据都需要审批如地址,销售单信息等,并且后续还会有,使用外键的写法为

from django.db import models
from django.contrib.auth.models import User

# 地址
class Address(models.Model):
    owner = models.ForeignKey(User,on_deleter=models.CASCADE)
    addr = models.TextField(blabk=True)

# 销售单    
class SaleOrder(models.Model):
    owner = models.ForeignKey(User,on_deleter=models.CASCADE)
    order_data = models.TextField(blabk=True)

# 审批单    
class Apply(models.Model):
    body = models.TextField(blabk=True)
    address = models.ForeignKey(Address,on_deleter=models.CASCADE,null=True)
    sale_order =  models.ForeignKey(SaleOrder,on_deleter=models.CASCADE,null=True)

这个情况会导致,每新增一个需要审批的模型,Apply就要加一个字段

而且,那么多的外键,只有某个外键有值

有没有一种外键,可以关联所有想关联的模型?有

它就是通用外键GenericForeignKey

使用

  • GenericForeignKey和GenericRelation需要一起使用
  • 配置
# settings.py
INSTALLED_APPS = [
	...
	"django.contrib.contenttypes",
	...
]
  • 改写模型
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey

# 地址
class Address(models.Model):
    owner = models.ForeignKey(User,on_deleter=models.CASCADE)
    addr = models.TextField(blabk=True)
    apply = GenericRelation(Apply)

# 销售单    
class SaleOrder(models.Model):
    owner = models.ForeignKey(User,on_deleter=models.CASCADE)
    order_data = models.TextField(blabk=True)
    apply = GenericRelation(Apply)

# 审批单    
class Apply(models.Model):
    body = models.TextField(blabk=True)
    content_type = JyForeignKey(ContentType, on_delete=models.SET_NULL, null=True)
    object_id = models.PositiveIntegerField('审批对象ID', default=None, null=True)
    # 可以在审批对象表上加GenericRelation 方便反向关联
    # approval_obj作用是只要这一个字段,就能关联多个表
    approval_obj = fields.GenericForeignKey('content_type', 'object_id')
  • 其他

有需要的可以查看官方文档:https://docs.djangoproject.com/en/2.2/ref/contrib/contenttypes/

posted @ 2022-12-02 15:32  umbrella~  阅读(161)  评论(0编辑  收藏  举报