Django自定义字段小部件和小部件行为的自定义" ListField"

时间:2014-05-07 09:16:44

标签: django model field

我根据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"])

基本上,我想要实现的是一个字段,您可以在其中编写类似" 1,asd,asdf fdgd"这样的字段,它将其存储在数据库中但是在检索时它应该返回该字符串作为数组,当给定数组时,它应该将其转换回逗号分隔的字符串。

我还不确定到目前为止我写的内容是否有效,但即使我设置了小部件,我也无法将其显示为输入字段而非textarea =的TextInput。

那么,如何在管理员中使用标准CharField使用的相同输入显示它? 我如何自定义它以便在显示此类输入时显示逗号分隔的字符串,但在其他地方访问时作为Python列表返回?

由于

1 个答案:

答案 0 :(得分:0)

以下是实现您想要的方法

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

您可以将标签视为ListField,设置值使用obj.set_labels(list)函数,并使用obj.get_labels()获取值 它充当列表字段,管理站点将作为普通的TextField运行。

这就是我所做的,但除了更好的解决方案之外。

更好的方法是在admin.py中使用save_mode:

class BlogAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        # extra data handling, prevent data convert
        obj.save()
相关问题