2009-09-07 11 views
10

J'expérimente django et l'interface d'administration intégrée.django model/modelForm - Comment obtenir des choix dynamiques dans choiceField?

Je veux fondamentalement avoir un champ qui est une liste déroulante dans l'interface utilisateur d'administration. Les choix déroulants doivent être tous les répertoires disponibles dans un répertoire spécifié.
Si je définir un champ comme ceci:

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

il me montre tous les fichiers dans le répertoire, mais pas les répertoires .

Est-ce que quelqu'un sait comment je peux afficher les dossiers?

aussi j'ai essayé de faire

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

où SOME_LIST est une liste i en utilisant POPULATE code personnalisé pour lire les dossiers dans un répertoire. Cela fonctionne mais il ne rafraîchit pas. c'est-à-dire que la liste de choix est limitée à un instantané de ce qui existait lors de l'exécution de l'application pour la première fois.

merci d'avance.


mise à jour:
j'ai découvert après une réflexion et à la recherche ce que je veux peut être soit
1. créer mon propre widget qui est basé sur forms.ChoiceField
ou
2. passer ma liste de dossiers à la liste de choix quand il est rendu au client

pour 1. j'ai essayé un widget personnalisé. mon modèle ressemble

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

alors ceci est mon widget personnalisé:

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) 

alors je l'ai fait dans mon ModelForm

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

et il ne semble pas work.What Je veux dire par là que django n'a pas voulu utiliser mon widget et a rendu le textinput par défaut lorsque vous utilisez un CharField.

pour 2. J'ai essayé dans mon ModelForm

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

J'ai aussi essayé test1Form de classe (ModelForm): test_folder_ddl = forms.ChoiceField (choix = {liste} certains)

et il rendrait toujours le widget champ de caractères par défaut. Quelqu'un sait ce que je fais mal?

Répondre

15

Yay résolu.après avoir battu ma tête toute la journée et avoir passé en revue toutes sortes d'exemples par des gens, je me suis mis au travail.

fondamentalement j'ai eu la bonne idée aveC# 2. Les étapes sont
- Créer une ModelForm de notre modèle - remplacer l'utilisateur de champ de formulaire par défaut pour un models.CharField. c'est-à-dire que nous voulons dire explicitement utiliser un champ de choix.
- Ensuite, nous devons passer outre la façon dont la forme est instancié pour que nous appelons la chose que nous voulons utiliser pour générer notre liste dynamique des choix
- puis dans notre ModelAdmin assurez-vous que nous disons explicitement l'administrateur d'utiliser notre 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

Impressionnant, merci beaucoup, cela fonctionne sur django 1.10, aussi. – Moritz

2

J'utilise un générateur:

voir 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:]] 
Questions connexes