[PYTHON] Comment filtrer les clés externes qui peuvent être sélectionnées sur l'écran d'administration de Django

Cet article est le troisième jour du Calendrier de l'Avent Django 2019. (Calendrier de l'Avent) est le premier article.

introduction

Je suis un non-ingénieur qui crée personnellement des applications avec Django depuis environ un mois. Lorsque j'ai utilisé une clé externe dans cette application, lorsque j'ai ouvert le menu déroulant, plus de 100 éléments étaient affichés, donc Je me suis demandé si je pouvais le presser d'une manière ou d'une autre.

Pour conclure d'abord, vous pouvez utiliser limit_choices_to pour filtrer les enregistrements affichés par des clés externes. Créons en fait une application et essayons-la pour voir comment l'utiliser.

L'application que j'ai créée pour cet article

J'ai créé une application simple pour l'explication. Seulement modèle. Soit dit en passant, le thème est une application qui enregistre la prédiction de l'équipe à laquelle les joueurs qui ont acquis la FA en 2019 iront. C'est presque décidé, donc ce n'est pas pratique! https://github.com/shimayu22/fa_expects_app/

Dans le tableau FaExpects, le tableau Players est défini comme une clé externe afin que les joueurs enregistrés puissent le sélectionner dans le menu déroulant. Les données des joueurs sont également disponibles, vous pouvez donc les essayer simplement en les lisant. Veuillez consulter README pour savoir comment l'utiliser.

des choses comme ça

https://github.com/shimayu22/fa_expects_app/tree/part1

スクリーンショット 2019-11-23 23.01.18.png

Est-il possible de filtrer sur l'écran de gestion?

Utilisez limit_choices_to

Depuis ForeignKey.limit_choices_to dans la documentation Django

Définissez une limite sur les choix disponibles dans ce champ lorsque ce champ est rendu à l'aide de ModelForm ou d'admin (par défaut, tous les objets de l'ensemble de requêtes peuvent être sélectionnés). Vous pouvez utiliser un dictionnaire, un objet Q ou un objet appelable qui renvoie un dictionnaire ou un objet Q. (Google Traduction)

Vous pouvez donc utiliser limit_choices_to pour filtrer les éléments sélectionnables.

Je l'ai vraiment essayé

https://github.com/shimayu22/fa_expects_app/tree/part2

Ajout de limit_choices_to à player_id de FaExpects.

models.py


    player_id = models.ForeignKey(
        Players,
        on_delete=models.CASCADE,
        verbose_name="joueur",
        limit_choices_to={"position":1,}
    )

Cette fois, seule la position "1" (lanceur) peut être sélectionnée. avec ça, http://127.0.0.1:8000/admin/fa_expects/faexpects/add/ Lorsque vous ouvrez le menu déroulant "Lecteur",

スクリーンショット 2019-11-24 22.52.48.png

Seuls les joueurs inscrits comme lanceurs étaient affichés!

Utilisez des mots-clés de recherche

Dans l'exemple ci-dessus, vous pouvez affiner par égalité telle que position == 1, mais en utilisant le mot clé de recherche, vous pouvez affiner en utilisant les éléments ci-dessus et suivants.

models.py


    player_id = models.ForeignKey(
        Players,
        on_delete=models.CASCADE,
        verbose_name="joueur",
        limit_choices_to={"position": 1,
                          "age__lt": 33}
    )

Ce qui précède stipule «position == 1 et âge <33» (lanceur et moins de 33 ans). Si vous ajoutez __lt (deux traits de soulignement) au nom de l'élément ʻage`, la condition" moins de "sera ajoutée.

スクリーンショット 2019-11-24 23.01.15.png

Il y a moins de joueurs à choisir! Les articles suivants sont très bien organisés pour les autres mots-clés.

Référence: [Summary of Django database operations #List of search keywords](https://qiita.com/okoppe8/items/66a8747cf179a538355b#%E6%A4%9C%E7%B4%A2%E3%82%AD%E3 % 83% BC% E3% 83% AF% E3% 83% BC% E3% 83% 89% E3% 81% AE% E4% B8% 80% E8% A6% A7)

Utiliser l'objet Q

Jusqu'à présent, les conditions de recherche étaient spécifiées dans le type de dictionnaire, mais elles peuvent également être spécifiées dans l'objet Q.

models.py


from django.db.models import Q

~~~réduction~~~
    player_id = models.ForeignKey(
        Players,
        on_delete=models.CASCADE,
        verbose_name="joueur",
        limit_choices_to=Q(position=4) | Q(position=7),
    )

Pour les objets Q, vous pouvez spécifier des conditions OR comme celle-ci. Dans ce qui précède, cela signifie "la position est la deuxième base ou le voltigeur".

スクリーンショット 2019-11-24 23.37.01.png

Je n'ai pu afficher que le joueur de deuxième but ou le voltigeur avec brio!

Créer un dictionnaire pour limit_choices_to

https://github.com/shimayu22/fa_expects_app/tree/part3

Puisqu'il n'est pas flexible s'il s'agit d'une écriture solide, je vais créer un type de dictionnaire avec une fonction et le transmettre. Cette fois, afin de le faire rapidement, j'ai fait un tableau pour spécifier les conditions. J'ajoute la classe RequestedConditions à Models.py. (Parce qu'il est long, veuillez vérifier Models.py)

Ensuite, j'ai créé une fonction pour créer un dictionnaire pour limit_choices_to à partir du dernier enregistrement de la table RequestedConditions.

Models.py


~~~ abrégé ~~~

def set_players_condition():
    condition =  RequestedConditions.objects.latest('pk')
    condition_dict = {}
    if condition.age > 0:
        condition_dict["age__lt"] = condition.age
    
    if condition.position > 0:
        condition_dict["position"] = condition.position
    
    if condition.dominant_hand > 0:
        condition_dict["dominant_hand"] = condition.dominant_hand

    return condition_dict

~~~ abrégé ~~~

Premier, http://127.0.0.1:8000/admin/fa_expects/requestedconditions/add/ Réglez «âge», «position» et «main dominante» et sauvegardez. (Si vous ne définissez pas tout, tout sera affiché)

スクリーンショット 2019-11-26 23.31.31.png

Après inscription http://127.0.0.1:8000/admin/fa_expects/faexpects/add/ Si vous regardez les joueurs dans, seuls les joueurs qui remplissent les conditions seront affichés.

スクリーンショット 2019-11-26 23.31.57.png

Je l'ai fait.

en conclusion

Si vous voulez juste faire quelque chose avec le modèle, vous pouvez le faire comme ceci. Il semble que vous puissiez le rendre plus flexible en combinant des objets Q. Jouez avec et essayez-le.

prime

Cela peut être naturel si vous pensez calmement, limit_choices_to={"age__lt":RequestedConditions.objects.latest('pk').age} Si vous écrivez quelque chose comme ceci, vous obtiendrez une erreur disant "Il n'y a pas de telle table" lors de la première migration. Sora (quand j'essaye de me référer à une table qui n'a pas encore été créée) Oui (j'obtiens une erreur) (N'est-ce pas naturel?).

Supplément moins pertinent

  1. Pas les joueurs qui ont déclaré FA, mais les joueurs qui ont obtenu le bon FA (je suis désolé s'il y a une erreur)
  2. Suzuki Daichi (b) est trop protégée, j'ai donc décidé de la protéger le plus en 2019 (1).
  3. Je suis un petit jambon
  4. J'ai hâte à la saison prochaine!

référence

Résumé des opérations de la base de données Django

De plus, les articles suivants ont été utiles pour Django en général. Je vous remercie! [Python] Didacticiel Django - Créer une application Web professionnelle à usage général le plus rapide [Django] Modèle de configuration de champ de modèle

Recommended Posts

Comment filtrer les clés externes qui peuvent être sélectionnées sur l'écran d'administration de Django
Comment enregistrer une seule donnée sur l'écran de gestion de Django
Comment définir des variables pouvant être utilisées dans toute l'application Django ~ Utile pour les modèles, etc. ~
L'histoire de l'échec de la mise à jour de "calendar.day_abbr" sur l'écran d'administration de django
Comment ajouter un traitement de pré-sauvegarde lors de l'ajout d'un objet sur le site d'administration de Django
[Django] À propos des utilisateurs pouvant être utilisés sur un modèle
Comment résoudre le problème que le contenu vidéo ne peut pas être lu sur Firefox pour Linux
Module standard Python utilisable en ligne de commande
Les filtres Kalman peuvent-ils être utilisés pour prédire les tendances boursières?
Masquer l'avertissement selon lequel zsh peut être utilisé par défaut sur Mac
Comment créer un bot Janken qui peut être facilement déplacé (commentaire)
TLE semblait effrayant en fonction de la manière dont l'entrée était reçue
Comment vérifier la version de Django
Comment résoudre le problème que seul le processus reste lorsque vous appuyez sur X sur l'écran imshow d'OpenCV
Comment installer la bibliothèque Python qui peut être utilisée par les sociétés pharmaceutiques
Comment imprimer des messages de débogage sur la console Django
Implémentez la fonction de saisie semi-automatique sur l'écran d'administration de Django
Personnalisez la page modèle de l'écran d'administration de Django
Remarques sur l'utilisation de StatsModels qui peuvent utiliser la régression linéaire et GLM en python
Comment créer une propriété de relations qui peuvent être prefetch_related par des conditions spécifiques
Comment résoudre le problème que l'écran de connexion ne s'affiche pas pour toujours sur Ubuntu 19.04 car il s'arrête au logo au démarrage
Statistiques simples qui peuvent être utilisées pour analyser l'effet des mesures sur les sites EC et les codes qui peuvent être utilisés dans le notebook jupyter
Réfléchissez à la programmation de Python sur votre iPad
Comment déployer une application Django dans le cloud Alibaba
Comment résoudre la fonction récursive qui a résolu abc115-D
Comment créer un environnement Django (python) sur Docker
Comment utiliser Django avec Google App Engine / Python
Transition vers l'écran de mise à jour avec le Django a tag
Comment profiter de Python sur Android !! Programmation en déplacement !!
Comment exécuter Django sur IIS sur un serveur Windows
Qiita peut maintenant être visualisé sur la console (shell)
Cours de Deep Learning pouvant être écrasé sur place
[Django] Comment rediriger les utilisateurs non connectés vers la page de connexion
Lister les classes qui peuvent être référencées par ObjCClass
Comment gérer le phénomène que Python (notebook Jupyter) exécuté sur WSL devient abandonné
Comment gérer le problème de l'échec de la construction de pandas 1.1.0 ou version ultérieure sur Alpine Linux
Comment configurer un serveur SMTP simple qui peut être testé localement en Python
[Django] Noms de champs pouvant être utilisés pour le modèle utilisateur, l'enregistrement des utilisateurs et les méthodes de connexion
Comment afficher le texte et le texte de survol qui peuvent être exécutés en cliquant avec le plug-in Minecraft
Comment gérer l'erreur selon laquelle le conteneur MySQL de Docker ne démarre pas sur Docker Toolbox
Comment supprimer "(base)" qui apparaît dans le terminal lorsqu'Anaconda est installé sur Mac
[Python] Un programme pour trouver le nombre de pommes et d'oranges qui peuvent être récoltées