182 votes

À l’aide de widgets de date/heure de Django dans formulaire personnalisé

Comment puis-je utiliser la chouette JavaScript date et l'heure de widgets que l'admin par défaut utilise avec mon affichage personnalisé?

J'ai regardé à travers le Django formes de documentation, et il mentionne brièvement django.contrib.admin.les widgets, mais je ne sais pas comment l'utiliser?

Voici mon modèle que je veux c'appliquée.

<form action="." method="POST">
    <table>
        {% for f in form %}
           <tr> <td> {{ f.name }}</td> <td>{{ f }}</td> </tr>
        {% endfor %}
    </table>
    <input type="submit" name="submit" value="Add Product">
</form>

Aussi, je pense qu'il devrait être noté que je n'ai pas vraiment écrit une vue moi-même pour cette forme, je suis en utilisant une vue générique. Voici l'entrée de la url.py:

(r'^admin/products/add/$', create_object, {'model': Product, 'post_save_redirect': ''}),

Et je suis pertinemment nouveau à l'ensemble de Django/MVC/MTV chose, rendez-vous donc facile...

167voto

Carl Meyer Points 30736

La complexité croissante de cette réponse au fil du temps, et de nombreux hacks nécessaire, doit sûrement vous mettre en garde contre cela. C'est en s'appuyant sur les sans-papiers interne détails de mise en œuvre de l'admin, est susceptible de se rompre à nouveau dans les futures versions de Django, et n'est pas plus facile à mettre en œuvre que juste de trouver un autre JS widget de calendrier et en les utilisant.

Cela dit, voici ce que vous devez faire si vous êtes déterminé à faire ce travail:

  1. Définir votre propre ModelForm sous-classe pour votre modèle (en mieux de le mettre dans forms.py dans votre application), et dites-lui d'utiliser le AdminDateWidget / AdminTimeWidget / AdminSplitDateTime (remplacez "madate", etc avec les bon noms de champ à partir de votre modèle):

    from django import forms
    from my_app.models import Product
    from django.contrib.admin import widgets                                       
    
    class ProductForm(forms.ModelForm):
        class Meta:
            model = Product
        def __init__(self, *args, **kwargs):
            super(ProductForm, self).__init__(*args, **kwargs)
            self.fields['mydate'].widget = widgets.AdminDateWidget()
            self.fields['mytime'].widget = widgets.AdminTimeWidget()
            self.fields['mydatetime'].widget = widgets.AdminSplitDateTime()
    
  2. Changer votre URLconf passer "form_class': ProductForm au lieu de "modèle": Produit générique create_object vue (qui signifie "à partir de my_app.les formulaires d'importation ProductForm" au lieu de "de my_app.modèles d'importation de Produits", bien sûr).

  3. Dans la tête de votre modèle, inclure {{ formulaire.les médias }} à la sortie de la des liens vers les fichiers Javascript.

  4. Et le hacky partie: l'administrateur de la date/heure widgets présumer que l'i18n JS choses a été chargé, et nécessitent également core.js mais ne pas fournir soit un automatiquement. Donc, dans votre modèle ci-dessus {{ formulaire.les médias }} vous aurez besoin de:

    <script type="text/javascript" src="/my_admin/jsi18n/"></script>
    <script type="text/javascript" src="/media/admin/js/core.js"></script>
    

    Vous pouvez également utiliser l'admin suivante CSS (merci Alex pour la mention de ceci):

    <link rel="stylesheet" type="text/css" href="http://stackoverflow.com/media/admin/css/forms.css"/>
    <link rel="stylesheet" type="text/css" href="http://stackoverflow.com/media/admin/css/base.css"/>
    <link rel="stylesheet" type="text/css" href="http://stackoverflow.com/media/admin/css/global.css"/>
    <link rel="stylesheet" type="text/css" href="http://stackoverflow.com/media/admin/css/widgets.css"/>
    

Cela implique que Django admin médias (ADMIN_MEDIA_PREFIX) est dans /media/admin/ -, vous pouvez le changer pour votre installation. Idéalement, vous devriez utiliser un contexte processeur de transmettre ces valeurs à votre modèle, au lieu de coder en dur, mais c'est au-delà de la portée de cette question.

Cela implique aussi que l'URL /my_admin/jsi18n/ manuellement filaire jusqu'à la django.les vues.i18n.javascript_catalog vue (ou null_javascript_catalog si vous n'utilisez pas l'I18N). Vous devez le faire vous-même au lieu de passer par l'administrateur de l'application, de sorte qu'il est accessible indépendamment de savoir si vous êtes connecté en admin (merci Jeremy pour le signaler). Exemple de code pour votre URLconf:

(r'^my_admin/jsi18n', 'django.views.i18n.javascript_catalog'),

Enfin, si vous utilisez Django 1.2 ou ultérieure, vous avez besoin d'un code supplémentaire dans votre modèle pour aider les widgets trouver leurs médias:

{% load adminmedia %} /* At the top of the template. */

/* In the head section of the template. */
<script type="text/javascript">
window.__admin_media_prefix__ = "{% filter escapejs %}{% admin_media_prefix %}{% endfilter %}";
</script>

Grâce lupefiasco pour cet ajout.

66voto

zgoda Points 8549

La solution est hackers, je pense qu’avec du JavaScript à l’aide de votre propre widget date/heure n’est plus possible.

13voto

Romamo Points 61

Mon code de tête pour la version 1.4 (certaines nouvelles et autres supprimées)

10voto

lupefiasco Points 1731

À partir de Django 1.2 RC1, si vous utilisez l’astuce Django admin date picker widge, le texte suivant doit être ajouté à votre modèle, ou vous verrez l’url d’icône calendrier référencé par « / manque-admin-médias-prefix / ».

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X