2009-09-07 13 views
10

sto sperimentando con django e l'interfaccia di amministrazione integrata.django model/modelForm - Come ottenere scelte dinamiche in choiceField?

Fondamentalmente voglio avere un campo che è un menu a discesa nell'interfaccia utente di amministrazione. Le opzioni di selezione dovrebbero essere tutte le directory disponibili in una directory specificata.
se definisco un campo come questo:

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

mi mostra tutti i file nella directory, ma non i directory.

Qualcuno sa come posso visualizzare le cartelle?

inoltre ho provato a fare

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

dove SOME_LIST è una lista Io popolo utilizzando codice personalizzato per leggere le cartelle in una directory. Funziona ma non si aggiorna. la lista delle scelte è limitata a un'istantanea di ciò che era presente quando si esegue l'app per la prima volta.

grazie in anticipo.


aggiornamento:
dopo un po 'di pensiero e di ricerca ho scoperto quello che voglio può essere a uno
1. creare il mio widget che si basa su forms.ChoiceField
o
2. passare il mio elenco di cartelle all'elenco delle scelte quando è reso al client

per 1. ho provato un widget personalizzato. mio modello assomiglia

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

allora questo è il mio widget personalizzato:

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) 

poi ho fatto questo nella mia ModelForm

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

e non sembrava work.What Intendo dire che Django non voleva usare il mio widget e invece ha reso il textinput predefinito che si ottiene quando si usa un CharField.

per 2. Ho provato questo nel mio ModelForm

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

Ho anche provato classe test1Form (ModelForm): test_folder_ddl = forms.ChoiceField (scelte = {} qualche lista)

e renderà ancora il widget char field predefinito. Qualcuno sa cosa sto facendo male?

risposta

15

Yay risolto.dopo aver battuto la testa tutto il giorno e aver esaminato ogni sorta di esempi da persone, ho fatto in modo che funzionasse.

in pratica ho avuto l'idea giusta con # 2. I passaggi sono
- Creare un ModelForm del nostro modello - sovrascrivere l'utente del campo modulo predefinito per un modello.CharField. cioè, diciamo esplicitamente di usare un campo di scelta.
- allora dobbiamo ignorare come la forma viene creata un'istanza in modo che noi chiamiamo la cosa che vogliamo utilizzare per generare il nostro elenco dinamico di scelte
- poi nel nostro ModelAdmin assicurarsi diciamo esplicitamente l'amministratore di utilizzare il nostro 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

impressionante, grazie mille, questo funziona su Django 1.10, anche. – Moritz

2

io uso un generatore:

vedere 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:]] 
Problemi correlati