Django在delete()之后安排模型外键属性

时间:2017-12-07 02:01:24

标签: python django views models

我有一个这样的模型:

class RepairOrder(models.Model):
user = models.ForeignKey(User)
ro_number = models.IntegerField(validators=[MaxValueValidator(999999999999)])
service_writer = models.ForeignKey(ServiceWriter, null=True, blank=True)
RO_STATUS_CHOICES = (
    ('P', 'Pending'),
    ('O', 'Open'),
    ('C', 'Closed')
)
ro_status = models.CharField(max_length=10, blank=False, choices=RO_STATUS_CHOICES)
open_date = models.DateTimeField()
closed_date = models.DateTimeField(null=True, blank=True)
mileage = models.IntegerField(blank=False, validators=[MaxValueValidator(999999999999)])
line_number_1 = models.ForeignKey(JobLine, null=True, blank=True, on_delete=models.SET_NULL,
                                  related_name='line_number_1')
line_number_2 = models.ForeignKey(JobLine, null=True, blank=True, on_delete=models.SET_NULL,
                                  related_name='line_number_2')
line_number_3 = models.ForeignKey(JobLine, null=True, blank=True, on_delete=models.SET_NULL,
                                  related_name='line_number_3')
line_number_4 = models.ForeignKey(JobLine, null=True, blank=True, on_delete=models.SET_NULL
                                  , related_name='line_number_4')
line_number_5 = models.ForeignKey(JobLine, null=True, blank=True, on_delete=models.SET_NULL,
                                  related_name='line_number_5')
line_number_6 = models.ForeignKey(JobLine, null=True, blank=True, on_delete=models.SET_NULL,
                                  related_name='line_number_6')
line_number_7 = models.ForeignKey(JobLine, null=True, blank=True, on_delete=models.SET_NULL,
                                  related_name='line_number_7')
line_number_8 = models.ForeignKey(JobLine, null=True, blank=True, on_delete=models.SET_NULL,
                                  related_name='line_number_8')
line_number_9 = models.ForeignKey(JobLine, null=True, blank=True, on_delete=models.SET_NULL,
                                  related_name='line_number_9')
line_number_10 = models.ForeignKey(JobLine, null=True, blank=True, on_delete=models.SET_NULL,
                                   related_name='line_number_10')
vehicle = models.ForeignKey(Vehicle, blank=False, related_name='vehicle')

def __str__(self):
    return str(self.ro_number)

其中一些对象可能有

line_number_(1 through 5)

分配给JobLine对象,其余设置为Null。 其他RepairOrder对象可能只有

line_number_(1 through 3)

分配给JobLine对象,而其余对象设置为Null。但是在创建RepairOrder对象期间

line_number_(x)

属性总是从1开始按升序分配。

这是我想要完成的事情: 让我们假设我有一个具有

的RepairOrder
line_number_(1 through 5)

分配给JobLine对象,其余分配为Null值。我希望能够删除分配给

的JobLine对象
line_number_3

RepairOrder对象的属性,并重新安排剩余的填充属性以填充

line_number_(1-4)

RepairOrder对象的属性。

这是我到目前为止所尝试的内容:

views.py
def advanced_delete_line(request, pk, jl):
user = request.user

if request.method == "POST":
    raise PermissionDenied
else:
    # Get RepairOrder object with pk passed in from url
    ro_obj = RepairOrder.objects.get(pk=pk, user=user)  
    # Get attribute object of 'line_number_(jl passed in from url)
    ro_line = getattr(ro_obj, "line_number_" + str(jl))  
    # Delete this object
    ro_line.delete()
    # Get the object assigned to the next numerically higher attribute or RepairOrder object
    x = int(jl) + 1
    for i in range(10-int(jl)):  # Only loop as many times is needed
        # Get the object assigned to the next numerically higher attribute or RepairOrder object
        line = getattr(ro_obj, "line_number_" + str(x))
        y = x - 1
        # Assign the previously retrieved object to the next lower job_line_attribute
        line_2 = setattr(ro_obj, "line_number_" + str(y), line)
        if line is None:
            pass
        else:
            line_2.save()
        # Do it all over again but starting at the next numerically higher attribute
        x += 1

    return HttpResponseRedirect('/advanced/repair-order/' + str(pk) + "/")

我对这种方法几乎没有运气。任何人都可以为我提供更好的方法吗?

2 个答案:

答案 0 :(得分:0)

我认为你需要在第一次将它设置为None后保存line_2。看看for循环中的这种变化是否有帮助:

for i in range(10-int(jl)):  # Only loop as many times is needed
    # Get the object assigned to the next numerically higher attribute or RepairOrder object
    line = getattr(ro_obj, "line_number_" + str(x))
    y = x - 1
    # Assign the previously retrieved object to the next lower job_line_attribute
    line_2 = setattr(ro_obj, "line_number_" + str(y), line)
    line_2.save()
    if line is None:
        break
    else:
        # Do it all over again but starting at the next numerically higher attribute
        x += 1

return HttpResponseRedirect('/advanced/repair-order/' + str(pk) + "/")

答案 1 :(得分:0)

我能够弄清楚我的逻辑有些问题。我将setattr()函数分配给一个变量,当它没有像那样工作时。您需要使用settattr()函数,如下所示:

replacement_value = "value"
setattr(object, "attribute_name", replacement_value)
object.save()