2009-09-16 23 views
23

Aquí está parte de mi models.py:Seleccionar un elemento en Django de administración en línea con los botones de radio

class Person(models.Model): 
    birth_year = WideYear(null=True, blank=True) 
    birth_year_uncertain = models.BooleanField() 
    death_year = WideYear(null=True, blank=True) 
    death_year_uncertain = models.BooleanField() 
    flourit_year = WideYear(null=True, blank=True) 
    flourit_year_uncertain = models.BooleanField() 
    FLOURIT_CHOICES = (
     (u'D', u'Birth and death dates'), 
     (u'F', u'Flourit date'), 
    ) 
    use_flourit = models.CharField('Date(s) to use', max_length=2, choices=FLOURIT_CHOICES) 
    def __unicode__(self): 
     if self.personname_set.filter(default_name__exact=True): 
      name = z(self.personname_set.filter(default_name__exact=True)[0]) 
     else: 
      name = u'[Unnamed person]' 
     if self.use_flourit == u'D': 
      dates = '%s - %s' % (z(self.birth_year), z(self.death_year)) 
     else: 
      dates = 'fl. %s' % (z(self.flourit_year)) 
     return '%s (%s)' % (name, dates) 
    class Meta: 
     ordering = ['ordering_string'] 

class PersonName(models.Model): 
    titles = models.CharField(max_length=65535, null=True, blank=True) 
    surname = models.CharField(max_length=255, null=True, blank=True) 
    first_name = models.CharField(max_length=255, null=True, blank=True) 
    middle_names = models.CharField(max_length=255, null=True, blank=True) 
    post_nominals = models.CharField(max_length=65535, null=True, blank=True) 
    default_name = models.BooleanField() 
    person = models.ForeignKey(Person, null=True, blank=True) 
    def __unicode__(self): 
     return '%s, %s %s' % (self.surname, self.first_name, self.middle_names) 
    class Meta: 
     unique_together = ("titles", "surname", "first_name", "middle_names", "post_nominals", "person") 
     unique_together = ("default_name", "person") 
post_save.connect(post_save_person_and_person_name, sender=PersonName) 

Quiero PersonName sea editable en línea con la persona en el admin como TabularInline. Además, quiero que el campo default_name de PersonName se muestre como un botón de opción, de modo que solo un PersonName por persona pueda tener default_name = True.

Es la última parte que es la parte difícil. Tener una interfaz de botón de radio dentro de un formulario es relativamente fácil en Django. Tener uno que seleccione, esencialmente, un formulario en un formset, parece ser mucho, mucho más difícil.

Una forma de hacer esto sería agregar JavaScript en change_form.html para Person que usa una expresión regular para hacer coincidir los < elementos de entrada > para default_name y asegura que al marcar uno de ellos se desmarca el resto. Pero parece que podría romperse si cambia la convención de Django para nombrar campos de formulario HTML; Además, solo solucionaría los problemas para los usuarios con navegadores habilitados para JavaScript.

¡Alguna idea mejor recibida con gratitud!

ACTUALIZACIÓN 17/9/2009

La siguiente extensión plantilla de administración (basado en this y this) pone en práctica la sugerencia de JavaScript anterior, pero sería de desear que las mejores soluciones!

{% extends "admin/change_form.html" %} 

{% block extrahead %} 
    <script src="/site_media/jquery-1.3.2.min.js" type="text/javascript"></script> 
    <script type="text/javascript"> 
     jQuery(document).ready(function(){ 
      // Replace default_name checkboxes with radio buttons. 
      $(".default_name input").each(function(){ 
       var name = $(this).attr('name'); // grab name of original 
       var id = $(this).attr('id'); // grab id of original 
       if ($(this).attr('checked')) { // grab checked value of original 
        var checked = ' checked="checked"'; 
       } else { 
        var checked = ''; 
       } 
       /* create new visible input */ 
       var html = '<input type="radio" name="'+name+'" id="'+id+'" value="True"'+checked+' />'; 
       $(this).after(html).remove(); // add new, then remove original input 
      }); 
      // Ensure only one default_name radio button can be checked at a time. 
      $(".default_name input").click(function(){ 
       $(".default_name input").not(this).removeAttr("checked"); 
      }); 
     }); 
    </script> 
{% endblock %} 

Respuesta

1

Creo que no obtendrá un método convencional de solo HTML para hacer lo que quiera.

Sin embargo, no debería tener que confiar en la expresión regular. ¿No puedes añadir un nombre de la clase a sus campos de entrada para que jQuery ...

supongo que es más duro que pensé por primera vez (aquí la respuesta): Define css class in django Forms

Es sólo una solución ligeramente mejor, aunque.

Cuestiones relacionadas