Django中的模型设计

Posted

技术标签:

【中文标题】Django中的模型设计【英文标题】:Model Design in Django 【发布时间】:2021-05-01 01:41:09 【问题描述】:

我有很多组件,我想为每个组件创建一个列表,其中显示哪些用户使用了该组件以及其中有多少?

class Component(models.Model):
    name=models.CharField(max_length=128,unique=False,blank=False)
    detail=models.TextField()
    max_num=models.IntegerField(default=0)
    issued_num=models.IntegerField(default=0)

    def __str__(self):
        return self.name

    def save(self,*args,**kwargs):
        super().save(args,kwargs)

    def available(self):
        return self.max_num-self.issued_num

Status=((0,"Pending"),(1,"Accepted"),(2,"Rejected"))

class Issued(models.Model):
    request_user=models.ForeignKey(User,on_delete=models.CASCADE)
    component=models.ForeignKey(Component,on_delete=models.CASCADE)
    status=models.IntegerField(choices=Status,default=0)
    request_num=models.IntegerField(default=0)

    def __str__(self):
        return self.component.name

我提出了这个解决方案,其中根据状态发布的模型将显示为请求,或者将根据其状态处理发布请求的确认

任何人都可以告诉它是正确的方法还是它不建议数据库友好的设计

【问题讨论】:

我觉得不错。您可以在组件模型中通过 as Issued 向 User 添加 ManyToMany 字段,以便更轻松地使用模型进行查询,但数据库看起来相同。在文档中检查这一点ManyToManyField.through 我不建议在这里使用 m2m 字段,因为每个问题只有一个用户 @AbdulAzizBarkat 感谢您的建议,我会调查一下 @CosmicReindeer 我不是指问题和用户之间的 m2m。我的意思是用户和组件之间的 m2m,问题是直通模型。 OP 已经这样做了,只是没有直接指定 m2m。 【参考方案1】:

我宁愿将issued_num作为模型的属性,并使用反向关系来确定它的值。

class Component(models.Model):
    name=models.CharField(max_length=128,unique=False,blank=False)
    detail=models.TextField()
    max_num=models.IntegerField(default=0)

    def __str__(self):
        return self.name

    @property
    issued_num(self):
    # self.issue_set returns a queryset
    return self.issue_set.count()

    @property
    def available(self):
        return self.max_num - self.issued_num

    def save(self, *args, **kwargs):
    # override save method to check for issue overflows
    if self.max_num <= self.issued_num:
        raise ValidationError('max issues reached')

class Issue(models.Model):
    Status=((0,"Pending"),(1,"Accepted"),(2,"Rejected"))

    request_user=models.ForeignKey(User,on_delete=models.CASCADE)
    component=models.ForeignKey(Component,on_delete=models.CASCADE)
    status=models.IntegerField(choices=Status,default=0)
    request_num=models.IntegerField(default=0)

    def __str__(self):
        return self.component.name

这样,您无需在每次创建问题对象时都更新issued_num 字段。这意味着访问数据库的次数更少。

你可以阅读更多关于跟随后向关系here。

【讨论】:

以上是关于Django中的模型设计的主要内容,如果未能解决你的问题,请参考以下文章

django模型

Django:模型设计,ManyToMany 属性字段?

Django框架:设计模型

Django基于PythonWeb的Django框架设计实现天天生鲜系统-3模型创建

django中的Model模型一:

Django基础核心技术之Model模型的介绍与设计