Question

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

Était-ce utile?

La solution

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 le fait à tous.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 citer ce):

    <link rel="stylesheet" type="text/css" href="/media/admin/css/forms.css"/>
    <link rel="stylesheet" type="text/css" href="/media/admin/css/base.css"/>
    <link rel="stylesheet" type="text/css" href="/media/admin/css/global.css"/>
    <link rel="stylesheet" type="text/css" href="/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 souligner ce point).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>

Merci lupefiasco pour cet ajout.

Autres conseils

Comme la solution est hackish, je pense à l'aide de votre propre date/heure widget avec un peu de JavaScript est plus possible.

Yep, j'ai fini par substitution de l' /admin/jsi18n/ url.

Voici ce que j'ai ajouté dans mon urls.py.Assurez-vous qu'il est au-dessus de l' /admin/ url

    (r'^admin/jsi18n', i18n_javascript),

Et voici le i18n_javascript fonction que j'ai créé.

from django.contrib import admin
def i18n_javascript(request):
  return admin.site.i18n_javascript(request)

Ma tête code pour la version 1.4(quelques nouvelles et quelques supprimé)

{% block extrahead %}

<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/forms.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/base.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/global.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/widgets.css"/>

<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/core.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/admin/RelatedObjectLookups.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/jquery.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/jquery.init.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/actions.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/calendar.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/admin/DateTimeShortcuts.js"></script>

{% endblock %}

Je trouve moi-même faisant référence à ce post beaucoup, et a constaté que la la documentation définit un légèrement moins hacky façon à remplacer les widgets par défaut.

(Pas besoin de surcharger la ModelForm de __init__ de la méthode)

Cependant, vous avez encore besoin de fil de votre JS et CSS de façon appropriée comme Carl mentionne.

forms.py

from django import forms
from my_app.models import Product
from django.contrib.admin import widgets                                       


class ProductForm(forms.ModelForm):
    mydate = forms.DateField(widget=widgets.AdminDateWidget)
    mytime = forms.TimeField(widget=widgets.AdminTimeWidget)
    mydatetime = forms.SplitDateTimeField(widget=widgets.AdminSplitDateTime)

    class Meta:
        model = Product

Référence Les Types De Champ pour trouver la valeur par défaut des champs de formulaire.

Départ dans Django 1.2 RC1, si vous utilisez le Django admin sélecteur de date widge truc, le suivant doit être ajouté à votre modèle, ou vous verrez l'icône du calendrier url référencé par "/manquant-admin-médias-prefix/".

{% 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>

En complément de la réponse de Carl Meyer, je voudrais faire un commentaire que vous avez besoin de mettre la tête dans certaines bloc valide (à l'intérieur de l'en-tête) à l'intérieur de votre modèle.

{% block extra_head %}

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

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

{{ form.media }}

{% endblock %}

Ci-dessous va aussi fonctionner comme un dernier recours si le ci-dessus a échoué

class PaymentsForm(forms.ModelForm):
    class Meta:
        model = Payments

    def __init__(self, *args, **kwargs):
        super(PaymentsForm, self).__init__(*args, **kwargs)
        self.fields['date'].widget = SelectDateWidget()

Même que

class PaymentsForm(forms.ModelForm):
    date = forms.DateField(widget=SelectDateWidget())

    class Meta:
        model = Payments

mettez ceci dans votre forms.py from django.forms.extras.widgets import SelectDateWidget

Qu'en est juste à l'affectation d'une classe pour votre widget, puis la liaison de cette classe pour le datepicker de JQuery?

Django forms.py:

class MyForm(forms.ModelForm):

  class Meta:
    model = MyModel

  def __init__(self, *args, **kwargs):
    super(MyForm, self).__init__(*args, **kwargs)
    self.fields['my_date_field'].widget.attrs['class'] = 'datepicker'

Et un peu de JavaScript pour le modèle:

  $(".datepicker").datepicker();

Pour Django >= 2.0

Note:En utilisant admin widgets pour la date-heure de champs n'est pas une bonne idée en tant qu'admin, les feuilles de style peuvent entrer en conflit avec votre site, les feuilles de style dans le cas où vous êtes en utilisant bootstrap ou de tout autre frameworks CSS.Si vous êtes à la construction de votre site sur bootstrap utiliser mon bootstrap-composant django-bootstrap-datepicker-plus.

Étape 1: Ajouter javascript-catalog URL de votre projet (pas d'application) urls.py fichier.

from django.views.i18n import JavaScriptCatalog

urlpatterns = [
    path('jsi18n', JavaScriptCatalog.as_view(), name='javascript-catalog'),
]

Étape 2: Ajouter JavaScript/CSS ressources à votre modèle.

<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
<script type="text/javascript" src="{% static '/admin/js/core.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static '/admin/css/widgets.css' %}">
<style>.calendar>table>caption{caption-side:unset}</style><!--caption fix for bootstrap4-->
{{ form.media }}        {# Form required JS and CSS #}

Étape 3: Utilisez admin widgets pour la date-heure de champs d'entrée dans votre forms.py.

from django.contrib.admin import widgets
from .models import Product

class ProductCreateForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ['name', 'publish_date', 'publish_time', 'publish_datetime']
        widgets = {
            'publish_date': widgets.AdminDateWidget,
            'publish_time': widgets.AdminTimeWidget,
            'publish_datetime': widgets.AdminSplitDateTime,
        }

Mise à jour de la solution et la solution de contournement pour SplitDateTime avec required=False:

forms.py

from django import forms

class SplitDateTimeJSField(forms.SplitDateTimeField):
    def __init__(self, *args, **kwargs):
        super(SplitDateTimeJSField, self).__init__(*args, **kwargs)
        self.widget.widgets[0].attrs = {'class': 'vDateField'}
        self.widget.widgets[1].attrs = {'class': 'vTimeField'}  


class AnyFormOrModelForm(forms.Form):
    date = forms.DateField(widget=forms.TextInput(attrs={'class':'vDateField'}))
    time = forms.TimeField(widget=forms.TextInput(attrs={'class':'vTimeField'}))
    timestamp = SplitDateTimeJSField(required=False,)

form.html

<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="/admin_media/js/core.js"></script>
<script type="text/javascript" src="/admin_media/js/calendar.js"></script>
<script type="text/javascript" src="/admin_media/js/admin/DateTimeShortcuts.js"></script>

urls.py

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

J'utilise cela, c'est génial, mais j'ai 2 problèmes avec le modèle:

  1. Je vois le calendrier des icônes deux fois pour chaque déposé dans le modèle.
  2. Et pour TimeField j'ai 'Entrer une date valide.'

    Here is a screenshot of the Form

models.py

from django.db import models
    name=models.CharField(max_length=100)
    create_date=models.DateField(blank=True)
    start_time=models.TimeField(blank=False)
    end_time=models.TimeField(blank=False)

forms.py

from django import forms
from .models import Guide
from django.contrib.admin import widgets

class GuideForm(forms.ModelForm):
    start_time = forms.DateField(widget=widgets.AdminTimeWidget)
    end_time = forms.DateField(widget=widgets.AdminTimeWidget)
    create_date = forms.DateField(widget=widgets.AdminDateWidget)
    class Meta:
        model=Guide
        fields=['name','categorie','thumb']

Dans Django 10.myproject/urls.py:au début de urlpatterns

  from django.views.i18n import JavaScriptCatalog

urlpatterns = [
    url(r'^jsi18n/$', JavaScriptCatalog.as_view(), name='javascript-catalog'),
.
.
.]

Dans mon template.html:

{% load staticfiles %}

    <script src="{% static "js/jquery-2.2.3.min.js" %}"></script>
    <script src="{% static "js/bootstrap.min.js" %}"></script>
    {# Loading internazionalization for js #}
    {% load i18n admin_modify %}
    <script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/jquery.init.js" %}"></script>

    <link rel="stylesheet" type="text/css" href="{% static "/admin/css/base.css" %}">
    <link rel="stylesheet" type="text/css" href="{% static "/admin/css/forms.css" %}">
    <link rel="stylesheet" type="text/css" href="{% static "/admin/css/login.css" %}">
    <link rel="stylesheet" type="text/css" href="{% static "/admin/css/widgets.css" %}">



    <script type="text/javascript" src="{% static "/admin/js/core.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/SelectFilter2.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/admin/RelatedObjectLookups.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/actions.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/calendar.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/admin/DateTimeShortcuts.js" %}"></script>

Mon Django D'Installation :1.11 Bootstrap:3.3.7

Puisque aucune de ces réponses sont tout à fait clair, je suis le partage de mon modèle de code qui ne présente pas d'erreurs à tous.

La première Moitié du modèle:

{% extends 'base.html' %}
{% load static %}
{% load i18n %}

{% block head %}
    <title>Add Interview</title>
{% endblock %}

{% block content %}

<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/core.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/forms.css' %}"/>
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/widgets.css' %}"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
<script type="text/javascript" src="{% static 'js/jquery.js' %}"></script>

Moitié Inférieure:

<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="{% static 'admin/js/vendor/jquery/jquery.min.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/actions.min.js' %}"></script>
{% endblock %}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top