django model / modelForm - 如何在choiceField中获得动态选择? [英] django model/modelForm - How to get dynamic choices in choiceField?

查看:165
本文介绍了django model / modelForm - 如何在choiceField中获得动态选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用django和内置管理界面。



我基本上想要在管理界面中放置一个字段。下拉选项应该是指定目录中可用的所有目录。

如果我定义了一个这样的字段:

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

我目录中的所有文件,而不是目录



有谁知道如何显示文件夹?



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

其中SOME_LIST是使用一些自定义代码填充目录中的文件夹的列表。这个工作,但它不刷新。即选择列表仅限于第一次运行应用程序时的任何快照。



提前感谢。






更新:

经过一些思考和研究,我发现我想要的可能是

1。创建我自己的基于forms.ChoiceField的小部件



2。将我的文件夹列表传递到选择列表当它被呈现给客户端



for 1。我尝试了一个自定义窗口小部件。
我的模型看起来像

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

那么这是我的自定义小部件:

  class FolderListDropDown(forms.Select):
def __init __(self,attrs = None,target_path):
target_folder ='/ some / file /路径'
dir_contents = os.listdir(target_folder)
directories = []
dir_contents中的项目:
如果os.path.isdir(''。join((target_folder,项目,))):
directories.append((item,item),)
folder_list = tuple(directories)
super(FolderListDropDown,self).__ init __(attrs = attrs,choices = folder_list)

然后我在我的modelForm中做到了这一点



pre code code code code code code code code code $ p>

它似乎没有工作。我的意思是django没有w蚂蚁使用我的小部件,而是渲染您使用CharField时获得的默认文本输入。



for 2。我在我的ModelForm中尝试过

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

我也尝试过
class test1Form(ModelForm):
test_folder_ddl = forms.ChoiceField(choices = {some list})



,它仍然会呈现默认的字段小部件。
任何人知道我在做错什么?

解决方案

Yay解决了。在整天殴打我的头,经过各种各样的例子,我得到了这个工作。



基本上我有正确的想法#2。步骤是

- 创建我们的模型
的ModelForm - 覆盖models.CharField的默认表单域用户。即我们想要明确地说使用choiceField。

- 然后我们必须重写表单的实例化,以便我们调用我们想要使用的东西来生成动态的选择列表

- 然后在我们的ModelAdmin中,确保我们明确告诉管理员使用我们的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


i'm experimenting with django and the builtin admin interface.

I basically want to have a field that is a drop down in the admin UI. The drop down choices should be all the directories available in a specified directory.
If i define a field like this:

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

it shows me all the files in the directory, but not the directories.

Does anyone know how i can display the folders?

also i tried doing

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

where SOME_LIST is a list i populate using some custom code to read the folders in a directory. This works but it doesn't refresh. i.e. the choice list is limited to a snapshot of whatever was there when running the app for the first time.

thanks in advance.


update:
after some thinking and research i discovered what i want may be to either
1. create my own widget that is based on forms.ChoiceField
or
2. pass my list of folders to the choice list when it is rendered to the client

for 1. i tried a custom widget. my model looks like

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

then this is my custom widget:

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)

then i did this in my modelForm

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

and it didn't seem to work.What i mean by that is django didn't want to use my widget and instead rendered the default textinput you get when you use a CharField.

for 2. I tried this in my ModelForm

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

I also tried class test1Form(ModelForm): test_folder_ddl = forms.ChoiceField(choices={some list})

and it would still render the default char field widget. Anyone know what i'm doing wrong?

解决方案

Yay solved. after beating my head all day and going through all sorts of examples by people i got this to work.

basically i had the right idea with #2. The steps are
- Create a ModelForm of our model - override the default form field user for a models.CharField. i.e. we want to explcitly say use a choiceField.
- Then we have to override how the form is instantiated so that we call the thing we want to use to generate our dynamic list of choices
- then in our ModelAdmin make sure we explicitly tell the admin to use our 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

这篇关于django model / modelForm - 如何在choiceField中获得动态选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆