Create a gist now

Instantly share code, notes, and snippets.

Embed
Howto use ListFields in Django's admin

Howto use ListFields in Django's admin

Problem

Consider this blog post model:

models.py

from django.db import models
from djangotoolbox.fields import ListField

class Post(models.Model):
    title = models.CharField(max_length=100)
    categories = ListField()

admin.py

from django.contrib.admin import site
from models import Post

site.register(Post)

Trying to edit some posts in the admin crashes with:

No form field implemented for <class 'djangotoolbox.fields.ListField'>

Solution

What we need to do is to teach the admin how to display a ListField in the edit view. Our form field will be a simple <input type=text> input box with comma-separated category names. For more about custom form fields, refer to the Django documentation and your favourite search engine using the terms "Django custom form field".

First, we need to subclass ListField to override the formfield method:

from .forms import StringListField

class CategoryField(ListField):
    def formfield(self, **kwargs):
        return models.Field.formfield(self, StringListField, **kwargs)

class Post(models.Model):
    title = models.CharField(max_length=100)
    categories = CategoryField()

Then, in forms.py, we define StringListField:

from django import forms

class StringListField(forms.CharField):
    def prepare_value(self, value):
        return ', '.join(value)

    def to_python(self, value):
        if not value:
            return []
        return [item.strip() for item in value.split(',')]

This will covert the comma-separated input box contents into a Python list, and the list value that is fetched from the database int a comma-separated string which is then displayed in the input box.

Let's add a post and check out the resulting model object in the database:

http://img30.imageshack.us/img30/2391/editform.png

>>> Post.objects.get(title='foo').categories
[u'spam', u'eggs', u'bar']

It worked! Simple, isn't it?

from django.db import models
from djangotoolbox.fields import ListField
from .forms import StringListField
class CategoryField(ListField):
def formfield(self, **kwargs):
return models.Field.formfield(self, StringListField, **kwargs)
class Post(models.Model):
title = models.CharField(max_length=100)
categories = CategoryField()
from django import forms
class StringListField(forms.CharField):
def prepare_value(self, value):
return ', '.join(value)
def to_python(self, value):
if not value:
return []
return [item.strip() for item in value.split(',')]
from django.contrib.admin import site, ModelAdmin
from models import Post
def categories(instance):
return ', '.join(instance.categories)
class PostAdmin(ModelAdmin):
list_display = ['title', categories]
site.register(Post, PostAdmin)
@nerdshark

This comment has been minimized.

Show comment
Hide comment
@nerdshark

nerdshark Jan 8, 2012

Thanks a lot for this!

Thanks a lot for this!

@georgedorn

This comment has been minimized.

Show comment
Hide comment
@georgedorn

georgedorn Jan 16, 2012

Is there something similar to handle loaddata/dumpdata? At the moment, my 'tags' SetField gets converted to a comma-delimited list of single characters.

Is there something similar to handle loaddata/dumpdata? At the moment, my 'tags' SetField gets converted to a comma-delimited list of single characters.

@jonashaag

This comment has been minimized.

Show comment
Hide comment
@jonashaag

jonashaag Jan 17, 2012

@georgedorn could you please open a bug for that: https://github.com/django-nonrel/django-nonrel. With your model definition and the output. Thanks!

Owner

jonashaag commented Jan 17, 2012

@georgedorn could you please open a bug for that: https://github.com/django-nonrel/django-nonrel. With your model definition and the output. Thanks!

@jonashaag

This comment has been minimized.

Show comment
Hide comment
@jonashaag

jonashaag Feb 3, 2012

me neither :)

Owner

jonashaag commented Feb 3, 2012

me neither :)

@jtdp

This comment has been minimized.

Show comment
Hide comment
@jtdp

jtdp Feb 10, 2012

Very helpful. Thank You!

jtdp commented Feb 10, 2012

Very helpful. Thank You!

@ielshareef

This comment has been minimized.

Show comment
Hide comment
@ielshareef

ielshareef Jun 28, 2012

Great work! Here's how to use EmbeddedModelField in Django's admin https://gist.github.com/3011156

Great work! Here's how to use EmbeddedModelField in Django's admin https://gist.github.com/3011156

@jmoz

This comment has been minimized.

Show comment
Hide comment
@jmoz

jmoz Nov 15, 2012

Thanks. How would you model finding a post by one of the tags?

jmoz commented Nov 15, 2012

Thanks. How would you model finding a post by one of the tags?

@DrKaoliN

This comment has been minimized.

Show comment
Hide comment
@DrKaoliN

DrKaoliN Jan 28, 2013

This is very useful. Thanks a lot!

This is very useful. Thanks a lot!

@jhgaylor

This comment has been minimized.

Show comment
Hide comment
@jhgaylor

jhgaylor Aug 23, 2013

Thanks so much. This gist got me on the right page!

Thanks so much. This gist got me on the right page!

@koleror

This comment has been minimized.

Show comment
Hide comment
@koleror

koleror Aug 24, 2013

Thanks! very helpful!

koleror commented Aug 24, 2013

Thanks! very helpful!

@viyatb

This comment has been minimized.

Show comment
Hide comment
@viyatb

viyatb Dec 9, 2013

Thanks! Saved my day!

viyatb commented Dec 9, 2013

Thanks! Saved my day!

@Arlus

This comment has been minimized.

Show comment
Hide comment
@Arlus

Arlus Dec 30, 2013

I'll buy u a beer.

Arlus commented Dec 30, 2013

I'll buy u a beer.

@arunshankerprasad

This comment has been minimized.

Show comment
Hide comment
@arunshankerprasad

arunshankerprasad Feb 3, 2014

Excellent!!

Excellent!!

@seaworld

This comment has been minimized.

Show comment
Hide comment
@seaworld

seaworld Apr 4, 2014

谢谢,非常好

seaworld commented Apr 4, 2014

谢谢,非常好

@opnchaudhary

This comment has been minimized.

Show comment
Hide comment
@opnchaudhary

opnchaudhary Sep 29, 2014

Thank you

Thank you

@Dastagirireddy

This comment has been minimized.

Show comment
Hide comment
@Dastagirireddy

Dastagirireddy Dec 23, 2014

Thanks a lot

Thanks a lot

@rahulkp220

This comment has been minimized.

Show comment
Hide comment
@rahulkp220

rahulkp220 Jun 6, 2016

djangotoolbox isn't working with django 1.9.Can anyone help?

djangotoolbox isn't working with django 1.9.Can anyone help?

@AmyAmeesha

This comment has been minimized.

Show comment
Hide comment
@AmyAmeesha

AmyAmeesha Jun 9, 2016

Hey! This method worked great! But I am having trouble in making a ModelForm out of this model now. Can you please help me with this?
Also this method is not working when I deploy my application on Apache. It is unable to import StringListField.

AmyAmeesha commented Jun 9, 2016

Hey! This method worked great! But I am having trouble in making a ModelForm out of this model now. Can you please help me with this?
Also this method is not working when I deploy my application on Apache. It is unable to import StringListField.

@engrogerio

This comment has been minimized.

Show comment
Hide comment
@engrogerio

engrogerio Apr 15, 2017

6 years after post and still work. Django 1.8.3 here.

6 years after post and still work. Django 1.8.3 here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment