Consider this blog post model:
from django.db import models
from djangotoolbox.fields import ListField
class Post(models.Model):
title = models.CharField(max_length=100)
categories = ListField()
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'>
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:
>>> Post.objects.get(title='foo').categories
[u'spam', u'eggs', u'bar']
It worked! Simple, isn't it?
Is there something similar to handle loaddata/dumpdata? At the moment, my 'tags' SetField gets converted to a comma-delimited list of single characters.