Reputation: 35
My goal with the following code is to create an athlete object and override the save method to automatically set the category
for a given athlete based on the born_date
.
The Category
class will be inherited in other models too. The list within the class serves as validation purposes for the save method and the tuples for choice fields (used in other models).
Although everything seems right, I ran some test in the shell and the code is saving whatever born_date
is inputed. Why is that the case? Can someone shed some light on the problem? Thanks
from django.db import models
from datetime import datetime
class Category:
list_categories = [
'u12',
'u13',
'u14',
'u15',
'u16',
'u17',
'u18',
'u19',
'u20',
'u21',
]
CATEGORIES = [
('U12', 'u12'),
('U13', 'u13'),
('U14', 'u14'),
('U15', 'u15'),
('U17', 'u17'),
('U19', 'u19'),
('U21', 'u21'),
]
class Athlete(models.Model, Category):
name = models.CharField(max_length=120)
born_date = models.DateField()
category = models.CharField(max_length=3)
def save(self, *args, **kwargs):
year_now = datetime.date.today().year
year_born_obj = datetime.datetime.strptime(self.born_date, "%Y-%m-%d")
self.category = 'u{}'.format(year_now - year_born_obj.year)
if self.category in Category.list_categories:
try:
super(Athlete, self).save(*args, **kwargs)
except ValueError:
print('Category does not exist. Check born date')
def __str__(self):
return self.name
Here is the shell output:
>>> a1 = Athlete.objects.create(name='Foo', born_date='1990-02-05')
>>> a1.save()
>>> a1.category
'u30'
>>> a1.category in Category.list_categories
False
Upvotes: 0
Views: 1833
Reputation: 171
You can upgrade your source code based on the following way. I made some modifications to your code. Hope that will help you a lot.
from django.db import models
from datetime import datetime
class Athlete(models.Model):
categories = [
("U12", "u12"),
("U13", "u13"),
("U14", "u14"),
("U15", "u15"),
("U16", "u16"),
("U17", "u17"),
("U18", "u18"),
("U19", "u19"),
("U20", "u20"),
("U21", "u21"),
]
name = models.CharField(max_length=120)
born_date = models.DateField(default=None, null=True)
category = models.CharField(max_length=3, default=None, null=True)
def __str__(self):
return self.name
def save(self, *args, **kwargs):
try:
age = "u{age}".format(age=datetime.today().year - datetime.strptime(self.born_date, "%Y-%m-%d").year)
category = "".join(ct[0] for ct in self.categories if age == ct[1])
self.category = category if category != "" else None
except Exception as exp:
print("Exception: {exp}".format(exp=exp))
return super(Athlete, self).save(*args, **kwargs)
Upvotes: 1
Reputation: 438
Do not assign category value to the object if you do not want to save it, I made some changes to your code.
Try to do like this:
category = 'u{}'.format(year_now - year_born_obj.year)
if category in Category.list_categories:
self.category = category
else:
print('Category does not exist. Check born date')
super().save(*args, **kwargs)
Please ask if you do not understand anything or it's not working:)
Upvotes: 0