Issue
I'm a coding noob and I'm writing a website in Django for Project and task management, and I want to generate a project code field in a 'Project' model automatically based on previous records.
The project code field should look like this: DDD-YY-SS, where DDD is department code, YY is 2-digit year number and SS the sequence number.
I'm trying to include the code generator in a custom save method like this:
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)
But I think this code is... sketchy? I feel like using too many auxiliaries or it just won't work. Is there a better way of doing this? Should I include the generating function in the model or should I move this to the View or tag functions in the templates?
Thanks a lot. My head is a noodle now.
Solution
Finally I found a way of doing this by checking previous records and also preventing the "Project Code" (or "serial number") to update itself when modifying record data.
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)
Answered By - Victor Donoso
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.