2011-04-24 16 views

Respuesta

11

Chris tiene una gran respuesta. Como alternativa, puedes hacer esto usando solo javascript. Coloque el siguiente javascript en las páginas donde desea las diferentes opciones de tiempo.

DateTimeShortcuts.overrideTimeOptions = function() { 
    // Find the first time element 
    timeElement = django.jQuery("ul.timelist li").eq(0).clone(); 
    originalHref = timeElement.find('a').attr('href'); 

    // remove all existing time elements 
    django.jQuery("ul.timelist li").remove(); 

    // add new time elements representing those you want 
    var i=0; 
    for (i=0;i<=23;i++) { 
     // use a regular expression to update the link 
     newHref = originalHref.replace(/Date\([^\)]*\)/g, "Date(1970,1,1," + i + ",0,0,0)"); 
     // update the text for the element 
     timeElement.find('a').attr('href', newHref).text(i+"h"); 
     // Add the new element into the document 
     django.jQuery("ul.timelist").append(timeElement.clone()); 
    } 
} 

addEvent(window, 'load', DateTimeShortcuts.overrideTimeOptions); 
+0

En realidad, eso es bastante elegante. Dado que el único punto en la subclasificación es anular el JS que se está utilizando, su enfoque es probablemente el mejor. –

+0

Gracias, me gustó tu solución también. Mi solución usa menos código, pero parece menos intencional que la tuya. Traté de pensar qué solución sería más fácil de mantener con el tiempo, en particular, ya que Django sí mismo se actualizó. Me gustó el tuyo porque dejaba muy claro lo que estaba sucediendo. Me gustó que la mina se pudiera implementar sin duplicar ninguno de los archivos de Django. Realmente no podía entender qué camino era más fácil de mantener, así que pensé en publicar la solución y dejar que la gente evaluara este enfoque. –

10

Subclase AdminTimeWidget para incluir un DateTimeShortcuts.js modificados (llegar a eso en un segundo), entonces subclase AdminSplitDateTime incluir su subclase MyAdminTimeWidget lugar del predeterminado Django uno:

from django.contrib.admin.widgets import AdminTimeWidget 
from django.conf import settings 

class MyAdminTimeWidget(AdminTimeWidget): 
    class Media: 
     js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js", 
       settings.MEDIA_URL + "js/admin/DateTimeShortcuts.js") 

class MyAdminSplitDateTime(AdminSplitDateTime): 
    def __init__(self, attrs=None): 
     widgets = [AdminDateWidget, MyAdminTimeWidget] 
     forms.MultiWidget.__init__(self, widgets, attrs) 

El ingrediente secreto está en django/contrib/admin/media/js/admin/DateTimeShortcuts.js . Esto es lo que crea la lista que desea modificar. Copie este archivo y péguelo en el directorio site_media/js/admin de su proyecto. El código en cuestión tiene que modificar es en las líneas 85-88:

quickElement("a", quickElement("li", time_list, ""), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().strftime('" + time_format + "'));"); 
quickElement("a", quickElement("li", time_list, ""), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,0,0,0,0).strftime('" + time_format + "'));"); 
quickElement("a", quickElement("li", time_list, ""), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,6,0,0,0).strftime('" + time_format + "'));"); 
quickElement("a", quickElement("li", time_list, ""), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,12,0,0,0).strftime('" + time_format + "'));"); 

sólo tiene que añadir a/eliminar de/modificar ese poco de Javascript al contenido de su corazón.

Finalmente, conecte su nuevo widget a cualquier DateTimeFields que desee. Su mejor apuesta para que, probablemente, será el atributo formfield_overrides en ModelAdmin:

class MyModelAdmin(admin.ModelAdmin): 
    formfield_overrides = { 
     models.DateTimeField: {'widget': MyAdminSplitDateTime}, 
    } 
1

JS Sustitución por DateTimeShortcuts.overrideTimeOptions función sólo con una forma (ERROR: el cambio de tiempo en el modelo del niño afecta modelo padre, por lo que no puede cambiar timefield en forma de modelo infantil por este widget)

Si desea utilizar opciones de tiempo de medida con inlines:

en /static/admin/js/admin/DateTimeShortcuts.js reemplazan:

quickElement("a", quickElement("li", time_list, ""), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().strftime('" + time_format + "'));"); 
quickElement("a", quickElement("li", time_list, ""), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,0,0,0,0).strftime('" + time_format + "'));"); 
quickElement("a", quickElement("li", time_list, ""), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,6,0,0,0).strftime('" + time_format + "'));"); 
quickElement("a", quickElement("li", time_list, ""), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,12,0,0,0).strftime('" + time_format + "'));"); 

por:

for(j=6;j<=23;j++){ 
    quickElement("a", quickElement("li", time_list, ""), j+":00", "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1," + j + ",0,0,0).strftime('" + time_format + "'));"); 
} 
3

He intentado utilizar este método y se encontró el código JavaScript anterior no funciona cuando varios de fecha y hora estaban presentes en el formulario.

esto es lo que hice.

En mi sección ModelAdmin i añadido:

class Media: 
    js = ('js/clock_time_selections.js',) 

a continuación en el archivo JS:

$('document').ready(function() { 
    DateTimeShortcuts.overrideTimeOptions = function() { 
     var clockCount = 0; 
     console.log('ready'); 
     $('ul.timelist').each(function() { 
      var $this = $(this); 
      var originalHref = $this.find('a').attr('href'); 
      console.log(originalHref); 
      $this.find('li').remove(); 
      for (i=8; i <= 20; i++) { 
       var newLink = '<li><a href="javascript:DateTimeShortcuts.handleClockQuicklink('+ clockCount + ', ' + i 
        + ');"> ' + i + ':00h</a></li>'; 
       $this.append(newLink); 
      } 
      //console.log($this.html()); 

      clockCount++; 
     }); 
    }; 

    addEvent(window, 'load', DateTimeShortcuts.overrideTimeOptions); 
}); 

Nota: tuve que poner dentro de un document.ready porque me encontré con que no podía controlar dónde se incluyó el guión en la página (parece haberse cargado antes de los archivos js del calendario predeterminado).

1

Fui con un enfoque mucho más simple y funcionó para mí.Simplemente añade opciones a mi modelo usando el siguiente código:

class Class(Model): program = ForeignKey('Program') time_of_the_day = TimeField(choices=( (datetime.datetime.strptime('7:00 am', "%I:%M %p").time(), '7:00 am'), (datetime.datetime.strptime('8:00 am', "%I:%M %p").time(), '8:00 am'), (datetime.datetime.strptime('9:00 am', "%I:%M %p").time(), '9:00 am'), (datetime.datetime.strptime('6:00 pm', "%I:%M %p").time(), '6:00 pm'), (datetime.datetime.strptime('7:00 pm', "%I:%M %p").time(), '7:00 pm'), (datetime.datetime.strptime('8:00 pm', "%I:%M %p").time(), '8:00 pm'), (datetime.datetime.strptime('9:00 pm', "%I:%M %p").time(), '9:00 pm'),
))

Esperanza esto ayuda

+0

¿Estás seguro? Recibí un error que decía que 'options' es una opción no válida para' TimeField' – raratiru

+0

Funcionó para mí en 2015, tal vez la versión actual no lo permite. El proyecto con este fragmento todavía está en funcionamiento. – Bit68

+1

Tengo que volver a verificarlo en caso de que haya escrito mal algo, su idea es genial. – raratiru

Cuestiones relacionadas