Django save()总是创建一个新对象

时间:2019-05-01 13:59:03

标签: django django-models django-admin

我的应用程序中有此模型,该模型旨在根据save()中添加的方法自动生成其主键。
但是,对于每个对象,我都希望对某些字段进行更新。现在,无论何时我在管理端进行更新(测试用例),它都会创建PK的新记录,而不是更新现有记录。关于如何解决这个问题有什么想法吗?

class DeploymentTask(models.Model):
    deployment_id = models.CharField(
        'Deployment Task ID', primary_key=True, max_length=25, editable=False)
    title = models.CharField(max_length=100)
    current_status = FSMField('Current Status',
                              default=STATES[0], choices=STATES)
    site_id = models.ForeignKey(
        Site, related_name='+', on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    refuel_record = models.ManyToManyField(RefuelRecord)

    def __str__(self):
        """String for representing the Model object."""
        return self.deployment_id

    class Meta:
        db_table = 'rm_deployment_task'
        verbose_name_plural = 'Deployment Tasks'

    def get_absolute_url(self):
        return reverse('deployment_id-view', args=[str(self.deployment_id)])

    def save(self):
        today = datetime.datetime.now()
        ticket_count = DeploymentTask.objects.filter(
            created_at__year=today.year, created_at__month=today.month).count() + 1
        new_task_id = 'DPT-' + str(str(datetime.date.today().year)) + str(
            datetime.date.today().month).zfill(2) + str(
            datetime.date.today().day).zfill(2) + '-' + str(ticket_count).zfill(6)
        self.deployment_id = new_task_id
        super(DeploymentTask, self).save()

enter image description here

2 个答案:

答案 0 :(得分:1)

  • 您总是在保存方法中将self.deployment_id设置为新值。
  • Django尝试执行UPDATE ... WHERE deployment_id = %,但尚无具有此ID的记录(至少如果您要在不同日期保存“旧”对象或具有不同的ticket_count)
  • 如果您要更新deployment_id以外的其他字段,则只需不设置self.deployment_id(如果已设置)。如果要更新deployment_id,则没有直接的方法,因为它用作主键(但是您可以记住旧的pk,并在save中创建新对象后删除该对象。 )

Django docs中了解更多信息。

答案 1 :(得分:0)

这是我更新的代码,对我有用...

def make_id():
    today = datetime.datetime.now()
    ticket_count = DeploymentTask.objects.filter(
                created_at__year=today.year, created_at__month=today.month).count() + 1
    new_task_id = 'DPT-' + str(str(datetime.date.today().year)) + str(
            datetime.date.today().month).zfill(2) + str(
            datetime.date.today().day).zfill(2) + '-' + str(ticket_count).zfill(6)  
    return new_task_id
class DeploymentTask(models.Model):
    deployment_id = models.CharField(
        'Deployment Task ID', primary_key=True, max_length=25, editable=False, default=make_id)
    title = models.CharField(max_length=100)
    current_status = FSMField('Current Status',
                              default=STATES[0], choices=STATES)
    site_id = models.ForeignKey(
        Site, related_name='+', on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    refuel_record = models.ManyToManyField(RefuelRecord)

    def __str__(self):
        """String for representing the Model object."""
        return self.deployment_id

    class Meta:
        db_table = 'rm_deployment_task'
        verbose_name_plural = 'Deployment Tasks'

    def get_absolute_url(self):
        return reverse('deployment_id-view', args=[str(self.deployment_id)])