Django Createsuperuser 如何知道如何解析我的日期字段

How Does Django Createsuperuser Know How To Parse My Date Field

我创建了一个自定义的用户模块,它添加了一些额外的字段:

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}"

当我 运行 createsuperuser 命令时,它要求我输入 birth_date(并且知道如何解析它)。我输入了 2020-01-01 作为值。

好奇,于是我临时把这些语句放在了createsuperuser函数中:

print("*****")
print(extra_fields)
print("*****")```

并得到:

{'first_name': 'super', 'last_name': 'user', 'birth_date': datetime.date(2020, 1, 1), 'phone': '12345', 'is_staff': True, 'is_superuser': True, 'is_active': True}

它是如何知道使用 datetime.date 以及如何正确解析它的?

更重要的是,如何为自定义相关对象做出类似的行为?

How did it know to use datetime.date and how to parse it correctly?

它知道这是一个日期,因为 birth_date 是一个 DateField() 对象。

关于格式,它使用DATE_INPUT_FORMAT setting [Django-doc]中定义的格式顺序。默认情况下,这些是:

[
    <b>'%Y-%m-%d'</b>, '%m/%d/%Y', '%m/%d/%y', # <b>'2006-10-25'</b>, '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'
]

所以这里第一个格式是匹配的。如果在解析时产生错误,它将移动到下一个,等等,直到其中一种格式接受输入,或者列表已用完,在这种情况下它将无法解析日期字符串。

您可以更改设置以使用您自己的格式,或更改顺序以使一种格式比另一种格式更受欢迎。这可能很重要,因为 2020-05-06 可以解析为 5 月 6 日或 6 月 5 日。因此,如果您在列表前面添加格式 %Y-%d-%m,它将被不同地解析。