Skip to content

Instantly share code, notes, and snippets.

@jonashaag
Created September 7, 2011 09:41
Show Gist options
  • Select an option

  • Save jonashaag/1200165 to your computer and use it in GitHub Desktop.

Select an option

Save jonashaag/1200165 to your computer and use it in GitHub Desktop.
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)
@georgedorn

Copy link
Copy Markdown

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

Copy link
Copy Markdown
Author

@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

Copy link
Copy Markdown
Author

me neither :)

@jtdp

jtdp commented Feb 10, 2012

Copy link
Copy Markdown

Very helpful. Thank You!

@ielshareef

Copy link
Copy Markdown

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

@jmoz

jmoz commented Nov 15, 2012

Copy link
Copy Markdown

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

@DrKaoliN

Copy link
Copy Markdown

This is very useful. Thanks a lot!

@jhgaylor

Copy link
Copy Markdown

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

@koleror

koleror commented Aug 24, 2013

Copy link
Copy Markdown

Thanks! very helpful!

@viyatb

viyatb commented Dec 9, 2013

Copy link
Copy Markdown

Thanks! Saved my day!

@Arlus

Arlus commented Dec 30, 2013

Copy link
Copy Markdown

I'll buy u a beer.

@arunshankerprasad

Copy link
Copy Markdown

Excellent!!

@seaworld

seaworld commented Apr 4, 2014

Copy link
Copy Markdown

谢谢,非常好

@opnchaudhary

Copy link
Copy Markdown

Thank you

@Dastagirireddy

Copy link
Copy Markdown

Thanks a lot

@rahulkp220

Copy link
Copy Markdown

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

@AmyAmeesha

AmyAmeesha commented Jun 9, 2016

Copy link
Copy Markdown

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

Copy link
Copy Markdown

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

@ezequias

Copy link
Copy Markdown

I would like to see that image.

@vklap

vklap commented Sep 10, 2020

Copy link
Copy Markdown

Thanks a lot!!!

@jonashaag

Copy link
Copy Markdown
Author

Are people still using django-nonrel?!

@SXHRYU

SXHRYU commented Aug 29, 2023

Copy link
Copy Markdown

2023 still the best solution

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