ManytoManyField保存并计算
ManytoManyField save and calculate
我最近才开始自学 Python 和 Django 作为一种爱好,并且一直在尝试自己开发一个对我的建筑业务有帮助的项目。我在我的项目中开发了某些功能,这些功能给了我想要的结果,但在编码实践方面并不是最理想的。然而,我只是从头开始学习,边学边修改我的代码。
但是,现在我卡住了(也许是因为我的基本概念不正确?)。需要有关如何继续的帮助。
这是我的 models.py
class FootingQuantity(models.Model):
member_name = models.CharField(max_length=8, unique=True)
--more fields hidden--
x_axis = models.FloatField()
y_axis = models.FloatField()
class BeamQuantity(models.Model):
work = models.ForeignKey(Work, default=1, on_delete=models.CASCADE)
member_name = models.CharField(max_length=8, unique=True)
location = models.ManyToManyField(FootingQuantity)
length = models.FloatField(blank=True)
breadth = models.FloatField()
height = models.FloatField()
-- more fields --
@property
def length_of_beam(self):
yy = self.location.all().values_list('y_axis', flat=True)
xx = self.location.all().values_list('x_axis', flat=True)
ylist = list(yy)
xlist = list(xx)
return abs(ylist[1] - ylist[0] + xlist[1] - xlist[0])
@property
def total_concrete_quantity(self):
return float(self.length) * float(self.breadth) * float(self.width)
def save(self, *args, **kwargs):
self.length = self.length_of_beam
self.total_quantity = self.total_concrete_quantity
super(BeamQuantity, self).save(*args, **kwargs)
def __float__(self):
return self.length, self.total_quantity
我希望我的模型接受选定的 2 个基脚的 ManytoManyRelation,然后计算长度。然后长度将乘以高度和宽度得到总数量(还有其他计算,但我猜它们都因为没有得到长度而崩溃)。
目前,当我填写表格或尝试通过管理页面填写详细信息并单击“保存”时,我收到一个 ValueError
ValueError - "<BeamQuantity: B5>" needs to have a value for field "id"
before this many-to-many relationship can be used.
我认为ManytoManyField需要保存然后计算需要运行。目前两者都试图同时发生,因此出现错误。请帮忙。
确切地说,您需要先创建 BeamQuantity 实例,然后再计算 bean 的长度。暂时将这些字段留空。
为此,我建议您让所有需要多对多关系的字段都有一个值,blank=True
和 null=True
。
所以,我会像这样重写保存方法:
def save(self, *args, **kwargs):
if self.id: # it means the object was already created, so has an id.
self.length = self.length_of_beam
self.total_quantity = self.total_concrete_quantity
super(BeamQuantity, self).save(*args, **kwargs)
然后当你想创建一个 BeanQuantity 时,执行:
bean_quantity = BeanQuantity.objects.create(**fields_you_want_here)
bean_quantity.save()
第二行将运行保存方法中的代码,因为现在对象有一个id。
我最近才开始自学 Python 和 Django 作为一种爱好,并且一直在尝试自己开发一个对我的建筑业务有帮助的项目。我在我的项目中开发了某些功能,这些功能给了我想要的结果,但在编码实践方面并不是最理想的。然而,我只是从头开始学习,边学边修改我的代码。
但是,现在我卡住了(也许是因为我的基本概念不正确?)。需要有关如何继续的帮助。
这是我的 models.py
class FootingQuantity(models.Model):
member_name = models.CharField(max_length=8, unique=True)
--more fields hidden--
x_axis = models.FloatField()
y_axis = models.FloatField()
class BeamQuantity(models.Model):
work = models.ForeignKey(Work, default=1, on_delete=models.CASCADE)
member_name = models.CharField(max_length=8, unique=True)
location = models.ManyToManyField(FootingQuantity)
length = models.FloatField(blank=True)
breadth = models.FloatField()
height = models.FloatField()
-- more fields --
@property
def length_of_beam(self):
yy = self.location.all().values_list('y_axis', flat=True)
xx = self.location.all().values_list('x_axis', flat=True)
ylist = list(yy)
xlist = list(xx)
return abs(ylist[1] - ylist[0] + xlist[1] - xlist[0])
@property
def total_concrete_quantity(self):
return float(self.length) * float(self.breadth) * float(self.width)
def save(self, *args, **kwargs):
self.length = self.length_of_beam
self.total_quantity = self.total_concrete_quantity
super(BeamQuantity, self).save(*args, **kwargs)
def __float__(self):
return self.length, self.total_quantity
我希望我的模型接受选定的 2 个基脚的 ManytoManyRelation,然后计算长度。然后长度将乘以高度和宽度得到总数量(还有其他计算,但我猜它们都因为没有得到长度而崩溃)。
目前,当我填写表格或尝试通过管理页面填写详细信息并单击“保存”时,我收到一个 ValueError
ValueError - "<BeamQuantity: B5>" needs to have a value for field "id" before this many-to-many relationship can be used.
我认为ManytoManyField需要保存然后计算需要运行。目前两者都试图同时发生,因此出现错误。请帮忙。
确切地说,您需要先创建 BeamQuantity 实例,然后再计算 bean 的长度。暂时将这些字段留空。
为此,我建议您让所有需要多对多关系的字段都有一个值,blank=True
和 null=True
。
所以,我会像这样重写保存方法:
def save(self, *args, **kwargs):
if self.id: # it means the object was already created, so has an id.
self.length = self.length_of_beam
self.total_quantity = self.total_concrete_quantity
super(BeamQuantity, self).save(*args, **kwargs)
然后当你想创建一个 BeanQuantity 时,执行:
bean_quantity = BeanQuantity.objects.create(**fields_you_want_here)
bean_quantity.save()
第二行将运行保存方法中的代码,因为现在对象有一个id。