Any way to improve this python function?
def __number():
# This line returns the number of the latest created object
# as a "Factura" object in format "n/year"
last = Factura.objects.filter(f_type__exact=False).latest('number')
# We convert it into a string and split it to get only the first number
spl = str(last).split('/')[0]
# Convert it into integer so we can do math
n = int(spl)
# Get the current year
y = date.today().strftime('%y')
# If none return 1/year
if n == None:
return str(1) + '/' + str(y)
# Else we increment the number in one.
else:
n = n + 1
return str(n) + '/' + str(y)
What it does: It autogenerates a number in the format '1/year' '2/year' etc. If the user introduces other number, p.e. 564/10 the function fol开发者_如何学Golows it and the next will be 565/10.
Even if the user introduces p.e. 34/10 after the entry with 564/10 the function will follow the largest number.
Did I do this right or there's a better way to do it?
Update:
def __number():
current_year = date.today().strftime('%y')
try:
facturas_emmited = Factura.objects.filter(f_type__exact=False)
latest_object = facturas_emmited.latest('number').__str__()
first_number = int(latest_object.split("/")[0]) + 1
except Factura.DoesNotExist:
first_number = 1
return '%s/%s' % (first_number, current_year)
This is really just the beginning, but I'd start by replacing some comments with self-documenting code.
def __number():
# "Factura" object in format "n/year"
latest_object = Factura.objects.filter(f_type__exact=False).latest('number')
# Better name can be available if you explain why the first number is important and what it means
# Do Factura objects not have a __repr__ or __str__ method that you must cast it?
first_number = int(str(latest_object).split('/')[0])
current_year = date.today().strftime('%y')
# Use "is None" rather than "== None"
if first_number is None:
return '1/%d' % current_year
# No else needed because of return above
# Why do we add 1 to first number? Comments should explain _why_, not how
return '%d/%d' % (first_number + 1, current_year)
Can last
be None
? If so it would be good to check for that:
# get last as before
if last:
n = int(str(last).split("/")[0]) + 1
else:
n = 1
# get y as before
return str(n) + "/" + str(y)
Another improvement here is that you only build the result string in one place.
I don't know what the Factura object is, but can you not get the value of n
by calling some method on it? This would be better than converting it to a string, splitting it and taking the last part.
I solved similar problem some time ago by using object.id/year (where object/id is database id).
It guarantees that this will be unique, autoincremented (you don't need to do n = n + 1
, which theoretically can lead to duplicate values in a db).
You can do this by overriding save
method and only trick is that you need first to save an object (id is assigned) and then create id/year number and save again (maybe there is better way to do this than double save).
def save(self, force_insert = False, force_update = False):
super(Factura, self).save(force_insert, force_update)
current_year = date.today().strftime('%y')
self.identifier = '%s/%s'%(self.id, current_year)
super(Factura, self).save(force_insert, force_update)
精彩评论