Es ist eine Arbeitsanwendung, die das Reservierungsdatum von Django verwaltet, das ich vor langer Zeit erstellt habe. Python ist ein 2-System, weil es ein altes ist. Django ist auch alt und 1.6.
Es war kompatibel mit 8-stelligen Eingaben, aber ...
Wie ein Date Picker In Bezug auf die Benutzeroberfläche ist es cool, das Datum per Mausklick einzugeben. Es ist für Benutzer leicht zu verstehen, Es ist ziemlich mühsam, wenn Sie kontinuierlich eingeben müssen. Es ist das gleiche, wie jeder Redakteur liebt, der keine Maus benutzen muss.
Das Standard-DateField ist das Schlüsselwortargument input_fields Die Texteingabe ist durch Angabe von "% Y-% m-% d", "% Y /% m /% d" usw. möglich. Das Eingeben von Bindestrichen und Schrägstrichen ist ziemlich mühsam. Wenn möglich, möchte ich es nur mit den Zahlen auf den zehn Schlüsseln vervollständigen. (Wenn Sie die Eingabetaste drücken, um Registerkarten zu verschieben) Wenn Sie jedoch "% Y% m% d" angeben, gibt es kein Problem, wenn Sie 8 Ziffern eingeben. Wenn nicht genügend Ziffern vorhanden sind, wie viel ist das Jahr, wie viel ist der Monat und wie viel ist der Tag Das tatsächliche Verhalten wird den Benutzer verwirren.
Wenn Sie "% m% d" angeben, ist das Jahr auf 1900 festgelegt. Und wie bei "% Y% m% d" bleibt das Problem der Grenze zwischen Daten bestehen.
Um dies zu lösen, müssen Sie die Interpretation des Eingabewerts von Field ändern. Tatsächlich ist es in Ordnung, wenn Sie die Funktion to_python von DateField überschreiben.
Vorerst nach Bestätigung, dass es sich um eine 8-stellige Nummer handelt
def to_python(self, value):
#Kürzung
#Schreiben Sie den Code am Ende an eine andere Stelle
year_month_day = value[:4], value[4:6] , value[6:]
result = date(*map(int, year_month_day))
return result
Genau wie ein 4-stelliges, 2-stelliges, 2-stelliges Datum.
Beseitigen Sie zunächst das Grenzproblem, indem Sie es auf nur vierstellige Zahlen eingrenzen.
Wenn es 4 Ziffern sind, gibt es nur ein Datum, also ungefähr Letztes Jahr, dieses Jahr, nächstes Jahr Es gibt drei mögliche Muster.
Wie man sich entscheidet, ist wichtig
Reicht es vorerst nicht aus, wenn es implementiert wird? Wenn Sie das Reservierungsdatum verwalten, verwenden Sie das nächste zukünftige Datum.
Aus diesem Grund bestimmt das Schlüsselwortargument die Datumsauswahl bei der Initialisierung. Stellen Sie sich vor
DateField("Zukünftiger Tag", selecter="nearest_fortune")
DateField("Vergangener Tag", selecter="nearest_past")
DateField("Demnächst", selecter="nearest")
Es sieht aus wie oben.
Zusammenfassend lautet der Code wie folgt.
class DateField(forms.DateField):
def __init__(self, *args, **kwargs):
#Der Name des Selektors sollte bis zu einem gewissen Grad breit sein
nearest = ["nearest_selecter", "nearest"]
fortune = ["nearest_fortune_selecter",
"nearest_fortune",
"fortune"]
past = ["nearest_past_selecter",
"nearest_past",
"past"]
#Wenn Sie es nicht knallen, ist es super Klasse__init__Ärgern Sie sich beim Aufruf über "undefinierte Argumente"
selecter_name = kwargs.pop("selecter", None)
#Ändern Sie die Jahresauswahlmethode mit dem Schlüsselwort selecter
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)
#Derjenige, der den nahen vergangenen Tag auswählt
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
#Derjenige, der den Tag der nahen Zukunft wählt
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
#Derjenige, der den nahen Tag wählt
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()
#Für 4 Ziffern
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)
#Für 8 Ziffern
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'Geben Sie das Jahr zwischen 2001 und 2099 ein.'
self.error_messages['invalid'] = message
raise ValidationError
else:
result = forms.DateField.to_python(self, value)
return result