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中的模型设计的主要内容,如果未能解决你的问题,请参考以下文章