ManytoManyField сохранять и вычислять
Недавно я начал самостоятельно изучать 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
Я хочу, чтобы моя модель принимала ManytoManyRelation из 2 выбранных фундаментов и затем вычисляла длину. Затем длина умножается на высоту и ширину, чтобы получить общее количество (Есть и другие расчеты, но я предполагаю, что все они просто сбиваются из-за того, что не получена длина).
В настоящее время, когда я заполняю форму или пытаюсь заполнить детали через страницу администратора и нажимаю кнопку Сохранить, я получаю ошибку ValueError
ValueError - "<BeamQuantity: B5>" должно иметь значение для поля "id" прежде чем можно будет использовать это отношение "многие-ко-многим".
Я думаю, что ManytoManyField нужно сохранить, а затем запустить вычисления. В настоящее время оба действия пытаются произойти одновременно, отсюда и ошибка. Пожалуйста, помогите.
Именно, вам нужно сначала создать экземпляр BeamQuantity, прежде чем вычислять длину бобов. Оставьте эти поля пустыми на секунду.
Для этого я рекомендую вам разрешить всем полям, которые требуют отношения "многие ко многим" иметь значение, с помощью 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()
Вторая строка выполнит код в методе save, потому что теперь у объекта есть id.