[Django] a créé un champ pour saisir des dates avec des nombres à 4 chiffres

On m'a dit que je voulais entrer 4 chiffres

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

Pourquoi saisir la date numériquement

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.

problème

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.

Premier à partir d'une entrée à 8 chiffres

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.

Sur cette base, entrez 4 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


Recommended Posts

[Django] a créé un champ pour saisir des dates avec des nombres à 4 chiffres
J'ai fait une application WEB avec Django
Notez la solution car django n'a pas pu s'installer avec pip
Transition vers l'écran de mise à jour avec le Django a tag
J'ai fait une commande pour marquer le clip de la table
Je voulais juste extraire les données de la date et de l'heure souhaitées avec Django
J'ai fait une commande pour attendre que Django démarre jusqu'à ce que la base de données soit prête
J'ai créé un package pour filtrer les séries chronologiques avec python
J'ai fait une commande pour générer un commentaire pour une table dans Django
J'ai fait une fonction pour vérifier le modèle de DCGAN
Je n'arrive pas à me connecter à la page d'administration avec Django 3
J'ai créé une classe pour obtenir le résultat de l'analyse par MeCab dans ndarray avec python
J'ai fait une loterie avec Python.
J'ai créé un démon avec Python
Lors de l'écriture dans un fichier csv avec python, une histoire que j'ai fait une légère erreur et n'a pas respecté la date de livraison
J'ai essayé de faire un programme pour résoudre (indice) la recherche d'erreur de Saiseriya
J'ai créé une bibliothèque qui lit facilement les fichiers de configuration avec Python
[Introduction à StyleGAN] J'ai joué avec "The Life of a Man" ♬
J'ai essayé de créer une liste de nombres premiers avec python
Je voulais résoudre le problème ABC164 A ~ D avec Python
J'ai créé un environnement de développement pour Django 3.0 avec Docker, Docker-compose, Poetry
J'ai fait une commande pour afficher un calendrier coloré dans le terminal
J'ai comparé Jinja2 en lisant le document pour l'utiliser avec Django
J'ai fait un programme qui calcule automatiquement le zodiaque avec tkinter
Créer une API REST pour faire fonctionner dynamodb avec le Framework Django REST
Lecteur RSS simple réalisé avec Django
J'ai fait un compteur de caractères avec Python
J'ai fait un script pour afficher des pictogrammes
J'ai fait une carte hexadécimale avec Python
J'ai fait un jeu de vie avec Numpy
J'ai fait un générateur Hanko avec GAN
J'ai fait un jeu rogue-like avec Python
J'ai fait un simple blackjack avec Python
J'ai créé un fichier de configuration avec Python
J'ai fait un simulateur de neurones avec Python
[Django 2.2] Ajouter un nouveau badge aux nouveaux messages avec une date à l'aide d'un filtre de modèle
J'ai créé un outil pour parcourir automatiquement plusieurs sites avec Selenium (Python)
J'ai essayé de créer un programme qui convertit les nombres hexadécimaux en nombres décimaux avec python
J'ai fait une minuterie de cuisine à afficher sur la barre d'état!
J'ai changé le générateur de jetons jwt en simplejwt avec Django Rest Auth.
J'ai essayé d'envoyer un e-mail de fin d'inscription depuis Gmail avec django.
J'ai fait GAN avec Keras, donc j'ai fait une vidéo du processus d'apprentissage.
J'ai créé un konoha de bibliothèque qui fait passer le tokenizer à une belle sensation
J'ai créé un outil pour convertir Jupyter py en ipynb avec VS Code
J'ai fait un programme pour vérifier la taille d'un fichier avec Python
J'ai fait une erreur en récupérant la hiérarchie avec MultiIndex of pandas
J'ai créé une fonction pour voir le mouvement d'un tableau à deux dimensions (Python)
J'ai fait un outil pour estimer le temps d'exécution de cron (+ débuts de PyPI)
J'ai fait un robot de remplacement de tampon avec une ligne
Mémorandum de mathématiques pour suivre le domaine # 4
Le moyen le plus simple de démarrer avec Django
J'ai fait une prévision météo de type bot avec Python.
Je souhaite créer une API qui retourne un modèle avec une relation récursive dans Django REST Framework
J'ai créé une application graphique avec Python + PyQt5
Je t'ai fait exprimer la fin de l'adresse IP avec L Chika
Comment développer une application de panier avec Django