C'est une application de travail qui gère la date de réservation de Django que j'ai faite il y a longtemps. Python est un système 2 car c'est un ancien. Django est également ancien et 1.6.
Il était compatible avec une entrée à 8 chiffres, mais ...
Comme un sélecteur de dates C'est cool en termes d'interface utilisateur de saisir la date en cliquant avec la souris, C'est facile à comprendre pour les utilisateurs, C'est assez gênant si vous devez entrer en continu. C'est la même chose que tout le monde aime les éditeurs qui n'ont pas besoin d'utiliser une souris.
Le champ DateField par défaut est l'argument mot-clé input_fields La saisie de texte est possible en spécifiant "% Y-% m-% d", "% Y /% m /% d", etc. La saisie de tirets et de barres obliques est assez gênante. Si possible, je veux le compléter avec seulement les chiffres sur les dix touches. (Si vous appuyez sur Entrée pour déplacer les onglets) Cependant, si vous spécifiez "% Y% m% d", il n'y a pas de problème lorsque vous entrez 8 chiffres, S'il n'y a pas assez de chiffres, combien représente l'année, combien coûte le mois et combien coûte le jour Le comportement réel sera déroutant pour l'utilisateur.
Si vous spécifiez "% m% d", l'année est fixée à 1900. Et, comme avec "% Y% m% d", le problème de la frontière entre les dates demeure.
Pour le résoudre, vous devez modifier l'interprétation de la valeur d'entrée de Field. En fait, vous pouvez remplacer la fonction to_python de DateField.
Pour le moment, après avoir confirmé qu'il s'agit d'un numéro à 8 chiffres
def to_python(self, value):
#réduction
#Écrivez le code ailleurs à la fin
year_month_day = value[:4], value[4:6] , value[6:]
result = date(*map(int, year_month_day))
return result
Tout comme une date à 4 chiffres, 2 chiffres et 2 chiffres.
Tout d'abord, résolvez le problème de limite en réduisant à seulement 4 chiffres.
S'il s'agit de 4 chiffres, il n'y a qu'une date, donc à peu près L'année dernière, cette année, l'année prochaine Il existe trois modèles possibles.
Comment décider est important
N'est-ce pas suffisant pour le moment s'il est mis en œuvre? Si vous gérez la date de réservation, vous utiliserez la date future la plus proche.
C'est pourquoi l'argument mot-clé détermine le sélecteur de date lors de l'initialisation. Imagewise
DateField("Jour futur", selecter="nearest_fortune")
DateField("Jour passé", selecter="nearest_past")
DateField("Bientôt", selecter="nearest")
Cela ressemble à ce qui précède.
En résumé, le code est le suivant.
class DateField(forms.DateField):
def __init__(self, *args, **kwargs):
#Le nom du sélecteur doit être large dans une certaine mesure
nearest = ["nearest_selecter", "nearest"]
fortune = ["nearest_fortune_selecter",
"nearest_fortune",
"fortune"]
past = ["nearest_past_selecter",
"nearest_past",
"past"]
#Si tu ne le fais pas, c'est super classe__init__Mettez-vous en colère contre des "arguments non définis" lors de l'appel
selecter_name = kwargs.pop("selecter", None)
#Changer la méthode de sélection de l'année avec le mot-clé de sélection
if selecter_name in nearest:
self.selecter = self.nearest_selecter
if selecter_name in past:
self.selecter = self.nearest_past_selecter
if selecter_name in fortune:
self.selecter = self.nearest_fortune_selecter
else:
self.selecter = self.nearest_selecter
forms.DateField.__init__(self, *args, **kwargs)
#Celui qui sélectionne le jour passé proche
def nearest_past_selecter(self, days):
today = date.today()
get_days = lambda d: abs((today - d).days)
nearest = min(filter(lambda d: d <= today, days), key=get_days)
return nearest
#Celui qui choisit le futur proche
def nearest_fortune_selecter(self, days):
today = date.today()
get_days = lambda d: abs((today - d).days)
nearest = min(filter(lambda d: d >= today, days), key=get_days)
return nearest
#Celui qui choisit le jour proche
def nearest_selecter(self, days):
today = date.today()
get_days = lambda d: abs((today - d).days)
nearest = min(days, key=get_days)
return nearest
@override
def to_python(self, value):
value = value.strip()
#Pour 4 chiffres
if len(value) == 4 and value.isdigit():
month, day = int(value[:2]), int(value[2:4])
today = date.today()
prev_year = date(today.year - 1, month, day)
this_year = date(today.year , month, day)
next_year = date(today.year + 1, month, day)
days = [prev_year, this_year, next_year]
return self.selecter(days)
#Pour 8 chiffres
elif len(value) == 8 and value.isdigit():
year_month_day = value[:4], value[4:6] , value[6:]
result = date(*map(int, year_month_day))
if result.year < 2000 or result.year > 2100:
message = u'Entrez l'année entre 2001 et 2099.'
self.error_messages['invalid'] = message
raise ValidationError
else:
result = forms.DateField.to_python(self, value)
return result