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=Truenull=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。