1

I'm creating the following custom field based off How to create list field in django

import re

from django.db            import models
from django.forms.widgets import TextInput

class ListField(models.TextField):
    __metaclass__ = models.SubfieldBase
    description   = "Stores a python list"
    widget        = TextInput

    def __init__(self, *args, **kwargs):
        super(ListField, self).__init__(*args, **kwargs)

    def to_python(self, value):
        if not value:
            return []

        return filter(None, re.split(r'\,|\s*', value))

    def get_prep_value(self, value):
        if value is None:
            return value

        return ', '.join(value)

    def value_to_string(self, obj):
        value = self._get_val_from_obj(obj)
        return self.get_db_prep_value(value)

from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^cflowportal\.utils\.modelutils\.ListField"])

Basically, what I want to achieve is a field where you write something like "1, asd, asdf fdgd", it stores it as such in the database but when retrieved it should return that string as an array and when given an array it should convert it back to a comma-seperated string.

I'm still not sure if what I've written so far works, but I'm having trouble displaying it as an input field and not a textarea even if I've set widget=TextInput.

So, how do I show it in the admin with the same input used by the standard CharField? How can I customize it so that it displays a comma-separated string when showed on such input, but is given back as a Python List when accessed elsewhere?

Thanks

Community
  • 1
  • 1
pistacchio
  • 56,889
  • 107
  • 278
  • 420
  • 1
    I met the same problem before, when you save every time, it convert. As a result, many [ and ] in content – WeizhongTu May 07 '14 at 09:31
  • that's the problem that i'm experiencing too – pistacchio May 07 '14 at 09:33
  • It works in shell or views.py but not work as excepted in admin site, I dont't find a better way to solve this, maybe a convert function instead of ListField, just use TextField or CharField, when you read, write a function of your class in models.py,such as get_content to convert content to list, just use obj.get_content() instead of obj.content... but I except a better answer – WeizhongTu May 07 '14 at 09:40
  • this may be helpful,https://gist.github.com/jonashaag/1200165 – WeizhongTu May 08 '14 at 09:01

1 Answers1

0

The following is a method to realize what you want

from django.db import models

class Blog(models.Model):
    title = models.CharField(max_length=256)
    labels = models.TextField()

    def get_labels(self):
        return self.content.split('\n')

    def set_labels(self,value):
        if isinstance(value,list) or isinstance(value,tuple) or isinstance(value,set):
            content = '\n'.join(value)
        else:
            content = value
        self.content = content

You can regard labels as a ListField, set value use obj.set_labels(list) function, and get value use obj.get_labels() It act as a List Field, and admin site will run as a normal TextField.

This is what I did, but a better solution is excepted.

and a better way to do this is using save_model in admin.py:

class BlogAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        # extra data handling, prevent data convert
        obj.save()
WeizhongTu
  • 6,124
  • 4
  • 37
  • 51