首页 > 解决方案 > Django:我想根据以前的记录和序号创建一个自生成的代码

问题描述

我是一个编码新手,我正在用 Django 编写一个用于项目和任务管理的网站,我想根据以前的记录在“项目”模型中自动生成一个项目代码字段。

项目代码字段应如下所示:DDD-YY-SS,其中 DDD 是部门代码,YY 是 2 位年份编号,SS 是序列号。

我正在尝试将代码生成器包含在这样的自定义保存方法中:

class ProjectModel(models.Model):

    name = models.CharField(_("project name"), max_length=50)
    sponsor = models.CharField(_("sponsor"), max_length=50)
    manager = models.ForeignKey(StaffModel, verbose_name=_("project manager"), null=True, on_delete=models.SET_NULL, related_name='project_manager')
    lead = models.ForeignKey(StaffModel, verbose_name=_("technical lead"), null=True, on_delete=models.SET_NULL, related_name='tech_lead')
    projectdate = models.DateField(_("start date"), auto_now=False, auto_now_add=False)
    department = models.ForeignKey(DepartmentModel, verbose_name=_("department"), null=True, on_delete=models.SET_NULL)
    sites = models.ManyToManyField(OfficeModel, verbose_name=_("sites"))
    code = models.CharField(_("project code"), max_length=50, unique=True)
    partner = models.ForeignKey(CompanyModel, verbose_name=_("partner"), null=True, on_delete=models.SET_NULL)
    status = models.ForeignKey(ProjectStatusModel, verbose_name=_("status"), null=True, on_delete=models.SET_NULL)

    def save(self, *args, **kwargs):

        dpt = str(self.department.code)
        yy = str(self.projectdate.year)[-2:]
        filter_kw = '{}-{}-'.format(dpt, yy)
        lastrec = ProjectModel.objects.filter(code__startswith=filter_kw).last()

        if lastrec == None:
            lastrec = '00'
        else:
            lastrec = str(lastrec.code)[-2:]
 
        newnum = "{:02d}".format(int(lastrec)+1)
        self.code = '{}{}'.format(filter_kw, str(newnum))

        super(ProjectModel, self).save(*args, **kwargs)

但我认为这段代码......粗略?我觉得使用了太多的助剂,否则它就不起作用了。有没有更好的方法来做到这一点?我应该在模型中包含生成函数还是应该将其移动到模板中的视图或标记函数?

非常感谢。我的头现在是面条。

标签: pythondjango

解决方案


最后,我找到了一种方法,通过检查以前的记录并防止“项目代码”(或“序列号”)在修改记录数据时自行更新。

def save(self, *args, **kwargs):
    dpt = str(self.department.code) #'department' is ForeignKey, has a 'code' field consisting of a 2-3 letter code.
    yy = str(self.projectdate.year)[-2:] #gets the last 2 digits from the project start date year.
    filter_kw = '{}-{}-'.format(dpt, yy) #makes a database query to find any matching Dept-Year combination in the 'project code' field
    lastrec = ProjectModel.objects.filter(code__startswith=filter_kw).last() #get the last record that has the same combination.
    
    if not self.pk: #this keeps the following instructions from executing if there already is a project code, i.e.: when updating record information.

        if lastrec == None:
            lastrec = '00'
            newrec = int(lastrec)+1
        elif lastrec.code == self.code:
            lastrec = str(lastrec.code)[-2:]
            newrec = int(lastrec)
        else:
            lastrec = str(lastrec.code)[-2:]
            newrec = int(lastrec)+1
        
        newnum = "{:02d}".format(int(newrec)) #the record should be in Charfield format, 2-digits, non-unique just in case there is a number above 99 (very unlikely)
        self.code = '{}{}'.format(filter_kw, str(newnum))
    
    elif self.code == None:
        lastrec = '00'
        newrec = int(lastrec)+1
    
        newnum = "{:02d}".format(int(newrec))
        self.code = '{}{}'.format(filter_kw, str(newnum))
    else:
        pass

    super(ProjectModel, self).save(*args, **kwargs)

推荐阅读