2009-09-07 8 views
10

Ich experimentiere mit Django und der eingebauten Admin-Oberfläche.django model/modelForm - Wie bekommt man eine dynamische Auswahl in choiceField?

Ich möchte im Grunde ein Feld, das eine Dropdown in der Admin-Benutzeroberfläche ist. Die Auswahlmöglichkeiten sollten alle Verzeichnisse sein, die in einem angegebenen Verzeichnis verfügbar sind.
Wenn ich ein Feld wie folgt definieren:

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

es mir alle Dateien im Verzeichnis zeigt, aber nicht die Verzeichnisse.

Weiß jemand wie ich die Ordner anzeigen kann?

auch versucht i

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

tun, wo SOME_LIST eine Liste i Code füllen mit einigen Brauch ist die Ordner in einem Verzeichnis zu lesen. Dies funktioniert, aber es wird nicht aktualisiert. d. h. die Auswahlliste ist auf einen Schnappschuss von dem, was dort war, wenn die App zum ersten Mal ausgeführt wird, beschränkt.

danke im voraus.


Update:
nach einiger Denken und Forschung entdeckte ich, was ich entweder
1. sein möchte kann mein eigenes Widget erstellen, die auf forms.ChoiceField
oder
2 basiert. übergeben Sie meine Liste der Ordner an die Auswahlliste, wenn es an den Client gerendert wird

für 1. ich versuchte ein benutzerdefiniertes Widget mein Modell sieht aus wie

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

dann dieses meine benutzerdefinierte Widget ist:

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) 

dann tat ich dies in meiner Modelform

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

und es schien nicht work.What Ich meine damit, dass Django mein Widget nicht verwenden wollte und stattdessen den Standard-Textinput gerendert hat, den Sie erhalten, wenn Sie ein CharField verwenden.

für 2. Ich habe versucht, dies in meinem Modelform

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

Ich habe auch versucht Klasse test1Form (Modelform): test_folder_ddl = forms.ChoiceField (Auswahl = {einige Liste})

und es würde immer noch das Standard-Char-Feld-Widget darstellen. Wer weiß, was ich falsch mache?

Antwort

15

Yay gelöst.Nachdem ich den ganzen Tag den Kopf geschlagen und alle möglichen Beispiele von Leuten durchgegangen bin, habe ich das zum Laufen gebracht.

im Grunde hatte ich mit # 2 die richtige Idee. Die Schritte sind
- Erstellen Sie eine ModelForm unseres Modells - überschreiben Sie den Standardformularfeldbenutzer für ein models.CharField. d. h. wir möchten explizit sagen, ein choiceField zu verwenden.
- Dann müssen wir außer Kraft setzen, wie das Formular instanziiert wird, so dass wir das, was wir erzeugen unsere dynamische Auswahlliste
verwenden möchten rufen - das Admin dann in unserer Modeladmin sicherstellen, dass wir ausdrücklich sagen unsere Modelform verwenden

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

Awesome, vielen Dank, das funktioniert auf django 1.10, auch. – Moritz

2

ich benutze einen Generator:

sehen 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:]] 
Verwandte Themen