2009-09-07 17 views
10

estoy experimentando con django y la interfaz de administración integrada.django model/modelForm - ¿Cómo obtener opciones dinámicas en choiceField?

Básicamente quiero tener un campo desplegable en la interfaz de usuario del administrador. Las opciones desplegables deben ser todos los directorios disponibles en un directorio específico.
Si defino un campo como este:

test_folder_list = models.FilePathField(path=/some/file/path) 

que me muestra todos los archivos en el directorio, pero no los directorios .

¿Alguien sabe cómo puedo mostrar las carpetas?

También probé haciendo

test_folder_list = models.charField(max_length=100, choices=SOME_LIST) 

donde SOME_LIST es una lista que pueblan el uso de algún código personalizado para leer las carpetas de un directorio. Esto funciona pero no se actualiza. es decir, la lista de opciones está limitada a una instantánea de lo que estaba allí cuando se ejecuta la aplicación por primera vez.

gracias de antemano.


actualización:
después de algún pensamiento y la investigación descubrí lo que deseo puede ser que sea
1. crear mi propio widget que se basa en forms.ChoiceField
o
2. pasar mi lista de carpetas a la lista de opciones cuando se representa en el cliente

para 1. intenté un widget personalizado. mi modelo se parece

class Test1(models.Model): 
    test_folder_ddl = models.CharField(max_length=100) 

entonces este es mi widget personalizado:

class FolderListDropDown(forms.Select): 
def __init__(self, attrs=None, target_path): 
    target_folder = '/some/file/path' 
    dir_contents = os.listdir(target_folder) 
    directories = [] 
    for item in dir_contents: 
    if os.path.isdir(''.join((target_folder,item,))): 
    directories.append((item, item),) 
    folder_list = tuple(directories) 
    super(FolderListDropDown, self).__init__(attrs=attrs, choices=folder_list) 

luego hice esto en mi ModelForm

class test1Form(ModelForm): 
    test_folder_ddl = forms.CharField(widget=FolderListDropDown()) 

y no parecía work.What Quiero decir con esto es que django no quería usar mi widget y en su lugar representaba el textinput predeterminado que obtienes cuando usas un CharField.

para 2. he intentado esto en mi ModelForm

class test1Form(ModelForm): 
    test_folder_ddl = forms.CharField(widget=FolderListDropDown()) 
    test_folder_ddl.choices = {some list} 

También probé test1Form clase (ModelForm): test_folder_ddl = forms.ChoiceField (opciones = {} alguna lista)

y todavía representaría el widget de campo de char por defecto. ¿Alguien sabe lo que estoy haciendo mal?

Respuesta

15

Yay resuelto.Después de golpearme la cabeza todo el día y examinar todo tipo de ejemplos por personas, conseguí que esto funcionara.

básicamente tuve la idea correcta con el n. ° 2. Los pasos son
- Cree un ModelForm de nuestro modelo - anule el usuario de campo de formulario predeterminado para un models.CharField. es decir, queremos decir explícitamente usar un campo de elección.
- Entonces tenemos que anular cómo la forma se crea una instancia para que nosotros llamamos el que queremos utilizar para generar nuestra lista dinámica de opciones
- entonces en nuestro ModelAdmin asegurarse que indicar explícitamente al administrador para utilizar nuestro ModelForm

class Test1(models.Model): 
    test_folder_ddl = models.CharField(max_length=100) 


class Test1Form(ModelForm): 
    test_folder_ddl = forms.choiceField() 

    def __init__(self, *args, **kwargs): 
     super(Test1Form, self).__init__(*args, **kwargs) 
     self.fields['test_folder_ddl'].choices = utility.get_folder_list() 

class Test1Admin(admin.ModelAdmin): 
    form = Test1Form 
+0

impresionante, muchas gracias, esto funciona en Django 1.10, también. – Moritz

2

Puedo usar un generador:

ver git: //gist.github.com/1118279.git

import pysvn 

    class SVNChoices(DynamicChoice): 
     """ 
     Generate a choice from somes files in a svn repo 
     """" 
     SVNPATH = 'http://xxxxx.com/svn/project/trunk/choices/' 
     def generate(self): 
      def get_login(realm, username, may_save): 
       return True, 'XXX', 'xxxxx', True 
      client = pysvn.Client() 
      client.callback_get_login = get_login 
      return [os.path.basename(sql[0].repos_path) for sql in client.list(self.SVNPATH)[1:]] 
Cuestiones relacionadas