Admin select box in django

I have a model that has CharField, and in the admin I want to add options to the widget. The reason for this is because I use a proxy model, and there are a bunch of models that share this CharField, but each of them has different options.

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) 

For this model, I want to use MY_CHOICES in MyModelAdmin .

Am I redefining a widget? Do I need to redefine the whole form?

+7
source share
4 answers
 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) 

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

+14
source

You need to override the form that ModelAdmin will use:

 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() 

If you need your choice to be dynamic, perhaps you could do something similar to:

 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 

and in ModelAdmin __init__ specify what will be MY_CHOICES , and instead assign an instance of the form:

Good luck! :)

+3
source

in Gerard's answer , if you hold:

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

then when you try to add a new model from admin, you will always get "This field is required." for all required fields.

you must remove stuff_choices=() from initialization:

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

You need to think about how you are going to store data at the database level. I suggest doing this:

  • Run this pip command: pip install django-multiselectfield
  • In the models.py file:

     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) 
  • In your settings.py file:

      INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', #.....................# 'multiselectfield', ) 
  • Watch the MAGIC!

A source:

0
source

All Articles