2012-09-27 168 views
7

我有一個模型,有一個CharField,並在管理員中,我想添加選擇到窗口小部件。原因是我使用的是代理模式,並且有許多共享此CharField的模型,但它們都有不同的選擇。Django管理員選擇字段

class MyModel(MyBaseModel): 
    stuff = models.CharField('Stuff', max_length=255, default=None) 

    class Meta: 
     proxy = True 

class MyModelAdmin(admin.ModelAdmin): 
    fields = ('stuff',) 
    list_display = ('stuff',) 
admin.site.register(MyModel, MyModelAdmin) 

對於這個模型我想在MyModelAdmin使用MY_CHOICES

我是否重寫一個小部件?我是否需要覆蓋整個表單?

回答

14
from django.contrib import admin 
from django import forms 

class MyModel(MyBaseModel): 
    stuff = models.CharField('Stuff', max_length=255, default=None) 

    class Meta: 
     proxy = True 

class MyModelForm(forms.ModelForm): 
    MY_CHOICES = (
     ('A', 'Choice A'), 
     ('B', 'Choice B'), 
    ) 

    stuff = forms.ChoiceField(choices=MY_CHOICES) 

class MyModelAdmin(admin.ModelAdmin): 
    fields = ('stuff',) 
    list_display = ('stuff',) 
    form = MyModelForm 

admin.site.register(MyModel, MyModelAdmin) 

參見:https://docs.djangoproject.com/en/dev/ref/forms/fields/#choicefield

+1

非常感謝,我是通過文檔挖掘,錯過了這個:S有沒有辦法避免創建的ModelForm是嗎? –

+0

我不認爲有。爲什麼? – demux

+0

只是檢查,我認爲可能有一個選項,只是將它傳遞給charfield或作爲元選項或其他東西。 –

3

你需要重寫形式ModelAdmin將使用:

class MyForm(forms.ModelForm): 
    stuff = forms.CharField('Stuff', max_length=255, choices=MY_CHOICES, default=None) 

    class Meta: 
     model = MyModel 
     fields = ('stuff', 'other_field', 'another_field') 


class MyModelAdmin(admin.ModelAdmin): 
    fields = ('stuff',) 
    list_display = ('stuff',) 
    form = MyForm() 

如果你需要你的選擇是動態的,也許你可以做一些類似的東西:

class MyForm(forms.ModelForm): 
    stuff = forms.CharField('Stuff', max_length=255, choices=MY_CHOICES, default=None) 

    def __init__(self, stuff_choices=(), *args, **kwargs): 
     # receive a tupple/list for custom choices 
     super(MyForm, self).__init__(*args, **kwargs) 
     self.fields['stuff'].choices = stuff_choices 

,並在您ModelAdmin__init__定義什麼MY_CHOICES將是,並在那裏分配表格實例:

祝你好運! :)

+0

我以爲形式。CharField就像models.CharField並有選擇選項。但我決定仔細檢查,發現表單中有ChoiceField(請參閱我的答案)。 – demux

0

Gerard's answer,如果你繼續:

def __init__(self, stuff_choices=(), *args, **kwargs): 

那麼當你將嘗試添加從管理新模式,你總是會得到「這是必須填寫。」爲所有必填字段。

,你應該從初始化刪除stuff_choices=()

def __init__(self,*args, **kwargs): 
0

你需要考慮你將如何把數據存儲在數據庫級別的。 我建議這樣做:

  1. 運行此命令點子:pip install django-multiselectfield
  2. 在你的models.py文件:

    from multiselectfield import MultiSelectField 
    
    MY_CHOICES = (('item_key1', 'Item title 1.1'), 
          ('item_key2', 'Item title 1.2'), 
          ('item_key3', 'Item title 1.3'), 
          ('item_key4', 'Item title 1.4'), 
          ('item_key5', 'Item title 1.5')) 
    
    class MyModel(models.Model): 
         my_field = MultiSelectField(choices=MY_CHOICES) 
    
  3. 在您的settings.py:

    INSTALLED_APPS = (
         'django.contrib.auth', 
         'django.contrib.contenttypes', 
         'django.contrib.sessions', 
         'django.contrib.sites', 
         'django.contrib.admin', 
    
         #.....................# 
    
         'multiselectfield', 
    ) 
    
  4. 觀看MAGIC發生!

來源: