I created a customized User module that adds a few extra fields:
class User(AbstractUser):
"""User modle for staff, clients and customers"""
username = None # remove username from the model
email = models.EmailField("email address", unique=True)
# """Email of user this will be used for login"""
address = models.OneToOneField(Address, on_delete = models.PROTECT, null=True, blank=True)
""":class:`Postal Address` associated with the User"""
birth_date = models.DateField()
"""Date of birth of User"""
phone = models.CharField(max_length=15)
"""Phone number of User"""
org = models.ForeignKey(Organization, on_delete=models.PROTECT, null=True, blank=True)
""":class:`Organization` User is associated with"""
# changes for using email instead of username
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name', 'birth_date', 'phone']
objects = UserManager()
def __str__(self):
return F"{self.email} {self.first_name} {self.last_name}"
When I ran the createsuperuser
command it asked me for birth_date (and knew how to parse it). I entered 2020-01-01 for the value.
Curious, I then temporarily put these statements in the createsuperuser
function:
print("*****")
print(extra_fields)
print("*****")```
and got:
{'first_name': 'super', 'last_name': 'user', 'birth_date': datetime.date(2020, 1, 1), 'phone': '12345', 'is_staff': True, 'is_superuser': True, 'is_active': True}
How did it know to use datetime.date
and how to parse it correctly?
More importantly, how can I make similar behavior for a custom related object?
How did it know to use datetime.date and how to parse it correctly?
It knows that it is a date because the birth_date
is a DateField()
object.
As for the format, it uses the formats in order that are defined in the DATE_INPUT_FORMAT
setting [Django-doc]. By default these are:
[ '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06' '%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006' '%d %b %Y', '%d %b, %Y', # '25 Oct 2006', '25 Oct, 2006' '%B %d %Y', '%B %d, %Y', # 'October 25 2006', 'October 25, 2006' '%d %B %Y', '%d %B, %Y', # '25 October 2006', '25 October, 2006' ]
So here the first format is a match. If that produces an error when parsing, it moves to the next one, etc. until either one of the formats accepts the input, or the list is exhausted, in which case it will not be able to parse the date string.
You can alter the setting to use your own formats, or change the order to make a format more preferred over the other one. This can be important since 2020-05-06
can be parsed as May 6, or June 5. So if you add a format %Y-%d-%m
in front of the list, it will be parsed differently.