[PYTHON] [Django] Erstellt ein Feld zur Eingabe von Daten mit 4-stelligen Zahlen

Mir wurde gesagt, dass ich 4 Ziffern eingeben wollte

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 ...

Warum das Datum numerisch eingeben?

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.

Problem

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.

Zuerst von der 8-stelligen Eingabe

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.

Geben Sie darauf basierend 4 Ziffern ein

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


Recommended Posts

[Django] Erstellt ein Feld zur Eingabe von Daten mit 4-stelligen Zahlen
Ich habe eine WEB-Bewerbung bei Django gemacht
Beachten Sie die Lösung, da Django nicht mit pip installiert werden konnte
Übergang zum Update-Bildschirm mit dem Django-Tag
Ich habe einen Befehl zum Markieren des Tabellenclips gegeben
Ich wollte nur die Daten des gewünschten Datums und der gewünschten Uhrzeit mit Django extrahieren
Ich habe einen Befehl gegeben, auf den Start von Django zu warten, bis die Datenbank bereit ist
Ich habe ein Paket erstellt, um Zeitreihen mit Python zu filtern
Ich habe einen Befehl zum Generieren eines Kommentars für eine Tabelle in Django eingegeben
Ich habe eine Funktion erstellt, um das Modell von DCGAN zu überprüfen
Ich kann mich mit Django 3 nicht auf der Admin-Seite anmelden
Ich habe eine Klasse erstellt, um das Analyseergebnis von MeCab in ndarray mit Python zu erhalten
Ich habe mit Python eine Lotterie gemacht.
Ich habe mit Python einen Daemon erstellt
Beim Schreiben in eine CSV-Datei mit Python habe ich einen kleinen Fehler gemacht und den Liefertermin nicht eingehalten
Ich habe versucht, ein Programm zu erstellen, um die Fehlersuche von Saiseriya zu lösen (Hinweis)
Ich habe eine Bibliothek erstellt, die Konfigurationsdateien mit Python einfach lesen kann
[Einführung in StyleGAN] Ich habe mit "The Life of a Man" ♬ gespielt
Ich habe versucht, mit Python eine Liste von Primzahlen zu erstellen
Ich wollte das ABC164 A ~ D-Problem mit Python lösen
Ich habe eine Entwicklungsumgebung für Django 3.0 mit Docker, Docker-Compose und Poetry erstellt
Ich habe den Befehl gegeben, einen farbenfrohen Kalender im Terminal anzuzeigen
Ich habe Jinja2 beim Lesen des Dokuments verglichen, um es mit Django zu verwenden
Ich habe ein Programm erstellt, das den Tierkreis mit tkinter automatisch berechnet
Erstellen Sie eine REST-API, um dynamodb mit dem Django REST Framework zu betreiben
Einfacher RSS-Reader mit Django
Ich habe mit Python einen Zeichenzähler erstellt
Ich habe ein Skript erstellt, um Piktogramme anzuzeigen
Ich habe mit Python eine Hex-Map erstellt
Ich habe ein Lebensspiel mit Numpy gemacht
Ich habe einen Hanko-Generator mit GAN gemacht
Ich habe mit Python ein schurkenhaftes Spiel gemacht
Ich habe mit Python einen einfachen Blackjack gemacht
Ich habe mit Python eine Einstellungsdatei erstellt
Ich habe mit Python einen Neuronensimulator erstellt
[Django 2.2] Fügen Sie neuen Posts mit einem Datum mithilfe eines Vorlagenfilters ein neues Abzeichen hinzu
Ich habe ein Tool zum automatischen Durchsuchen mehrerer Websites mit Selenium (Python) erstellt.
Ich habe versucht, ein Programm zu erstellen, das Hexadezimalzahlen mit Python in Dezimalzahlen konvertiert
Ich habe einen Küchentimer erstellt, der in der Statusleiste angezeigt wird!
Ich habe den JWT-Token-Generator mit Django Rest Auth auf SimpleJWT geändert.
Ich habe versucht, mit django eine E-Mail zum Abschluss der Registrierung von Google Mail zu senden.
Ich habe GAN mit Keras gemacht, also habe ich ein Video des Lernprozesses gemacht.
Ich habe eine Bibliothek konoha gemacht, die den Tokenizer auf ein schönes Gefühl umstellt
Ich habe ein Tool erstellt, um Jupyter py mit VS Code in ipynb zu konvertieren
Ich habe ein Programm erstellt, um die Größe einer Datei mit Python zu überprüfen
Ich habe einen Fehler beim Abrufen der Hierarchie mit MultiIndex von Pandas gemacht
Ich habe eine Funktion erstellt, um die Bewegung eines zweidimensionalen Arrays (Python) zu sehen.
Ich habe ein Tool erstellt, um die Ausführungszeit von cron zu schätzen (+ PyPI-Debüt)
Ich habe einen Stempelersatzbot mit Linie gemacht
Mathematik-Memorandum, um mit dem Feld Nr. 4 Schritt zu halten
Der einfachste Weg, um mit Django zu beginnen
Ich habe mit Python eine Bot-Wettervorhersage gemacht.
Ich möchte eine API erstellen, die ein Modell mit einer rekursiven Beziehung im Django REST Framework zurückgibt
Ich habe eine GUI-App mit Python + PyQt5 erstellt
Ich habe Sie dazu gebracht, das Ende der IP-Adresse mit L Chika auszudrücken
So entwickeln Sie eine Cart-App mit Django